compnerd removed rL LLVM as the repository for this revision.
compnerd updated this revision to Diff 83432.
compnerd added a comment.

rebase


https://reviews.llvm.org/D28220

Files:
  include/__config
  include/__threading_support
  include/thread

Index: include/thread
===================================================================
--- include/thread
+++ include/thread
@@ -148,7 +148,8 @@
     __thread_specific_ptr(const __thread_specific_ptr&);
     __thread_specific_ptr& operator=(const __thread_specific_ptr&);
 
-    static void __at_thread_exit(void*);
+    static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);
+
 public:
     typedef _Tp* pointer;
 
@@ -164,21 +165,19 @@
 };
 
 template <class _Tp>
-void
+void _LIBCPP_TLS_DESTRUCTOR_CC
 __thread_specific_ptr<_Tp>::__at_thread_exit(void* __p)
 {
     delete static_cast<pointer>(__p);
 }
 
 template <class _Tp>
 __thread_specific_ptr<_Tp>::__thread_specific_ptr()
 {
-    int __ec = __libcpp_tls_create(
-        &__key_,
-        &__thread_specific_ptr::__at_thread_exit);
-    if (__ec)
-        __throw_system_error(__ec,
-                           "__thread_specific_ptr construction failed");
+  int __ec =
+      __libcpp_tls_create(&__key_, &__thread_specific_ptr::__at_thread_exit);
+  if (__ec)
+    __throw_system_error(__ec, "__thread_specific_ptr construction failed");
 }
 
 template <class _Tp>
Index: include/__threading_support
===================================================================
--- include/__threading_support
+++ include/__threading_support
@@ -24,6 +24,14 @@
 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
 # include <pthread.h>
 # include <sched.h>
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#include <assert.h>
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+#include <process.h>
+#include <fibersapi.h>
+
+#include <chrono>
 #endif
 
 #if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
@@ -58,6 +66,33 @@
 
 // Thrad Local Storage
 typedef pthread_key_t __libcpp_tls_key;
+
+#define _LIBCPP_TLS_DESTRUCTOR_CC
+#else
+// Mutex
+typedef SRWLOCK __libcpp_mutex_t;
+#define _LIBCPP_MUTEX_INITIALIZER SRWLOCK_INIT
+
+typedef CRITICAL_SECTION __libcpp_recursive_mutex_t;
+
+// Condition Variable
+typedef CONDITION_VARIABLE __libcpp_condvar_t;
+#define _LIBCPP_CONDVAR_INITIALIZER CONDITION_VARIABLE_INIT
+
+// Execute Once
+typedef INIT_ONCE __libcpp_exec_once_flag;
+#define _LIBCPP_EXEC_ONCE_INITIALIZER INIT_ONCE_STATIC_INIT
+
+// Thread ID
+typedef DWORD __libcpp_thread_id;
+
+// Thread
+typedef HANDLE __libcpp_thread_t;
+
+// Thread Local Storage
+typedef DWORD __libcpp_tls_key;
+
+#define _LIBCPP_TLS_DESTRUCTOR_CC WINAPI
 #endif
 
 // Mutex
@@ -321,6 +356,249 @@
     return pthread_setspecific(__key, __p);
 }
 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+
