Skip to content

Commit b37c49f

Browse files
committed
Deinitialization support.
1 parent 634ef47 commit b37c49f

14 files changed

Lines changed: 494 additions & 37 deletions

include/cl_khr_icd2.h

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

1919
#include <CL/cl.h>
2020

21+
#if !defined(CL_PLATFORM_UNLOADABLE_KHR)
22+
#define CL_PLATFORM_UNLOADABLE_KHR 0x0921
23+
#endif
24+
25+
#if defined(CL_ENABLE_LAYERS) && !defined(CL_LAYER_API_VERSION_200)
26+
#define CL_LAYER_API_VERSION_200 200
27+
28+
typedef cl_int CL_API_CALL
29+
clDeinitLayer_t(void);
30+
31+
typedef clDeinitLayer_t *pfn_clDeinitLayer;
32+
#endif //defined(CL_ENABLE_LAYERS) && !defined(CL_LAYER_API_VERSION_200)
33+
2134
#if !defined(CL_ICD2_TAG_KHR)
2235
#if INTPTR_MAX == INT32_MAX
2336
#define CL_ICD2_TAG_KHR ((intptr_t)0x434C3331)

loader/cllayerinfo.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include "icd.h"
2020
#include <stdio.h>
2121
#include <stdlib.h>
22-
#include <CL/cl_layer.h>
2322
#if defined(_WIN32)
2423
#include <io.h>
2524
#include <share.h>
@@ -90,7 +89,7 @@ static void restore_outputs(void)
9089
void printLayerInfo(const struct KHRLayer *layer)
9190
{
9291
cl_layer_api_version api_version = 0;
93-
pfn_clGetLayerInfo p_clGetLayerInfo = (pfn_clGetLayerInfo)(size_t)layer->p_clGetLayerInfo;
92+
pfn_clGetLayerInfo p_clGetLayerInfo = layer->p_clGetLayerInfo;
9493
cl_int result = CL_SUCCESS;
9594
size_t sz;
9695

@@ -113,20 +112,26 @@ void printLayerInfo(const struct KHRLayer *layer)
113112
}
114113
}
115114

116-
int main (int argc, char *argv[])
115+
static void run_silently(void (*pfn)(void))
117116
{
118-
(void)argc;
119-
(void)argv;
120117
silence_layers();
121118
atexit(restore_outputs);
122-
khrIcdInitialize();
119+
pfn();
123120
restore_outputs();
124121
atexit(silence_layers);
122+
}
123+
124+
int main (int argc, char *argv[])
125+
{
126+
(void)argc;
127+
(void)argv;
128+
run_silently(&khrIcdInitialize);
125129
const struct KHRLayer *layer = khrFirstLayer;
126130
while (layer)
127131
{
128132
printLayerInfo(layer);
129133
layer = layer->next;
130134
}
135+
run_silently(&khrIcdDeinitialize);
131136
return 0;
132137
}

loader/icd.c

Lines changed: 92 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,13 @@
1919
#include "icd.h"
2020
#include "icd_dispatch.h"
2121
#include "icd_envvars.h"
22-
#if defined(CL_ENABLE_LAYERS)
23-
#include <CL/cl_layer.h>
24-
#endif // defined(CL_ENABLE_LAYERS)
2522
#include <stdlib.h>
2623
#include <string.h>
2724

2825
KHRicdVendor *khrIcdVendors = NULL;
26+
static KHRicdVendor *lastVendor = NULL;
2927
int khrEnableTrace = 0;
28+
static int khrDisableLibraryUnloading = 0;
3029

3130
#if defined(CL_ENABLE_LAYERS)
3231
struct KHRLayer *khrFirstLayer = NULL;
@@ -43,6 +42,26 @@ void khrIcdInitializeTrace(void)
4342
{
4443
khrEnableTrace = 1;
4544
}
45+
if (enableTrace)
46+
{
47+
khrIcd_free_getenv(enableTrace);
48+
}
49+
}
50+
51+
void khrIcdInitializeLibraryUnloading(void)
52+
{
53+
char *disableLibraryUnloading = khrIcd_getenv("OCL_ICD_DISABLE_DYNAMIC_LIBRARY_UNLOADING");
54+
if (disableLibraryUnloading && (strcmp(disableLibraryUnloading, "True") == 0 ||
55+
strcmp(disableLibraryUnloading, "true") == 0 ||
56+
strcmp(disableLibraryUnloading, "T") == 0 ||
57+
strcmp(disableLibraryUnloading, "1") == 0))
58+
{
59+
khrDisableLibraryUnloading = 1;
60+
}
61+
if (disableLibraryUnloading)
62+
{
63+
khrIcd_free_getenv(disableLibraryUnloading);
64+
}
4665
}
4766

