compnerd updated this revision to Diff 82826.
compnerd added a comment.

Use SRW locks, rebase for avoid redeclaration of interfaces, remove static 
initialization check removals.


Repository:
  rL LLVM

https://reviews.llvm.org/D28220

Files:
  include/__config
  include/__threading_support

Index: include/__threading_support
===================================================================
--- include/__threading_support
+++ include/__threading_support
@@ -32,9 +32,20 @@
 #include <__external_threading>
 #else

+#if !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) &&                                \
+    !defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#error "unknown threading model"
+#endif
+
 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
 #include <pthread.h>
 #include <sched.h>
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRA_LEAN
+#include <Windows.h>
+#include <process.h>
+#include <fibersapi.h>
 #endif

 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
@@ -62,6 +73,23 @@

 // Thrad Local Storage
 typedef pthread_key_t __libcpp_tls_key;
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+// Mutex
+typedef SRWLOCK __libcpp_mutex_t;
+#define _LIBCPP_MUTEX_INITIALIZER SRWLOCK_INIT
+
+// Condition Variable
+typedef CONDITION_VARIABLE __libcpp_condvar_t;
+#define _LIBCPP_CONDVAR_INITIALIZER CONDITION_VARIABLE_INIT
+
+// Thread ID
+typedef DWORD __libcpp_thread_id;
+
+// Thread
+typedef HANDLE __libcpp_thread_t;
+
+// Thread Local Storage
+typedef DWORD __libcpp_tls_key;
 #endif

 // Mutex
@@ -267,6 +295,150 @@
   pthread_setspecific(__key, __p);
 }

+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+
+// Mutex
+int __libcpp_recursive_mutex_init(__libcpp_mutex_t *__m)
+{
+  InitializeSRWLock(__m);
+  return 0;
+}
+
+int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
+{
+  AcquireSRWLockExclusive(__m);
+  return 0;
+}
+
+int __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
+{
+  return TryAcquireSRWLockExclusive(__m);
+}
+
+int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
+{
+  ReleaseSRWLockExclusive(__m);
+  return 0;
+}
+
+int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
+{
+  static_cast<void>(__m);
+  return 0;
+}
+
+// Condition Variable
+int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
+{
+  WakeConditionVariable(__cv);
+  return 0;
+}
+
+int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
+{
+  WakeAllConditionVariable(__cv);
+  return 0;
+}
+
+int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
+{
+  SleepConditionVariableSRW(__cv, __m, INFINITE, 0);
+  return 0;
+}
+
+int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
+                               timespec *__ts)
+{
+  using namespace _VSTD::chrono;
+  auto timeout = seconds(__ts->tv_sec) + nanoseconds(__ts->tv_nsec);
+  // TODO(compnerd) handle timeouts < 10ms
+  // TODO(compnerd) handle spurious timeout
+  if (!SleepConditionVariableSRW(__cv, __m,
+                                 duration_cast<milliseconds>(timeout).count(),
+                                 0))
+    return GetLastError();
+  return 0;
+}
+
+int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
+{
+  static_cast<void>(__cv);
+  return 0;
+}
+
+// Thread ID
+bool __libcpp_thread_id_equal(__libcpp_thread_id __lhs,
+                              __libcpp_thread_id __rhs)
+{
+  return __lhs == __rhs;
+}
+
+bool __libcpp_thread_id_less(__libcpp_thread_id __lhs, __libcpp_thread_id __rhs)
+{
+  return __lhs < __rhs;
+}
+
+// Thread
+int __libcpp_thread_create(__libcpp_thread_t *__t,
+                           unsigned int (* WINAPI __func)(void *), void *__arg)
+{
+  *__t =
+      reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, __func, __arg, 0, NULL));
+  if (*__t)
+    return 0;
+  return GetLastError();
+}
+
+__libcpp_thread_id __libcpp_thread_get_current_id()
+{
+  return GetCurrentThreadId();
+}
+
+__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
+{
+  return GetThreadId(*__t);
+}
+
+int __libcpp_thread_join(__libcpp_thread_t *__t)
+{
+  if (WaitForSingleObjectEx(*__t, INFINITE, FALSE) == WAIT_FAILED)
+    return GetLastError();
+  if (!CloseHandle(*__t))
+    return GetLastError();
+  return 0;
+}
+
+int __libcpp_thread_detach(__libcpp_thread_t *__t)
+{
+  if (!CloseHandle(*__t))
+    return GetLastError();
+  return 0;
+}
+
+void __libcpp_thread_yield()
+{
+  SwitchToThread();
+}
+
+// Thread Local Storage
+int __libcpp_tls_create(__libcpp_tls_key *__key, void (* WINAPI __at_exit)(void *))
+{
+  *__key = FlsAlloc(__at_exit);
+  if (*__key == FLS_OUT_OF_INDEXES)
+    return GetLastError();
+  return 0;
+}
+
+void *__libcpp_tls_get(__libcpp_tls_key __key)
+{
+  return FlsGetValue(__key);
+}
+
+void __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
+{
+  FlsSetValue(__key, __p);
+}
+
 #endif // _LIBCPP_HAS_THREAD_API_PTHREAD

 _LIBCPP_END_NAMESPACE_STD
Index: include/__config
===================================================================
--- include/__config
+++ include/__config
@@ -882,6 +882,8 @@
     defined(__CloudABI__) || \
     defined(__sun__)
 #  define _LIBCPP_HAS_THREAD_API_PTHREAD
+# elif defined(_WIN32)
+#  define _LIBCPP_HAS_THREAD_API_WIN32
 # else
 #  error "No thread API"
 # endif // _LIBCPP_HAS_THREAD_API
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to