compnerd updated the summary for this revision.
compnerd updated this revision to Diff 83174.
Repository:
rL LLVM
https://reviews.llvm.org/D28220
Files:
include/__config
include/__threading_support
Index: include/__threading_support
===================================================================
--- include/__threading_support
+++ include/__threading_support
@@ -47,6 +47,12 @@
defined(_LIBCPP_HAS_THREAD_API_EXTERNAL_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>
#endif
#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
@@ -81,6 +87,29 @@
// Thrad Local Storage
typedef pthread_key_t __libcpp_tls_key;
+#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;
#endif
// Mutex
@@ -342,6 +371,247 @@
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 timeout = seconds(__ts->tv_sec) + nanoseconds(__ts->tv_nsec);
+ auto timeout_ms = duration_cast<milliseconds>(timeout);
+
+ _LIBCPP_ASSERT(timeout_ms.count() < _VSTD::numeric_limits<DWORD>::max() &&
+ "timeout duration overflow");
+
+ if (!SleepConditionVariableSRW(__cv, __m, timeout_ms.count(), 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 InitOnce, PVOID Parameter,
+ PVOID *Context)
+{
+ static_cast<void>(InitOnce);
+ 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);
+ _VSTD::free(__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)
+{
+ __libcpp_beginthreadex_thunk_data *data =
+ reinterpret_cast<__libcpp_beginthreadex_thunk_data *>(_VSTD::malloc(sizeof(*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 (*__at_exit)(void *))
+{
+ // TODO(compnerd) provide a wrapper for CC adjustment
+ *__key = FlsAlloc(reinterpret_cast<void (WINAPI *)(void *)>(__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
_LIBCPP_END_NAMESPACE_STD
Index: include/__config
===================================================================
--- include/__config
+++ include/__config
@@ -902,6 +902,8 @@
defined(__CloudABI__) || \
defined(__sun__)
# define _LIBCPP_HAS_THREAD_API_PTHREAD
+# elif defined(_LIBCPP_WIN32API)
+# define _LIBCPP_HAS_THREAD_API_WIN32
# else
# error "No thread API"
# endif // _LIBCPP_HAS_THREAD_API
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits