aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Stroyan <mike@LunarG.com>2015-05-15 08:50:57 -0600
committerMike Stroyan <mike@LunarG.com>2015-05-15 15:38:23 -0600
commitcbf8fc1ce9911fa700009a1c7cfaa61e3eddbe8e (patch)
tree4a3e17b85dd61e944a3e2d787b7a334255f54ca7
parent9fde28dffb7e642dfa282e5bb8df44d9f4c2444a (diff)
downloadusermoji-cbf8fc1ce9911fa700009a1c7cfaa61e3eddbe8e.tar.xz
layers: Make threading layer provide thread-safety
Add mutual exclusion behavior to threading layer after reporting collisions. This will allow applications to continue beyond first threading error. It can't help reentrant calls.
-rw-r--r--loader/loader_platform.h13
-rwxr-xr-xvk-layer-generate.py31
2 files changed, 24 insertions, 20 deletions
diff --git a/loader/loader_platform.h b/loader/loader_platform.h
index 60460bfb..9f7b47d1 100644
--- a/loader/loader_platform.h
+++ b/loader/loader_platform.h
@@ -129,6 +129,19 @@ static inline void loader_platform_thread_delete_mutex(loader_platform_thread_mu
{
pthread_mutex_destroy(pMutex);
}
+typedef pthread_cond_t loader_platform_thread_cond;
+static inline void loader_platform_thread_init_cond(loader_platform_thread_cond* pCond)
+{
+ pthread_cond_init(pCond, NULL);
+}
+static inline void loader_platform_thread_cond_wait(loader_platform_thread_cond* pCond, loader_platform_thread_mutex* pMutex)
+{
+ pthread_cond_wait(pCond, pMutex);
+}
+static inline void loader_platform_thread_cond_broadcast(loader_platform_thread_cond* pCond)
+{
+ pthread_cond_broadcast(pCond);
+}
#elif defined(_WIN32) // defined(__linux__)
diff --git a/vk-layer-generate.py b/vk-layer-generate.py
index 5c43a942..30c5d6f0 100755
--- a/vk-layer-generate.py
+++ b/vk-layer-generate.py
@@ -399,7 +399,7 @@ class Subcommand(object):
"}\n")
return "\n".join(func_body)
- def _generate_layer_initialization(self, init_opts=False, prefix='vk', lockname=None):
+ def _generate_layer_initialization(self, init_opts=False, prefix='vk', lockname=None, condname=None):
func_body = ["#include \"vk_dispatch_table_helper.h\""]
func_body.append('static void init%s(void)\n'
'{\n' % self.layer_name)
@@ -430,29 +430,13 @@ class Subcommand(object):
func_body.append(" {")
func_body.append(" // TODO/TBD: Need to delete this mutex sometime. How???")
func_body.append(" loader_platform_thread_create_mutex(&%sLock);" % lockname)
+ if condname is not None:
+ func_body.append(" loader_platform_thread_init_cond(&%sCond);" % condname)
func_body.append(" %sLockInitialized = 1;" % lockname)
func_body.append(" }")
func_body.append("}\n")
return "\n".join(func_body)
- def _generate_layer_initialization_with_lock(self, prefix='vk'):
- func_body = ["#include \"vk_dispatch_table_helper.h\""]
- func_body.append('static void init%s(void)\n'
- '{\n'
- ' PFN_vkGetProcAddr fpNextGPA;\n'
- ' fpNextGPA = pCurObj->pGPA;\n'
- ' assert(fpNextGPA);\n' % self.layer_name)
-
- func_body.append(" layer_initialize_dispatch_table(&nextTable, fpNextGPA, (VkPhysicalDevice) pCurObj->nextObject);\n")
- func_body.append(" if (!printLockInitialized)")
- func_body.append(" {")
- func_body.append(" // TODO/TBD: Need to delete this mutex sometime. How???")
- func_body.append(" loader_platform_thread_create_mutex(&printLock);")
- func_body.append(" printLockInitialized = 1;")
- func_body.append(" }")
- func_body.append("}\n")
- return "\n".join(func_body)
-
class LayerFuncsSubcommand(Subcommand):
def generate_header(self):
return '#include <vkLayer.h>\n#include "loader.h"'
@@ -1365,6 +1349,7 @@ class ThreadingSubcommand(Subcommand):
header_txt.append('static unordered_map<VkObject, loader_platform_thread_id> objectsInUse;\n')
header_txt.append('static int threadingLockInitialized = 0;')
header_txt.append('static loader_platform_thread_mutex threadingLock;')
+ header_txt.append('static loader_platform_thread_cond threadingCond;')
header_txt.append('static int printLockInitialized = 0;')
header_txt.append('static loader_platform_thread_mutex printLock;\n')
header_txt.append('')
@@ -1379,6 +1364,11 @@ class ThreadingSubcommand(Subcommand):
header_txt.append(' char str[1024];')
header_txt.append(' sprintf(str, "THREADING ERROR : object of type %s is simultaneously used in thread %ld and thread %ld", type, objectsInUse[object], tid);')
header_txt.append(' layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, 0, 0, THREADING_CHECKER_MULTIPLE_THREADS, "THREADING", str);')
+ header_txt.append(' // Wait for thread-safe access to object')
+ header_txt.append(' while (objectsInUse.find(object) != objectsInUse.end()) {')
+ header_txt.append(' loader_platform_thread_cond_wait(&threadingCond, &threadingLock);')
+ header_txt.append(' }')
+ header_txt.append(' objectsInUse[object] = tid;')
header_txt.append(' } else {')
header_txt.append(' char str[1024];')
header_txt.append(' sprintf(str, "THREADING ERROR : object of type %s is recursively used in thread %ld", type, tid);')
@@ -1392,6 +1382,7 @@ class ThreadingSubcommand(Subcommand):
header_txt.append(' // Object is no longer in use')
header_txt.append(' loader_platform_thread_lock_mutex(&threadingLock);')
header_txt.append(' objectsInUse.erase(object);')
+ header_txt.append(' loader_platform_thread_cond_broadcast(&threadingCond);')
header_txt.append(' loader_platform_thread_unlock_mutex(&threadingLock);')
header_txt.append('}')
return "\n".join(header_txt)
@@ -1501,7 +1492,7 @@ class ThreadingSubcommand(Subcommand):
def generate_body(self):
self.layer_name = "Threading"
- body = [self._generate_layer_initialization(True, lockname='threading'),
+ body = [self._generate_layer_initialization(True, lockname='threading', condname='threading'),
self._generate_dispatch_entrypoints("VK_LAYER_EXPORT"),
self._generate_layer_gpa_function()]
return "\n\n".join(body)