4867
// entrypoint to initialize the ICD and add all vendors
@@ -186,6 +205,14 @@ void khrIcdVendorAdd(const char *libraryName)
186205
#endif
187206

188207
// call clGetPlatformInfo on the returned platform to get the suffix
208+
209+
KHR_ICD2_DISPATCH(platforms[i])->clGetPlatformInfo(
210+
platforms[i],
211+
CL_PLATFORM_UNLOADABLE_KHR,
212+
sizeof(vendor->unloadable),
213+
&vendor->unloadable,
214+
NULL);
215+
189216
result = KHR_ICD2_DISPATCH(platforms[i])->clGetPlatformInfo(
190217
platforms[i],
191218
CL_PLATFORM_ICD_SUFFIX_KHR,
@@ -230,11 +257,13 @@ void khrIcdVendorAdd(const char *libraryName)
230257
vendor->suffix = suffix;
231258

232259
// add this vendor to the list of vendors at the tail
233-
{
234-
KHRicdVendor **prevNextPointer = NULL;
235-
for (prevNextPointer = &khrIcdVendors; *prevNextPointer; prevNextPointer = &( (*prevNextPointer)->next) );
236-
*prevNextPointer = vendor;
260+
if (lastVendor) {
261+
lastVendor->next = vendor;
262+
vendor->prev = lastVendor;
263+
} else {
264+
khrIcdVendors = vendor;
237265
}
266+
lastVendor = vendor;
238267

239268
KHR_ICD_TRACE("successfully added vendor %s with suffix %s\n", libraryName, suffix);
240269

@@ -259,6 +288,7 @@ void khrIcdLayerAdd(const char *libraryName)
259288
cl_int result = CL_SUCCESS;
260289
pfn_clGetLayerInfo p_clGetLayerInfo = NULL;
261290
pfn_clInitLayer p_clInitLayer = NULL;
291+
pfn_clDeinitLayer p_clDeinitLayer = NULL;
262292
struct KHRLayer *layerIterator = NULL;
263293
struct KHRLayer *layer = NULL;
264294
cl_layer_api_version api_version = 0;
@@ -315,12 +345,22 @@ void khrIcdLayerAdd(const char *libraryName)
315345
goto Done;
316346
}
317347

318-
if (CL_LAYER_API_VERSION_100 != api_version)
348+
if (CL_LAYER_API_VERSION_100 != api_version && CL_LAYER_API_VERSION_200 != api_version)
319349
{
320350
KHR_ICD_TRACE("unsupported api version\n");
321351
goto Done;
322352
}
323353

354+
if (CL_LAYER_API_VERSION_200 == api_version)
355+
{
356+
p_clDeinitLayer = (pfn_clDeinitLayer)(size_t)khrIcdOsLibraryGetFunctionAddress(library, "clDeinitLayer");
357+
if (!p_clDeinitLayer)
358+
{
359+
KHR_ICD_TRACE("failed to get function address clDeinitLayer\n");
360+
goto Done;
361+
}
362+
}
363+
324364
layer = (struct KHRLayer*)calloc(sizeof(struct KHRLayer), 1);
325365
if (!layer)
326366
{
@@ -338,9 +378,10 @@ void khrIcdLayerAdd(const char *libraryName)
338378
goto Done;
339379
}
340380
memcpy(layer->libraryName, libraryName, sz_name);
341-
layer->p_clGetLayerInfo = (void *)(size_t)p_clGetLayerInfo;
381+
layer->p_clGetLayerInfo = p_clGetLayerInfo;
342382
}
343383
#endif
384+
layer->p_clDeinitLayer = p_clDeinitLayer;
344385

345386
if (khrFirstLayer) {
346387
targetDispatch = &(khrFirstLayer->dispatch);
@@ -472,3 +513,45 @@ void khrIcdContextPropertiesGetPlatform(const cl_context_properties *properties,
472513
}
473514
}
474515

