Skip to content

Commit e2ce2dd

Browse files
committed
added OCL_ICD_FILENAMES support
1 parent a62dd71 commit e2ce2dd

5 files changed

Lines changed: 180 additions & 123 deletions

File tree

loader/icd.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "icd.h"
2020
#include "icd_dispatch.h"
21+
#include "icd_envvars.h"
2122
#include <stdlib.h>
2223
#include <string.h>
2324

@@ -188,6 +189,52 @@ void khrIcdVendorAdd(const char *libraryName)
188189
}
189190
}
190191

192+
#if defined(__linux__) || defined(__APPLE__)
193+
#define PATH_SEPARATOR ':'
194+
#elif defined(_WIN32)
195+
#define PATH_SEPARATOR ';'
196+
#endif
197+
198+
// Get next file or dirname given a string list or registry key path.
199+
// Note: the input string may be modified!
200+
static char *loader_get_next_path(char *path) {
201+
size_t len;
202+
char *next;
203+
204+
if (path == NULL) return NULL;
205+
next = strchr(path, PATH_SEPARATOR);
206+
if (next == NULL) {
207+
len = strlen(path);
208+
next = path + len;
209+
} else {
210+
*next = '\0';
211+
next++;
212+
}
213+
214+
return next;
215+
}
216+
217+
void khrIcdVendorsEnumerateEnv(void)
218+
{
219+
char* icdFilenames = khrIcd_secure_getenv("OCL_ICD_FILENAMES");
220+
char* cur_file = NULL;
221+
char* next_file = NULL;
222+
if (icdFilenames)
223+
{
224+
KHR_ICD_TRACE("Found OCL_ICD_FILENAMES environment variable.\n");
225+
226+
next_file = icdFilenames;
227+
while (NULL != next_file && *next_file != '\0') {
228+
cur_file = next_file;
229+
next_file = loader_get_next_path(cur_file);
230+
231+
khrIcdVendorAdd(cur_file);
232+
}
233+
234+
khrIcd_free_getenv(icdFilenames);
235+
}
236+
}
237+
191238
void khrIcdContextPropertiesGetPlatform(const cl_context_properties *properties, cl_platform_id *outPlatform)
192239
{
193240
if (properties == NULL && khrIcdVendors != NULL)

loader/icd.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ void khrIcdInitialize(void);
101101
// n.b, this call is OS-specific
102102
void khrIcdOsVendorsEnumerateOnce(void);
103103

104+
// read vendors from environment variables
105+
void khrIcdVendorsEnumerateEnv(void);
106+
104107
// add a vendor's implementation to the list of libraries
105108
void khrIcdVendorAdd(const char *libraryName);
106109

@@ -122,7 +125,7 @@ void khrIcdContextPropertiesGetPlatform(
122125
cl_platform_id *outPlatform);
123126

124127
// internal tracing macros
125-
#if 0
128+
#if 1
126129
#include <stdio.h>
127130
#define KHR_ICD_TRACE(...) \
128131
do \

loader/linux/icd_linux.c

Lines changed: 82 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -40,106 +40,111 @@ void khrIcdOsVendorsEnumerate(void)
4040
{
4141
DIR *dir = NULL;
4242
struct dirent *dirEntry = NULL;
43-
char* vendorPath = khrIcd_secure_getenv("OCL_ICD_VENDORS");
44-
if (vendorPath == NULL)
45-
{
43+
char* vendorPath =
4644
#ifdef __ANDROID__
47-
vendorPath = "/system/vendor/Khronos/OpenCL/vendors/";
45+
"/system/vendor/Khronos/OpenCL/vendors/";
4846
#else
49-
vendorPath = "/etc/OpenCL/vendors/";
47+
"/etc/OpenCL/vendors/";
5048
#endif // ANDROID
49+
char* envPath = NULL;
50+
51+
khrIcdVendorsEnumerateEnv();
52+
53+
envPath = khrIcd_secure_getenv("OCL_ICD_VENDORS");
54+
if (NULL != envPath)
55+
{
56+
vendorPath = envPath;
5157
}
5258

53-
// open the directory
5459
dir = opendir(vendorPath);
5560
if (NULL == dir)
5661
{
57-
KHR_ICD_TRACE("Failed to open path %s\n", vendorPath);
58-
goto Cleanup;
62+
KHR_ICD_TRACE("Failed to open path %s, continuing\n", vendorPath);
5963
}
60-
61-
// attempt to load all files in the directory
62-
for (dirEntry = readdir(dir); dirEntry; dirEntry = readdir(dir) )
64+
else
6365
{
64-
switch(dirEntry->d_type)
66+
// attempt to load all files in the directory
67+
for (dirEntry = readdir(dir); dirEntry; dirEntry = readdir(dir) )
6568
{
66-
case DT_UNKNOWN:
67-
case DT_REG:
68-
case DT_LNK:
69+
switch(dirEntry->d_type)
6970
{
70-
const char* extension = ".icd";
71-
FILE *fin = NULL;
72-
char* fileName = NULL;
73-
char* buffer = NULL;
74-
long bufferSize = 0;
75-
76-
// make sure the file name ends in .icd
77-
if (strlen(extension) > strlen(dirEntry->d_name) )
78-
{
79-
break;
80-
}
81-
if (strcmp(dirEntry->d_name + strlen(dirEntry->d_name) - strlen(extension), extension) )
82-
{
83-
break;
84-
}
85-
86-
// allocate space for the full path of the vendor library name
87-
fileName = malloc(strlen(dirEntry->d_name) + strlen(vendorPath) + 1);
88-
if (!fileName)
71+
case DT_UNKNOWN:
72+
case DT_REG:
73+
case DT_LNK:
8974
{
90-
KHR_ICD_TRACE("Failed allocate space for ICD file path\n");
91-
break;
92-
}
93-
sprintf(fileName, "%s%s", vendorPath, dirEntry->d_name);
75+
const char* extension = ".icd";
76+
FILE *fin = NULL;
77+
char* fileName = NULL;
78+
char* buffer = NULL;
79+
long bufferSize = 0;
80+
81+
// make sure the file name ends in .icd
82+
if (strlen(extension) > strlen(dirEntry->d_name) )
83+
{
84+
break;
85+
}
86+
if (strcmp(dirEntry->d_name + strlen(dirEntry->d_name) - strlen(extension), extension) )
87+
{
88+
break;
89+
}
90+
91+
// allocate space for the full path of the vendor library name
92+
fileName = malloc(strlen(dirEntry->d_name) + strlen(vendorPath) + 1);
93+
if (!fileName)
94+
{
95+
KHR_ICD_TRACE("Failed allocate space for ICD file path\n");
96+
break;
97+
}
98+
sprintf(fileName, "%s%s", vendorPath, dirEntry->d_name);
99+
100+
// open the file and read its contents
101+
fin = fopen(fileName, "r");
102+
if (!fin)
103+
{
104+
free(fileName);
105+
break;
106+
}
107+
fseek(fin, 0, SEEK_END);
108+
bufferSize = ftell(fin);
109+
110+
buffer = malloc(bufferSize+1);
111+
if (!buffer)
112+
{
113+
free(fileName);
114+
fclose(fin);
115+
break;
116+
}
117+
memset(buffer, 0, bufferSize+1);
118+
fseek(fin, 0, SEEK_SET);
119+
if (bufferSize != (long)fread(buffer, 1, bufferSize, fin) )
120+
{
121+
free(fileName);
122+
free(buffer);
123+
fclose(fin);
124+
break;
125+
}
126+
// ignore a newline at the end of the file
127+
if (buffer[bufferSize-1] == '\n') buffer[bufferSize-1] = '\0';
128+
129+
// load the string read from the file
130+
khrIcdVendorAdd(buffer);
94131

95-
// open the file and read its contents
96-
fin = fopen(fileName, "r");
97-
if (!fin)
98-
{
99-
free(fileName);
100-
break;
101-
}
102-
fseek(fin, 0, SEEK_END);
103-
bufferSize = ftell(fin);
104-
105-
buffer = malloc(bufferSize+1);
106-
if (!buffer)
107-
{
108-
free(fileName);
109-
fclose(fin);
110-
break;
111-
}
112-
memset(buffer, 0, bufferSize+1);
113-
fseek(fin, 0, SEEK_SET);
114-
if (bufferSize != (long)fread(buffer, 1, bufferSize, fin) )
115-
{
116132
free(fileName);
117133
free(buffer);
118134
fclose(fin);
119-
break;
120135
}
121-
// ignore a newline at the end of the file
122-
if (buffer[bufferSize-1] == '\n') buffer[bufferSize-1] = '\0';
123-
124-
// load the string read from the file
125-
khrIcdVendorAdd(buffer);
126-
127-
free(fileName);
128-
free(buffer);
129-
fclose(fin);
136+
break;
137+
default:
138+
break;
130139
}
131-
break;
132-
default:
133-
break;
134140
}
135-
}
136141

137-
Cleanup:
142+
closedir(dir);
143+
}
138144

139-
// free resources and exit
140-
if (dir)
145+
if (NULL != envPath)
141146
{
142-
closedir(dir);
147+
khrIcd_free_getenv(envPath);
143148
}
144149
}
145150

loader/windows/icd_windows.c

Lines changed: 47 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ BOOL CALLBACK khrIcdOsVendorsEnumerate(PINIT_ONCE InitOnce, PVOID Parameter, PVO
3939
HKEY platformsKey = NULL;
4040
DWORD dwIndex;
4141

42+
khrIcdVendorsEnumerateEnv();
43+
4244
if (!khrIcdOsVendorsEnumerateHKR())
4345
{
4446
KHR_ICD_TRACE("Failed to enumerate HKR entries, continuing\n");
@@ -54,59 +56,60 @@ BOOL CALLBACK khrIcdOsVendorsEnumerate(PINIT_ONCE InitOnce, PVOID Parameter, PVO
5456
if (ERROR_SUCCESS != result)
5557
{
5658
KHR_ICD_TRACE("Failed to open platforms key %s, continuing\n", platformsName);
57-
return TRUE;
5859
}
59-
60-
// for each value
61-
for (dwIndex = 0;; ++dwIndex)
60+
else
6261
{
63-
char cszLibraryName[1024] = {0};
64-
DWORD dwLibraryNameSize = sizeof(cszLibraryName);
65-
DWORD dwLibraryNameType = 0;
66-
DWORD dwValue = 0;
67-
DWORD dwValueSize = sizeof(dwValue);
68-
69-
// read the value name
70-
KHR_ICD_TRACE("Reading value %d...\n", dwIndex);
71-
result = RegEnumValueA(
72-
platformsKey,
73-
dwIndex,
74-
cszLibraryName,
75-
&dwLibraryNameSize,
76-
NULL,
77-
&dwLibraryNameType,
78-
(LPBYTE)&dwValue,
79-
&dwValueSize);
80-
// if RegEnumKeyEx fails, we are done with the enumeration
81-
if (ERROR_SUCCESS != result)
62+
// for each value
63+
for (dwIndex = 0;; ++dwIndex)
8264
{
83-
KHR_ICD_TRACE("Failed to read value %d, done reading key.\n", dwIndex);
84-
break;
85-
}
86-
KHR_ICD_TRACE("Value %s found...\n", cszLibraryName);
65+
char cszLibraryName[1024] = {0};
66+
DWORD dwLibraryNameSize = sizeof(cszLibraryName);
67+
DWORD dwLibraryNameType = 0;
68+
DWORD dwValue = 0;
69+
DWORD dwValueSize = sizeof(dwValue);
70+
71+
// read the value name
72+
KHR_ICD_TRACE("Reading value %d...\n", dwIndex);
73+
result = RegEnumValueA(
74+
platformsKey,
75+
dwIndex,
76+
cszLibraryName,
77+
&dwLibraryNameSize,
78+
NULL,
79+
&dwLibraryNameType,
80+
(LPBYTE)&dwValue,
81+
&dwValueSize);
82+
// if RegEnumKeyEx fails, we are done with the enumeration
83+
if (ERROR_SUCCESS != result)
84+
{
85+
KHR_ICD_TRACE("Failed to read value %d, done reading key.\n", dwIndex);
86+
break;
87+
}
88+
KHR_ICD_TRACE("Value %s found...\n", cszLibraryName);
8789

88-
// Require that the value be a DWORD and equal zero
89-
if (REG_DWORD != dwLibraryNameType)
90-
{
91-
KHR_ICD_TRACE("Value not a DWORD, skipping\n");
92-
continue;
90+
// Require that the value be a DWORD and equal zero
91+
if (REG_DWORD != dwLibraryNameType)
92+
{
93+
KHR_ICD_TRACE("Value not a DWORD, skipping\n");
94+
continue;
95+
}
96+
if (dwValue)
97+
{
98+
KHR_ICD_TRACE("Value not zero, skipping\n");
99+
continue;
100+
}
101+
102+
// add the library
103+
khrIcdVendorAdd(cszLibraryName);
93104
}
94-
if (dwValue)
105+
106+
result = RegCloseKey(platformsKey);
107+
if (ERROR_SUCCESS != result)
95108
{
96-
KHR_ICD_TRACE("Value not zero, skipping\n");
97-
continue;
109+
KHR_ICD_TRACE("Failed to close platforms key %s, ignoring\n", platformsName);
98110
}
99-
100-
// add the library
101-
khrIcdVendorAdd(cszLibraryName);
102111
}
103112

104-
result = RegCloseKey(platformsKey);
105-
if (ERROR_SUCCESS != result)
106-
{
107-
KHR_ICD_TRACE("Failed to close platforms key %s, ignoring\n", platformsName);
108-
}
109-
110113
return TRUE;
111114
}
112115

test/driver_stub/driver_stub.def

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
EXPORTS
22
clGetExtensionFunctionAddress
3-
clIcdGetPlatformIDsKHR

0 commit comments

Comments
 (0)