aboutsummaryrefslogtreecommitdiff
path: root/loader
diff options
context:
space:
mode:
authorJon Ashburn <jon@lunarg.com>2015-05-29 13:15:39 -0600
committerCourtney Goeltzenleuchter <courtney@LunarG.com>2015-06-18 10:18:20 -0600
commit87e0fa040fad2093a7ae96943bca64b47cbadb62 (patch)
treed9b8d27e3b310417d46b89704b7ad8f38c9a8c3a /loader
parentd00f0f53a7850b263789a7426028ad2a098c926f (diff)
downloadusermoji-87e0fa040fad2093a7ae96943bca64b47cbadb62.tar.xz
loader: Make global functions (instance chain entrypoints) thread safe
Diffstat (limited to 'loader')
-rw-r--r--loader/debug_report.c4
-rw-r--r--loader/loader.c34
-rw-r--r--loader/loader.h10
-rw-r--r--loader/trampoline.c54
-rw-r--r--loader/wsi_lunarg.c6
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(