516+
#if defined(CL_ENABLE_LAYERS)
517+
static struct KHRLayer deinitLayer = {0};
518+
#endif
519+
520+
void khrIcdDeinitialize(void) {
521+
522+
KHR_ICD_TRACE("ICD Loader deinitialization\n");
523+
524+
#if defined(CL_ENABLE_LAYERS)
525+
// free layers first in reverse order of their creation (front to back)
526+
// they may still need to use vendors while terminating
527+
KHR_ICD_TRACE("Finalizing and unloading layers\n");
528+
struct KHRLayer *head = khrFirstLayer;
529+
deinitLayer.dispatch = khrDeinitDispatch;
530+
khrFirstLayer = &deinitLayer;
531+
532+
while(head) {
533+
struct KHRLayer *cur = head;
534+
#ifdef CL_LAYER_INFO
535+
free(cur->libraryName);
536+
#endif
537+
if (cur->p_clDeinitLayer)
538+
cur->p_clDeinitLayer();
539+
if (cur->p_clDeinitLayer && !khrDisableLibraryUnloading)
540+
khrIcdOsLibraryUnload(cur->library);
541+
head = cur->next;
542+
free(cur);
543+
}
544+
#endif // defined(CL_ENABLE_LAYERS)
545+
546+
// free vendor in reverse order of their creation (back to front)
547+
KHR_ICD_TRACE("Finalizing and unloading vendors\n");
548+
while (lastVendor) {
549+
KHRicdVendor *cur = lastVendor;
550+
free(cur->suffix);
551+
if (cur->unloadable && !khrDisableLibraryUnloading)
552+
khrIcdOsLibraryUnload(cur->library);
553+
lastVendor = cur->prev;
554+
free(cur);
555+
}
556+
khrIcdVendors = NULL;
557+
}

loader/icd.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@
4949
#include <CL/cl.h>
5050
#include <CL/cl_ext.h>
5151
#include <CL/cl_icd.h>
52+
#if defined(CL_ENABLE_LAYERS)
53+
#include <CL/cl_layer.h>
54+
#endif // defined(CL_ENABLE_LAYERS)
5255
#include <stdio.h>
5356

5457
/*
@@ -85,6 +88,9 @@ struct KHRicdVendorRec
8588
// the extension suffix for this platform
8689
char *suffix;
8790

91+
// can this vendor library be unloaded?
92+
cl_bool unloadable;
93+
8894
// function pointer to the ICD platform IDs extracted from the library
8995
pfn_clGetExtensionFunctionAddress clGetExtensionFunctionAddress;
9096

@@ -98,6 +104,7 @@ struct KHRicdVendorRec
98104

99105
// next vendor in the list vendors
100106
KHRicdVendor *next;
107+
KHRicdVendor *prev;
101108
};
102109

103110
// the global state
@@ -123,14 +130,17 @@ struct KHRLayer
123130
#ifdef CL_LAYER_INFO
124131
// The layer library name
125132
char *libraryName;
126-
// the pointer to the clGetLayerInfo funciton
127-
void *p_clGetLayerInfo;
133+
// the pointer to the clGetLayerInfo function
134+
pfn_clGetLayerInfo p_clGetLayerInfo;
128135
#endif
136+
// the pointer to the clDeinitLayer function
137+
pfn_clDeinitLayer p_clDeinitLayer;
129138
};
130139

131140
// the global layer state
132141
extern struct KHRLayer * khrFirstLayer;
133142
extern const struct _cl_icd_dispatch khrMainDispatch;
143+
extern const struct _cl_icd_dispatch khrDeinitDispatch;
134144
#endif // defined(CL_ENABLE_LAYERS)
135145

136146
/*
@@ -147,6 +157,12 @@ void khrIcdInitialize(void);
147157
// entrypoint to check and initialize trace.
148158
void khrIcdInitializeTrace(void);
149159

160+
// entrypoint to check and initialize library unloading
161+
void khrIcdInitializeLibraryUnloading(void);
162+
163+
// entrypoint to release icd resources
164+
void khrIcdDeinitialize(void);
165+
150166
// go through the list of vendors (in /etc/OpenCL.conf or through
151167
// the registry) and call khrIcdVendorAdd for each vendor encountered
152168
// n.b, this call is OS-specific

0 commit comments

Comments
 (0)