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
2825KHRicdVendor * khrIcdVendors = NULL ;
26+ static KHRicdVendor * lastVendor = NULL ;
2927int khrEnableTrace = 0 ;
28+ static int khrDisableLibraryUnloading = 0 ;
3029
3130#if defined(CL_ENABLE_LAYERS )
3231struct 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+ }
0 commit comments