diff options
| author | Jon Ashburn <jon@lunarg.com> | 2015-05-29 13:15:39 -0600 |
|---|---|---|
| committer | Courtney Goeltzenleuchter <courtney@LunarG.com> | 2015-06-18 10:18:20 -0600 |
| commit | 87e0fa040fad2093a7ae96943bca64b47cbadb62 (patch) | |
| tree | d9b8d27e3b310417d46b89704b7ad8f38c9a8c3a /loader | |
| parent | d00f0f53a7850b263789a7426028ad2a098c926f (diff) | |
| download | usermoji-87e0fa040fad2093a7ae96943bca64b47cbadb62.tar.xz | |
loader: Make global functions (instance chain entrypoints) thread safe
Diffstat (limited to 'loader')
| -rw-r--r-- | loader/debug_report.c | 4 | ||||
| -rw-r--r-- | loader/loader.c | 34 | ||||
| -rw-r--r-- | loader/loader.h | 10 | ||||
| -rw-r--r-- | loader/trampoline.c | 54 | ||||
| -rw-r--r-- | loader/wsi_lunarg.c | 6 |
5 files changed, 89 insertions, 19 deletions
diff --git a/loader/debug_report.c b/loader/debug_report.c index e9e36fac..a7fdb5d6 100644 --- a/loader/debug_report.c +++ b/loader/debug_report.c @@ -68,6 +68,7 @@ static VkResult debug_report_DbgCreateMsgCallback( return VK_ERROR_OUT_OF_HOST_MEMORY; struct loader_instance *inst = loader_instance(instance); + loader_platform_thread_lock_mutex(&loader_lock); VkResult result = inst->disp->DbgCreateMsgCallback(instance, msgFlags, pfnMsgCallback, pUserData, pMsgCallback); if (result == VK_SUCCESS) { pNewDbgFuncNode->msgCallback = *pMsgCallback; @@ -79,6 +80,7 @@ static VkResult debug_report_DbgCreateMsgCallback( } else { free(pNewDbgFuncNode); } + loader_platform_thread_unlock_mutex(&loader_lock); return result; } @@ -87,6 +89,7 @@ static VkResult debug_report_DbgDestroyMsgCallback( VkDbgMsgCallback msg_callback) { struct loader_instance *inst = loader_instance(instance); + loader_platform_thread_lock_mutex(&loader_lock); VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead; VkLayerDbgFunctionNode *pPrev = pTrav; @@ -104,6 +107,7 @@ static VkResult debug_report_DbgDestroyMsgCallback( pTrav = pTrav->pNext; } + loader_platform_thread_unlock_mutex(&loader_lock); return result; } diff --git a/loader/loader.c b/loader/loader.c index 6a8e25c6..2e538617 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -64,7 +64,6 @@ static void loader_remove_layer_lib( struct loader_instance *inst, struct loader_extension_property *ext_prop); -/* TODO: do we need to lock around access to linked lists and such? */ struct loader_struct loader = {0}; enum loader_debug { @@ -78,7 +77,12 @@ enum loader_debug { uint32_t g_loader_debug = 0; uint32_t g_loader_log_msgs = 0; -VkLayerInstanceDispatchTable instance_disp = { +//thread safety lock for accessing global data structures such as "loader" +// all entrypoints on the instance chain need to be locked except GPA +// additionally DestroyDevice needs to be locked +loader_platform_thread_mutex loader_lock; + +const VkLayerInstanceDispatchTable instance_disp = { .GetInstanceProcAddr = vkGetInstanceProcAddr, .CreateInstance = loader_CreateInstance, .DestroyInstance = loader_DestroyInstance, @@ -86,7 +90,7 @@ VkLayerInstanceDispatchTable instance_disp = { .GetPhysicalDeviceInfo = loader_GetPhysicalDeviceInfo, .CreateDevice = loader_CreateDevice, .GetGlobalExtensionInfo = vkGetGlobalExtensionInfo, - .GetPhysicalDeviceExtensionInfo = vkGetPhysicalDeviceExtensionInfo, + .GetPhysicalDeviceExtensionInfo = loader_GetPhysicalDeviceExtensionInfo, .GetMultiDeviceCompatibility = loader_GetMultiDeviceCompatibility, .GetDisplayInfoWSI = loader_GetDisplayInfoWSI, .DbgCreateMsgCallback = loader_DbgCreateMsgCallback, @@ -703,6 +707,10 @@ void loader_icd_scan(void) char icd_library[1024]; char path[1024]; uint32_t len; + + // convenient place to initialize a mutex + loader_platform_thread_create_mutex(&loader_lock); + #if defined(WIN32) bool must_free_libPaths; libPaths = loader_get_registry_and_env(DRIVER_PATH_ENV, @@ -1743,6 +1751,8 @@ LOADER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo( void* pData) { uint32_t *count; + VkResult res = VK_SUCCESS; + /* Scan/discover all ICD libraries in a single-threaded manner */ loader_platform_thread_once(&once_icd, loader_icd_scan); @@ -1752,22 +1762,26 @@ LOADER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo( /* merge any duplicate extensions */ loader_platform_thread_once(&once_exts, loader_coalesce_extensions); - if (pDataSize == NULL) return VK_ERROR_INVALID_POINTER; + loader_platform_thread_lock_mutex(&loader_lock); switch (infoType) { case VK_EXTENSION_INFO_TYPE_COUNT: *pDataSize = sizeof(uint32_t); - if (pData == NULL) + if (pData == NULL) { + loader_platform_thread_unlock_mutex(&loader_lock); return VK_SUCCESS; + } count = (uint32_t *) pData; *count = loader.global_extensions.count; break; case VK_EXTENSION_INFO_TYPE_PROPERTIES: *pDataSize = sizeof(VkExtensionProperties); - if (pData == NULL) + if (pData == NULL) { + loader_platform_thread_unlock_mutex(&loader_lock); return VK_SUCCESS; + } if (extensionIndex >= loader.global_extensions.count) return VK_ERROR_INVALID_VALUE; memcpy((VkExtensionProperties *) pData, @@ -1776,13 +1790,13 @@ LOADER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo( break; default: loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Invalid infoType in vkGetGlobalExtensionInfo"); - return VK_ERROR_INVALID_VALUE; + res = VK_ERROR_INVALID_VALUE; }; - - return VK_SUCCESS; + loader_platform_thread_unlock_mutex(&loader_lock); + return res; } -LOADER_EXPORT VkResult VKAPI vkGetPhysicalDeviceExtensionInfo( +VkResult loader_GetPhysicalDeviceExtensionInfo( VkPhysicalDevice gpu, VkExtensionInfoType infoType, uint32_t extensionIndex, diff --git a/loader/loader.h b/loader/loader.h index c333f028..8602704b 100644 --- a/loader/loader.h +++ b/loader/loader.h @@ -292,7 +292,8 @@ extern struct loader_struct loader; extern LOADER_PLATFORM_THREAD_ONCE_DEFINITION(once_icd); extern LOADER_PLATFORM_THREAD_ONCE_DEFINITION(once_layer); extern LOADER_PLATFORM_THREAD_ONCE_DEFINITION(once_exts); -extern VkLayerInstanceDispatchTable instance_disp; +extern loader_platform_thread_mutex loader_lock; +extern const VkLayerInstanceDispatchTable instance_disp; struct loader_msg_callback_map_entry { VkDbgMsgCallback icd_obj; @@ -321,6 +322,13 @@ VkResult loader_GetPhysicalDeviceInfo( size_t* pDataSize, void* pData); +VkResult loader_GetPhysicalDeviceExtensionInfo( + VkPhysicalDevice gpu, + VkExtensionInfoType infoType, + uint32_t extensionIndex, + size_t* pDataSize, + void* pData); + VkResult loader_CreateDevice( VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo, diff --git a/loader/trampoline.c b/loader/trampoline.c index 1afb671c..3658017b 100644 --- a/loader/trampoline.c +++ b/loader/trampoline.c @@ -57,12 +57,15 @@ LOADER_EXPORT VkResult VKAPI vkCreateInstance( if (ptr_instance == NULL) { return VK_ERROR_OUT_OF_HOST_MEMORY; } + loader_platform_thread_lock_mutex(&loader_lock); memset(ptr_instance, 0, sizeof(struct loader_instance)); ptr_instance->app_extension_count = pCreateInfo->extensionCount; ptr_instance->app_extension_props = (ptr_instance->app_extension_count > 0) ? malloc(sizeof (VkExtensionProperties) * ptr_instance->app_extension_count) : NULL; - if (ptr_instance->app_extension_props == NULL && (ptr_instance->app_extension_count > 0)) + if (ptr_instance->app_extension_props == NULL && (ptr_instance->app_extension_count > 0)) { + loader_platform_thread_unlock_mutex(&loader_lock); return VK_ERROR_OUT_OF_HOST_MEMORY; + } /* * Make local copy of extension properties indicated by application. @@ -74,8 +77,10 @@ LOADER_EXPORT VkResult VKAPI vkCreateInstance( } ptr_instance->disp = malloc(sizeof(VkLayerInstanceDispatchTable)); - if (ptr_instance->disp == NULL) + if (ptr_instance->disp == NULL) { + loader_platform_thread_unlock_mutex(&loader_lock); return VK_ERROR_OUT_OF_HOST_MEMORY; + } memcpy(ptr_instance->disp, &instance_disp, sizeof(instance_disp)); ptr_instance->next = loader.instances; loader.instances = ptr_instance; @@ -100,6 +105,8 @@ LOADER_EXPORT VkResult VKAPI vkCreateInstance( */ loader_activate_instance_layer_extensions(ptr_instance); + loader_platform_thread_unlock_mutex(&loader_lock); + return res; } @@ -107,10 +114,12 @@ LOADER_EXPORT VkResult VKAPI vkDestroyInstance( VkInstance instance) { const VkLayerInstanceDispatchTable *disp; - + VkResult res; disp = loader_get_instance_dispatch(instance); - VkResult res = disp->DestroyInstance(instance); + loader_platform_thread_lock_mutex(&loader_lock); + + res = disp->DestroyInstance(instance); struct loader_instance *ptr_instance = loader_instance(instance); loader_deactivate_instance_layers(ptr_instance); @@ -119,6 +128,8 @@ LOADER_EXPORT VkResult VKAPI vkDestroyInstance( free(ptr_instance); + loader_platform_thread_unlock_mutex(&loader_lock); + return res; } @@ -128,10 +139,14 @@ LOADER_EXPORT VkResult VKAPI vkEnumeratePhysicalDevices( VkPhysicalDevice* pPhysicalDevices) { const VkLayerInstanceDispatchTable *disp; - + VkResult res; disp = loader_get_instance_dispatch(instance); - return disp->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, + + loader_platform_thread_lock_mutex(&loader_lock); + res = disp->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices); + loader_platform_thread_unlock_mutex(&loader_lock); + return res; } LOADER_EXPORT VkResult VKAPI vkGetPhysicalDeviceInfo( @@ -145,8 +160,10 @@ LOADER_EXPORT VkResult VKAPI vkGetPhysicalDeviceInfo( disp = loader_get_instance_dispatch(gpu); + loader_platform_thread_lock_mutex(&loader_lock); res = disp->GetPhysicalDeviceInfo(gpu, infoType, pDataSize, pData); //TODO add check for extension enabled + loader_platform_thread_unlock_mutex(&loader_lock); if (infoType == VK_PHYSICAL_DEVICE_INFO_TYPE_DISPLAY_PROPERTIES_WSI && pData && res == VK_SUCCESS) { VkDisplayPropertiesWSI *info = pData; size_t count = *pDataSize / sizeof(*info), i; @@ -168,8 +185,10 @@ LOADER_EXPORT VkResult VKAPI vkCreateDevice( disp = loader_get_instance_dispatch(gpu); + loader_platform_thread_lock_mutex(&loader_lock); // CreateDevice is dispatched on the instance chain res = disp->CreateDevice(gpu, pCreateInfo, pDevice); + loader_platform_thread_unlock_mutex(&loader_lock); return res; } @@ -180,9 +199,26 @@ LOADER_EXPORT VkResult VKAPI vkDestroyDevice(VkDevice device) disp = loader_get_dispatch(device); + loader_platform_thread_lock_mutex(&loader_lock); res = disp->DestroyDevice(device); // TODO need to keep track of device objs to be able to get icd/gpu to deactivate //loader_deactivate_device_layer(device); + loader_platform_thread_unlock_mutex(&loader_lock); + return res; +} + +LOADER_EXPORT VkResult VKAPI vkGetPhysicalDeviceExtensionInfo( + VkPhysicalDevice gpu, + VkExtensionInfoType infoType, + uint32_t extensionIndex, + size_t* pDataSize, + void* pData) +{ + VkResult res; + + loader_platform_thread_lock_mutex(&loader_lock); + res = loader_GetPhysicalDeviceExtensionInfo(gpu, infoType, extensionIndex, pDataSize, pData); + loader_platform_thread_unlock_mutex(&loader_lock); return res; } @@ -303,10 +339,14 @@ LOADER_EXPORT VkResult VKAPI vkPinSystemMemory(VkDevice device, const void* pSys LOADER_EXPORT VkResult VKAPI vkGetMultiDeviceCompatibility(VkPhysicalDevice gpu0, VkPhysicalDevice gpu1, VkPhysicalDeviceCompatibilityInfo* pInfo) { const VkLayerInstanceDispatchTable *disp; + VkResult res; disp = loader_get_instance_dispatch(gpu0); - return disp->GetMultiDeviceCompatibility(gpu0, gpu1, pInfo); + loader_platform_thread_lock_mutex(&loader_lock); + res = disp->GetMultiDeviceCompatibility(gpu0, gpu1, pInfo); + loader_platform_thread_unlock_mutex(&loader_lock); + return res; } LOADER_EXPORT VkResult VKAPI vkOpenSharedMemory(VkDevice device, const VkMemoryOpenInfo* pOpenInfo, VkDeviceMemory* pMem) diff --git a/loader/wsi_lunarg.c b/loader/wsi_lunarg.c index 5cd9585d..e5d1513e 100644 --- a/loader/wsi_lunarg.c +++ b/loader/wsi_lunarg.c @@ -40,10 +40,14 @@ VkResult VKAPI wsi_lunarg_GetDisplayInfoWSI( void* pData) { const VkLayerInstanceDispatchTable *disp; + VkResult res; disp = loader_get_instance_dispatch(display); - return disp->GetDisplayInfoWSI(display, infoType, pDataSize, pData); + loader_platform_thread_lock_mutex(&loader_lock); + res = disp->GetDisplayInfoWSI(display, infoType, pDataSize, pData); + loader_platform_thread_unlock_mutex(&loader_lock); + return res; } VkResult wsi_lunarg_CreateSwapChainWSI( |
