diff options
| author | Mike Stroyan <mike@LunarG.com> | 2015-05-15 08:50:57 -0600 |
|---|---|---|
| committer | Mike Stroyan <mike@LunarG.com> | 2015-05-15 15:38:23 -0600 |
| commit | cbf8fc1ce9911fa700009a1c7cfaa61e3eddbe8e (patch) | |
| tree | 4a3e17b85dd61e944a3e2d787b7a334255f54ca7 | |
| parent | 9fde28dffb7e642dfa282e5bb8df44d9f4c2444a (diff) | |
| download | usermoji-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.h | 13 | ||||
| -rwxr-xr-x | vk-layer-generate.py | 31 |
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) |