+// Mutex
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
+{
+  InitializeCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
+{
+  EnterCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
+{
+  TryEnterCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
+{
+  LeaveCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
+{
+  static_cast<void>(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
+{
+  AcquireSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
+{
+  TryAcquireSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
+{
+  ReleaseSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
+{
+  static_cast<void>(__m);
+  return 0;
+}
+
+// Condition Variable
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
+{
+  WakeConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
+{
+  WakeAllConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
+{
+  SleepConditionVariableSRW(__cv, __m, INFINITE, 0);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
+                               timespec *__ts)
+{
+  using namespace _VSTD::chrono;
+
+  auto duration = seconds(__ts->tv_sec) + nanoseconds(__ts->tv_nsec);
+  auto abstime =
+      system_clock::time_point(duration_cast<system_clock::duration>(duration));
+  auto timeout_ms = duration_cast<milliseconds>(abstime - system_clock::now());
+
+  if (!SleepConditionVariableSRW(__cv, __m,
+                                 timeout_ms.count() > 0 ? timeout_ms.count()
+                                                        : 0,
+                                 0))
+    return GetLastError();
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
+{
+  static_cast<void>(__cv);
+  return 0;
+}
+
+// Execute Once
+static inline _LIBCPP_ALWAYS_INLINE BOOL CALLBACK
+__libcpp_init_once_execute_once_thunk(PINIT_ONCE __init_once, PVOID __parameter,
+                                      PVOID *__context)
+{
+  static_cast<void>(__init_once);
+  static_cast<void>(__context);
+
+  void (*init_routine)(void) = reinterpret_cast<void (*)(void)>(__parameter);
+  init_routine();
+  return TRUE;
+}
+
+int __libcpp_execute_once(__libcpp_exec_once_flag *__flag,
+                          void (*__init_routine)(void))
+{
+  if (!InitOnceExecuteOnce(__flag, __libcpp_init_once_execute_once_thunk,
+                           reinterpret_cast<void *>(__init_routine), NULL))
+    return GetLastError();
+  return 0;
+}
+
+// Thread ID
+_LIBCPP_ALWAYS_INLINE
+bool __libcpp_thread_id_equal(__libcpp_thread_id __lhs,
+                              __libcpp_thread_id __rhs)
+{
+  return __lhs == __rhs;
+}
+
+_LIBCPP_ALWAYS_INLINE
+bool __libcpp_thread_id_less(__libcpp_thread_id __lhs, __libcpp_thread_id __rhs)
+{
+  return __lhs < __rhs;
+}
+
+// Thread
+struct __libcpp_beginthreadex_thunk_data
+{
+  void *(*__func)(void *);
+  void *__arg;
+};
+
+static inline _LIBCPP_ALWAYS_INLINE unsigned int WINAPI
+__libcpp_beginthreadex_thunk(void *__data)
+{
+  __libcpp_beginthreadex_thunk_data data =
+      *reinterpret_cast<__libcpp_beginthreadex_thunk_data *>(__data);
+  delete __data;
+  return reinterpret_cast<unsigned int>(data.__func(data.__arg));
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_thread_create(__libcpp_thread_t *__t, void (*__func)(void *),
+                           void *__arg)
+{
+  auto *data = new __libcpp_beginthreadex_thunk_data;
+  data->__func = __func;
+  data->__arg = __arg;
+
+  *__t = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0,
+                                                 __libcpp_beginthreadex_thunk,
+                                                 data, 0, NULL));
+  if (*__t)
+    return 0;
+  return GetLastError();
+}
+
+_LIBCPP_ALWAYS_INLINE
+__libcpp_thread_id __libcpp_thread_get_current_id()
+{
+  return GetCurrentThreadId();
+}
+
+_LIBCPP_ALWAYS_INLINE
+__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
+{
+  return GetThreadId(*__t);
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_thread_join(__libcpp_thread_t *__t)
+{
+  if (WaitForSingleObjectEx(*__t, INFINITE, FALSE) == WAIT_FAILED)
+    return GetLastError();
+  if (!CloseHandle(*__t))
+    return GetLastError();
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_thread_detach(__libcpp_thread_t *__t)
+{
+  if (!CloseHandle(*__t))
+    return GetLastError();
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_thread_yield()
+{
+  SwitchToThread();
+}
+
+// Thread Local Storage
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_tls_create(__libcpp_tls_key* __key,
+                        void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*))
+{
+  *__key = FlsAlloc(__at_exit);
+  if (*__key == FLS_OUT_OF_INDEXES)
+    return GetLastError();
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_tls_get(__libcpp_tls_key __key)
+{
+  return FlsGetValue(__key);
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
+{
+  if (!FlsSetValue(__key, __p))
+    return GetLastError();
+  return 0;
+}
+
 #endif // _LIBCPP_HAS_THREAD_API_PTHREAD
 
 #endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL
Index: include/__config
===================================================================
--- include/__config
+++ include/__config
@@ -905,6 +905,8 @@
 #   ifndef _LIBCPP_HAS_THREAD_API_PTHREAD
 #     define _LIBCPP_HAS_THREAD_API_PTHREAD
 #   endif
+# elif defined(_LIBCPP_WIN32API)
+#  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