[libcxx] r323169 - libcxx: Move Windows threading support into a .cpp file.

Peter Collingbourne via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 22 17:59:43 PST 2018


Author: pcc
Date: Mon Jan 22 17:59:43 2018
New Revision: 323169

URL: http://llvm.org/viewvc/llvm-project?rev=323169&view=rev
Log:
libcxx: Move Windows threading support into a .cpp file.

This allows us to avoid polluting the namespace of users of <thread>
with the definitions in windows.h.

Differential Revision: https://reviews.llvm.org/D42214

Added:
    libcxx/trunk/src/support/win32/thread_win32.cpp
Modified:
    libcxx/trunk/include/__threading_support

Modified: libcxx/trunk/include/__threading_support
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__threading_support?rev=323169&r1=323168&r2=323169&view=diff
==============================================================================
--- libcxx/trunk/include/__threading_support (original)
+++ libcxx/trunk/include/__threading_support Mon Jan 22 17:59:43 2018
@@ -26,23 +26,11 @@
 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
 # include <pthread.h>
 # include <sched.h>
-#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
-#include <windows.h>
-#include <process.h>
-#include <fibersapi.h>
 #endif
 
 _LIBCPP_PUSH_MACROS
 #include <__undef_macros>
 
-
-#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
-    defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)
-#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
-#else
-#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
-#endif
-
 #if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis)
 #define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis))
 #else
@@ -51,7 +39,15 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
+#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
+    defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)
+
+#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
+
+#elif defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
+
+#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
+
 // Mutex
 typedef pthread_mutex_t __libcpp_mutex_t;
 #define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
@@ -79,32 +75,41 @@ typedef pthread_key_t __libcpp_tls_key;
 
 #define _LIBCPP_TLS_DESTRUCTOR_CC
 #else
+
+#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
+
 // Mutex
-typedef SRWLOCK __libcpp_mutex_t;
-#define _LIBCPP_MUTEX_INITIALIZER SRWLOCK_INIT
+typedef void* __libcpp_mutex_t;
+#define _LIBCPP_MUTEX_INITIALIZER 0
 
-typedef CRITICAL_SECTION __libcpp_recursive_mutex_t;
+#if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__)
+typedef void* __libcpp_recursive_mutex_t[6];
+#elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__)
+typedef void* __libcpp_recursive_mutex_t[5];
+#else
+# error Unsupported architecture
+#endif
 
 // Condition Variable
-typedef CONDITION_VARIABLE __libcpp_condvar_t;
-#define _LIBCPP_CONDVAR_INITIALIZER CONDITION_VARIABLE_INIT
+typedef void* __libcpp_condvar_t;
+#define _LIBCPP_CONDVAR_INITIALIZER 0
 
 // Execute Once
-typedef INIT_ONCE __libcpp_exec_once_flag;
-#define _LIBCPP_EXEC_ONCE_INITIALIZER INIT_ONCE_STATIC_INIT
+typedef void* __libcpp_exec_once_flag;
+#define _LIBCPP_EXEC_ONCE_INITIALIZER 0
 
 // Thread ID
-typedef DWORD __libcpp_thread_id;
+typedef long __libcpp_thread_id;
 
 // Thread
 #define _LIBCPP_NULL_THREAD 0U
 
-typedef HANDLE __libcpp_thread_t;
+typedef void* __libcpp_thread_t;
 
 // Thread Local Storage
-typedef DWORD __libcpp_tls_key;
+typedef long __libcpp_tls_key;
 
-#define _LIBCPP_TLS_DESTRUCTOR_CC WINAPI
+#define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall
 #endif
 
 // Mutex
