layers: threading - use std mutex

Change-Id: I773ea148807e5b634ad021ea58b001cd3d1bad87
diff --git a/layers/threading.h b/layers/threading.h
index 2116875..6c3a055 100644
--- a/layers/threading.h
+++ b/layers/threading.h
@@ -27,6 +27,8 @@
 
 #ifndef THREADING_H
 #define THREADING_H
+#include <condition_variable>
+#include <mutex>
 #include <vector>
 #include "vk_layer_config.h"
 #include "vk_layer_logging.h"
@@ -53,9 +55,8 @@
 
 struct layer_data;
 
-static int threadingLockInitialized = 0;
-static loader_platform_thread_mutex threadingLock;
-static loader_platform_thread_cond threadingCond;
+static std::mutex global_lock;
+static std::condition_variable global_condition;
 
 template <typename T> class counter {
   public:
@@ -65,7 +66,7 @@
     void startWrite(debug_report_data *report_data, T object) {
         bool skipCall = false;
         loader_platform_thread_id tid = loader_platform_get_thread_id();
-        loader_platform_thread_lock_mutex(&threadingLock);
+        std::unique_lock<std::mutex> lock(global_lock);
         if (uses.find(object) == uses.end()) {
             // There is no current use of the object.  Record writer thread.
             struct object_use_data *use_data = &uses[object];
@@ -84,7 +85,7 @@
                     if (skipCall) {
                         // Wait for thread-safe access to object instead of skipping call.
                         while (uses.find(object) != uses.end()) {
-                            loader_platform_thread_cond_wait(&threadingCond, &threadingLock);
+                            global_condition.wait(lock);
                         }
                         // There is now no current use of the object.  Record writer thread.
                         struct object_use_data *use_data = &uses[object];
@@ -111,7 +112,7 @@
                     if (skipCall) {
                         // Wait for thread-safe access to object instead of skipping call.
                         while (uses.find(object) != uses.end()) {
-                            loader_platform_thread_cond_wait(&threadingCond, &threadingLock);
+                            global_condition.wait(lock);
                         }
                         // There is now no current use of the object.  Record writer thread.
                         struct object_use_data *use_data = &uses[object];
@@ -130,25 +131,24 @@
                 }
             }
         }
-        loader_platform_thread_unlock_mutex(&threadingLock);
     }
 
     void finishWrite(T object) {
         // Object is no longer in use
-        loader_platform_thread_lock_mutex(&threadingLock);
+        std::unique_lock<std::mutex> lock(global_lock);
         uses[object].writer_count -= 1;
         if ((uses[object].reader_count == 0) && (uses[object].writer_count == 0)) {
             uses.erase(object);
         }
         // Notify any waiting threads that this object may be safe to use
-        loader_platform_thread_cond_broadcast(&threadingCond);
-        loader_platform_thread_unlock_mutex(&threadingLock);
+        lock.unlock();
+        global_condition.notify_all();
     }
 
     void startRead(debug_report_data *report_data, T object) {
         bool skipCall = false;
         loader_platform_thread_id tid = loader_platform_get_thread_id();
-        loader_platform_thread_lock_mutex(&threadingLock);
+        std::unique_lock<std::mutex> lock(global_lock);
         if (uses.find(object) == uses.end()) {
             // There is no current use of the object.  Record reader count
             struct object_use_data *use_data = &uses[object];
@@ -164,7 +164,7 @@
             if (skipCall) {
                 // Wait for thread-safe access to object instead of skipping call.
                 while (uses.find(object) != uses.end()) {
-                    loader_platform_thread_cond_wait(&threadingCond, &threadingLock);
+                    global_condition.wait(lock);
                 }
                 // There is no current use of the object.  Record reader count
                 struct object_use_data *use_data = &uses[object];
@@ -178,17 +178,16 @@
             // There are other readers of the object.  Increase reader count
             uses[object].reader_count += 1;
         }
-        loader_platform_thread_unlock_mutex(&threadingLock);
     }
     void finishRead(T object) {
-        loader_platform_thread_lock_mutex(&threadingLock);
+        std::unique_lock<std::mutex> lock(global_lock);
         uses[object].reader_count -= 1;
         if ((uses[object].reader_count == 0) && (uses[object].writer_count == 0)) {
             uses.erase(object);
         }
         // Notify and waiting threads that this object may be safe to use
-        loader_platform_thread_cond_broadcast(&threadingCond);
-        loader_platform_thread_unlock_mutex(&threadingLock);
+        lock.unlock();
+        global_condition.notify_all();
     }
     counter(const char *name = "", VkDebugReportObjectTypeEXT type = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT) {
         typeName = name;
@@ -307,9 +306,9 @@
 // VkCommandBuffer needs check for implicit use of command pool
 static void startWriteObject(struct layer_data *my_data, VkCommandBuffer object, bool lockPool = true) {
     if (lockPool) {
-        loader_platform_thread_lock_mutex(&threadingLock);
+        std::unique_lock<std::mutex> lock(global_lock);
         VkCommandPool pool = command_pool_map[object];
-        loader_platform_thread_unlock_mutex(&threadingLock);
+        lock.unlock();
         startWriteObject(my_data, pool);
     }
     my_data->c_VkCommandBuffer.startWrite(my_data->report_data, object);
@@ -317,24 +316,24 @@
 static void finishWriteObject(struct layer_data *my_data, VkCommandBuffer object, bool lockPool = true) {
     my_data->c_VkCommandBuffer.finishWrite(object);
     if (lockPool) {
-        loader_platform_thread_lock_mutex(&threadingLock);
+        std::unique_lock<std::mutex> lock(global_lock);
         VkCommandPool pool = command_pool_map[object];
-        loader_platform_thread_unlock_mutex(&threadingLock);
+        lock.unlock();
         finishWriteObject(my_data, pool);
     }
 }
 static void startReadObject(struct layer_data *my_data, VkCommandBuffer object) {
-    loader_platform_thread_lock_mutex(&threadingLock);
+    std::unique_lock<std::mutex> lock(global_lock);
     VkCommandPool pool = command_pool_map[object];
-    loader_platform_thread_unlock_mutex(&threadingLock);
+    lock.unlock();
     startReadObject(my_data, pool);
     my_data->c_VkCommandBuffer.startRead(my_data->report_data, object);
 }
 static void finishReadObject(struct layer_data *my_data, VkCommandBuffer object) {
     my_data->c_VkCommandBuffer.finishRead(object);
-    loader_platform_thread_lock_mutex(&threadingLock);
+    std::unique_lock<std::mutex> lock(global_lock);
     VkCommandPool pool = command_pool_map[object];
-    loader_platform_thread_unlock_mutex(&threadingLock);
+    lock.unlock();
     finishReadObject(my_data, pool);
 }
 #endif // THREADING_H