Skip to content

Commit a57a3c2

Browse files
committed
Deinitialization support.
1 parent 5cd421f commit a57a3c2

12 files changed

Lines changed: 399 additions & 33 deletions

File tree

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)
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: 1 addition & 2 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

loader/icd.c

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,11 @@
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;
3028

3129
#if defined(CL_ENABLE_LAYERS)
@@ -186,6 +184,14 @@ void khrIcdVendorAdd(const char *libraryName)
186184
#endif
187185

188186
// call clGetPlatformInfo on the returned platform to get the suffix
187+
188+
KHR_ICD2_DISPATCH(platforms[i])->clGetPlatformInfo(
189+
platforms[i],
190+
CL_PLATFORM_UNLOADABLE_KHR,
191+
sizeof(vendor->unloadable),
192+
&vendor->unloadable,
193+
NULL);
194+
189195
result = KHR_ICD2_DISPATCH(platforms[i])->clGetPlatformInfo(
190196
platforms[i],
191197
CL_PLATFORM_ICD_SUFFIX_KHR,
@@ -230,11 +236,13 @@ void khrIcdVendorAdd(const char *libraryName)
230236
vendor->suffix = suffix;
231237

232238
// 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;
239+
if (lastVendor) {
240+
lastVendor->next = vendor;
241+
vendor->prev = lastVendor;
242+
} else {
243+
khrIcdVendors = vendor;
237244
}
245+
lastVendor = vendor;
238246

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

@@ -259,6 +267,7 @@ void khrIcdLayerAdd(const char *libraryName)
259267
cl_int result = CL_SUCCESS;
260268
pfn_clGetLayerInfo p_clGetLayerInfo = NULL;
261269
pfn_clInitLayer p_clInitLayer = NULL;
270+
pfn_clDeinitLayer p_clDeinitLayer = NULL;
262271
struct KHRLayer *layerIterator = NULL;
263272
struct KHRLayer *layer = NULL;
264273
cl_layer_api_version api_version = 0;
@@ -308,14 +317,21 @@ void khrIcdLayerAdd(const char *libraryName)
308317
goto Done;
309318
}
310319

320+
p_clDeinitLayer = (pfn_clDeinitLayer)(size_t)khrIcdOsLibraryGetFunctionAddress(library, "clDeinitLayer");
321+
if (!p_clDeinitLayer)
322+
{
323+
KHR_ICD_TRACE("failed to get function address clDeinitLayer\n");
324+
goto Done;
325+
}
326+
311327
result = p_clGetLayerInfo(CL_LAYER_API_VERSION, sizeof(api_version), &api_version, NULL);
312328
if (CL_SUCCESS != result)
313329
{
314330
KHR_ICD_TRACE("failed to query layer version\n");
315331
goto Done;
316332
}
317333

318-
if (CL_LAYER_API_VERSION_100 != api_version)
334+
if (CL_LAYER_API_VERSION_200 != api_version)
319335
{
320336
KHR_ICD_TRACE("unsupported api version\n");
321337
goto Done;
@@ -338,9 +354,10 @@ void khrIcdLayerAdd(const char *libraryName)
338354
goto Done;
339355
}
340356
memcpy(layer->libraryName, libraryName, sz_name);
341-
layer->p_clGetLayerInfo = (void *)(size_t)p_clGetLayerInfo;
357+
layer->p_clGetLayerInfo = p_clGetLayerInfo;
342358
}
343359
#endif
360+
layer->p_clDeinitLayer = p_clDeinitLayer;
344361

345362
if (khrFirstLayer) {
346363
targetDispatch = &(khrFirstLayer->dispatch);
@@ -472,3 +489,43 @@ void khrIcdContextPropertiesGetPlatform(const cl_context_properties *properties,
472489
}
473490
}
474491

492+
#if defined(CL_ENABLE_LAYERS)
493+
static struct KHRLayer deinitLayer = {0};
494+
#endif
495+
496+
void khrIcdDeinitialize(void) {
497+
498+
KHR_ICD_TRACE("ICD Loader deinitialization\n");
499+
500+
#if defined(CL_ENABLE_LAYERS)
501+
// free layers first in reverse order of their creation (front to back)
502+
// they may still need to use vendors while terminating
503+
KHR_ICD_TRACE("Finalizing and unloading layers\n");
504+
struct KHRLayer *head = khrFirstLayer;
505+
deinitLayer.dispatch = khrDeinitDispatch;
506+
khrFirstLayer = &deinitLayer;
507+
508+
while(head) {
509+
struct KHRLayer *cur = head;
510+
#ifdef CL_LAYER_INFO
511+
free(cur->libraryName);
512+
#endif
513+
cur->p_clDeinitLayer();
514+
khrIcdOsLibraryUnload(cur->library);
515+
head = cur->next;
516+
free(cur);
517+
}
518+
#endif // defined(CL_ENABLE_LAYERS)
519+
520+
// free vendor in reverse order of their creation (back to front)
521+
KHR_ICD_TRACE("Finalizing and unloading vendors\n");
522+
while (lastVendor) {
523+
KHRicdVendor *cur = lastVendor;
524+
free(cur->suffix);
525+
if (cur->unloadable)
526+
khrIcdOsLibraryUnload(cur->library);
527+
lastVendor = cur->prev;
528+
free(cur);
529+
}
530+
khrIcdVendors = NULL;
531+
}

loader/icd.h

Lines changed: 15 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,9 @@ void khrIcdInitialize(void);
147157
// entrypoint to check and initialize trace.
148158
void khrIcdInitializeTrace(void);
149159

160+
// entrypoint to release icd resources
161+
void khrIcdDeinitialize(void);
162+
150163
// go through the list of vendors (in /etc/OpenCL.conf or through
151164
// the registry) and call khrIcdVendorAdd for each vendor encountered
152165
// n.b, this call is OS-specific

0 commit comments

Comments
 (0)