@@ -201,10 +206,9 @@ void *__libcpp_tls_get(__libcpp_tls_key
 _LIBCPP_THREAD_ABI_VISIBILITY
 int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
 
-#if !defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
-    defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)
-
-#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
+#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
+     defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) && \
+    defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
 
 int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
 {
@@ -390,244 +394,6 @@ int __libcpp_tls_set(__libcpp_tls_key __
     return pthread_setspecific(__key, __p);
 }
 
-#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
-
-// Mutex
-int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
-{
-  InitializeCriticalSection(__m);
-  return 0;
-}
-
-int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
-{
-  EnterCriticalSection(__m);
-  return 0;
-}
-
-bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
-{
-  return TryEnterCriticalSection(__m) != 0;
-}
-
-int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
-{
-  LeaveCriticalSection(__m);
-  return 0;
-}
-
-int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
-{
-  DeleteCriticalSection(__m);
-  return 0;
-}
-
-int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
-{
-  AcquireSRWLockExclusive(__m);
-  return 0;
-}
-
-bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
-{
-  return TryAcquireSRWLockExclusive(__m) != 0;
-}
-
-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 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))
-    {
-      auto __ec = GetLastError();
-      return __ec == ERROR_TIMEOUT ? ETIMEDOUT : __ec;
-    }
-  return 0;
-}
-
-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
-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
-struct __libcpp_beginthreadex_thunk_data
-{
-  void *(*__func)(void *);
-  void *__arg;
-};
-
-static inline _LIBCPP_ALWAYS_INLINE unsigned WINAPI
-__libcpp_beginthreadex_thunk(void *__raw_data)
-{
-  auto *__data =
-      static_cast<__libcpp_beginthreadex_thunk_data *>(__raw_data);
-  auto *__func = __data->__func;
-  void *__arg = __data->__arg;
-  delete __data;
-  return static_cast<unsigned>(reinterpret_cast<uintptr_t>(__func(__arg)));
-}
-
-bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
-  return *__t == 0;
-}
-
-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(nullptr, 0,
-                                                 __libcpp_beginthreadex_thunk,
-                                                 __data, 0, nullptr));
-
-  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();
-}
-
-void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
-{
-  using namespace chrono;
-  // round-up to the nearest milisecond
-  milliseconds __ms =
-      duration_cast<milliseconds>(__ns + chrono::nanoseconds(999999));
-  // FIXME(compnerd) this should be an alertable sleep (WFSO or SleepEx)
-  Sleep(__ms.count());
-}
-
-// Thread Local Storage
-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;
-}
-
-void *__libcpp_tls_get(__libcpp_tls_key __key)
-{
-  return FlsGetValue(__key);
-}
-
-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
 
 _LIBCPP_END_NAMESPACE_STD

