mstorsjo created this revision.
Herald added a subscriber: mehdi_amini.

This makes sure that the FDE cache is thread safe.

This requires building with `_WIN32_WINNT >= 0x0600`.

The alternative would be to skip the FDE cache altogether if building without 
threads.


https://reviews.llvm.org/D38704

Files:
  src/UnwindCursor.hpp


Index: src/UnwindCursor.hpp
===================================================================
--- src/UnwindCursor.hpp
+++ src/UnwindCursor.hpp
@@ -17,7 +17,11 @@
 #include <stdio.h>
 #include <stdlib.h>
 #ifndef _LIBUNWIND_HAS_NO_THREADS
-  #include <pthread.h>
+  #ifdef _WIN32
+    #include <windows.h>
+  #else
+    #include <pthread.h>
+  #endif
 #endif
 #include <unwind.h>
 
@@ -36,6 +40,34 @@
 #include "Registers.hpp"
 #include "Unwind-EHABI.h"
 
+#if !defined(_LIBUNWIND_HAS_NO_THREADS) && defined(_WIN32)
+#define pthread_rwlock_t SRWLOCK
+#define PTHREAD_RWLOCK_INITIALIZER SRWLOCK_INIT
+// As long as these functions are only ever used with one lock,
+// we can get away with a global flag to decide which kind of
+// unlock to do.
+static bool lockedForWrite = false;
+static int pthread_rwlock_rdlock(pthread_rwlock_t *lock) {
+  AcquireSRWLockShared(lock);
+  lockedForWrite = false;
+  return 0;
+}
+static int pthread_rwlock_wrlock(pthread_rwlock_t *lock) {
+  AcquireSRWLockExclusive(lock);
+  lockedForWrite = true;
+  return 0;
+}
+static int pthread_rwlock_unlock(pthread_rwlock_t *lock) {
+  if (lockedForWrite) {
+    lockedForWrite = false;
+    ReleaseSRWLockExclusive(lock);
+  } else {
+    ReleaseSRWLockShared(lock);
+  }
+  return 0;
+}
+#endif
+
 namespace libunwind {
 
 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)


Index: src/UnwindCursor.hpp
===================================================================
--- src/UnwindCursor.hpp
+++ src/UnwindCursor.hpp
@@ -17,7 +17,11 @@
 #include <stdio.h>
 #include <stdlib.h>
 #ifndef _LIBUNWIND_HAS_NO_THREADS
-  #include <pthread.h>
+  #ifdef _WIN32
+    #include <windows.h>
+  #else
+    #include <pthread.h>
+  #endif
 #endif
 #include <unwind.h>
 
@@ -36,6 +40,34 @@
 #include "Registers.hpp"
 #include "Unwind-EHABI.h"
 
+#if !defined(_LIBUNWIND_HAS_NO_THREADS) && defined(_WIN32)
+#define pthread_rwlock_t SRWLOCK
+#define PTHREAD_RWLOCK_INITIALIZER SRWLOCK_INIT
+// As long as these functions are only ever used with one lock,
+// we can get away with a global flag to decide which kind of
+// unlock to do.
+static bool lockedForWrite = false;
+static int pthread_rwlock_rdlock(pthread_rwlock_t *lock) {
+  AcquireSRWLockShared(lock);
+  lockedForWrite = false;
+  return 0;
+}
+static int pthread_rwlock_wrlock(pthread_rwlock_t *lock) {
+  AcquireSRWLockExclusive(lock);
+  lockedForWrite = true;
+  return 0;
+}
+static int pthread_rwlock_unlock(pthread_rwlock_t *lock) {
+  if (lockedForWrite) {
+    lockedForWrite = false;
+    ReleaseSRWLockExclusive(lock);
+  } else {
+    ReleaseSRWLockShared(lock);
+  }
+  return 0;
+}
+#endif
+
 namespace libunwind {
 
 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to