Added: libcxx/trunk/src/support/win32/thread_win32.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/support/win32/thread_win32.cpp?rev=323169&view=auto
==============================================================================
--- libcxx/trunk/src/support/win32/thread_win32.cpp (added)
+++ libcxx/trunk/src/support/win32/thread_win32.cpp Mon Jan 22 17:59:43 2018
@@ -0,0 +1,275 @@
+// -*- C++ -*-
+//===-------------------- support/win32/thread_win32.cpp ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <__threading_support>
+#include <windows.h>
+#include <process.h>
+#include <fibersapi.h>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+static_assert(sizeof(__libcpp_mutex_t) == sizeof(SRWLOCK), "");
+static_assert(alignof(__libcpp_mutex_t) == alignof(SRWLOCK), "");
+
+static_assert(sizeof(__libcpp_recursive_mutex_t) == sizeof(CRITICAL_SECTION),
+              "");
+static_assert(alignof(__libcpp_recursive_mutex_t) == alignof(CRITICAL_SECTION),
+              "");
+
+static_assert(sizeof(__libcpp_condvar_t) == sizeof(CONDITION_VARIABLE), "");
+static_assert(alignof(__libcpp_condvar_t) == alignof(CONDITION_VARIABLE), "");
+
+static_assert(sizeof(__libcpp_exec_once_flag) == sizeof(INIT_ONCE), "");
+static_assert(alignof(__libcpp_exec_once_flag) == alignof(INIT_ONCE), "");
+
+static_assert(sizeof(__libcpp_thread_id) == sizeof(DWORD), "");
+static_assert(alignof(__libcpp_thread_id) == alignof(DWORD), "");
+
+static_assert(sizeof(__libcpp_thread_t) == sizeof(HANDLE), "");
+static_assert(alignof(__libcpp_thread_t) == alignof(HANDLE), "");
+
+static_assert(sizeof(__libcpp_tls_key) == sizeof(DWORD), "");
+static_assert(alignof(__libcpp_tls_key) == alignof(DWORD), "");
+
+// Mutex
+int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
+{
+  InitializeCriticalSection((LPCRITICAL_SECTION)__m);
+  return 0;
+}
+
+int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
+{
+  EnterCriticalSection((LPCRITICAL_SECTION)__m);
+  return 0;
+}
+
+bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
+{
+  return TryEnterCriticalSection((LPCRITICAL_SECTION)__m) != 0;
+}
+
+int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
+{
+  LeaveCriticalSection((LPCRITICAL_SECTION)__m);
+  return 0;
+}
+
+int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
+{
+  DeleteCriticalSection((LPCRITICAL_SECTION)__m);
+  return 0;
+}
+
+int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
+{
+  AcquireSRWLockExclusive((PSRWLOCK)__m);
+  return 0;
+}
+
+bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
+{
+  return TryAcquireSRWLockExclusive((PSRWLOCK)__m) != 0;
+}
+
+int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
+{
+  ReleaseSRWLockExclusive((PSRWLOCK)__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((PCONDITION_VARIABLE)__cv);
+  return 0;
+}
+
+int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
+{
+  WakeAllConditionVariable((PCONDITION_VARIABLE)__cv);
+  return 0;
+}
+
+int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
+{
+  SleepConditionVariableSRW((PCONDITION_VARIABLE)__cv, (PSRWLOCK)__m, INFINITE, 0);
+  return 0;
+}
+
+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((PCONDITION_VARIABLE)__cv, (PSRWLOCK)__m,
+                                 timeout_ms.count() > 0 ? timeout_ms.count()
+                                                        : 0,
+                                 0))
+    {
+      auto __ec = GetLastError();
+      return __ec == ERROR_TIMEOUT ? ETIMEDOUT : __ec;
+    }
+  return 0;
+}
+
+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((PINIT_ONCE)__flag, __libcpp_init_once_execute_once_thunk,
+                           reinterpret_cast<void *>(__init_routine), NULL))
+    return GetLastError();
+  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
+struct __libcpp_beginthreadex_thunk_data
+{
+  void *(*__func)(void *);
+  void *__arg;
+};
+
+static inline _LIBCPP_ALWAYS_INLINE unsigned WINAPI
+__libcpp_beginthreadex_thunk(void *__raw_data)
+{
+  auto *__data =
+      static_cast<__libcpp_beginthreadex_thunk_data *>(__raw_data);
+  auto *__func = __data->__func;
+  void *__arg = __data->__arg;
+  delete __data;
+  return static_cast<unsigned>(reinterpret_cast<uintptr_t>(__func(__arg)));
+}
+
+bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
+  return *__t == 0;
+}
+
+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(nullptr, 0,
+                                                 __libcpp_beginthreadex_thunk,
+                                                 __data, 0, nullptr));
+
+  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();
+}
+
+void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
+{
+  using namespace chrono;
+  // round-up to the nearest milisecond
+  milliseconds __ms =
+      duration_cast<milliseconds>(__ns + chrono::nanoseconds(999999));
+  // FIXME(compnerd) this should be an alertable sleep (WFSO or SleepEx)
+  Sleep(__ms.count());
+}
+
+// Thread Local Storage
+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;
+}
+
+void *__libcpp_tls_get(__libcpp_tls_key __key)
+{
+  return FlsGetValue(__key);
+}
+
+int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
+{
+  if (!FlsSetValue(__key, __p))
+    return GetLastError();
+  return 0;
+}
+
+_LIBCPP_END_NAMESPACE_STD




More information about the cfe-commits mailing list