[libcxx] Implement semaphores for windows
authorMartin Storsjö <martin@martin.st>
Thu, 25 Feb 2021 22:41:35 +0000 (00:41 +0200)
committerMartin Storsjö <martin@martin.st>
Fri, 5 Mar 2021 08:48:59 +0000 (10:48 +0200)
Also add WIN32_LEAN_AND_MEAN before including windows.h, for consistency
with other sources.

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

libcxx/include/__threading_support
libcxx/src/support/win32/thread_win32.cpp

index 46438b7..430ec54 100644 (file)
@@ -15,6 +15,7 @@
 #include <chrono>
 #include <iosfwd>
 #include <errno.h>
+#include <limits>
 
 #ifdef __MVS__
 # include <__support/ibm/nanosleep.h>
@@ -149,6 +150,9 @@ typedef void* __libcpp_condvar_t;
 
 // Semaphore
 typedef void* __libcpp_semaphore_t;
+#if defined(_LIBCPP_HAS_THREAD_API_WIN32)
+# define _LIBCPP_SEMAPHORE_MAX (::std::numeric_limits<long>::max())
+#endif
 
 // Execute Once
 typedef void* __libcpp_exec_once_flag;
index 35c4c87..2b1aa56 100644 (file)
@@ -8,6 +8,8 @@
 //===----------------------------------------------------------------------===//
 
 #include <__threading_support>
+#define NOMINMAX
+#define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <process.h>
 #include <fibersapi.h>
@@ -37,6 +39,9 @@ static_assert(alignof(__libcpp_thread_t) == alignof(HANDLE), "");
 static_assert(sizeof(__libcpp_tls_key) == sizeof(DWORD), "");
 static_assert(alignof(__libcpp_tls_key) == alignof(DWORD), "");
 
+static_assert(sizeof(__libcpp_semaphore_t) == sizeof(HANDLE), "");
+static_assert(alignof(__libcpp_semaphore_t) == alignof(HANDLE), "");
+
 // Mutex
 int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
 {
@@ -272,4 +277,37 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
   return 0;
 }
 
+// Semaphores
+bool __libcpp_semaphore_init(__libcpp_semaphore_t* __sem, int __init)
+{
+  *(PHANDLE)__sem = CreateSemaphoreEx(nullptr, __init, _LIBCPP_SEMAPHORE_MAX,
+                                      nullptr, 0, SEMAPHORE_ALL_ACCESS);
+  return *__sem != nullptr;
+}
+
+bool __libcpp_semaphore_destroy(__libcpp_semaphore_t* __sem)
+{
+  CloseHandle(*(PHANDLE)__sem);
+  return true;
+}
+
+bool __libcpp_semaphore_post(__libcpp_semaphore_t* __sem)
+{
+  return ReleaseSemaphore(*(PHANDLE)__sem, 1, nullptr);
+}
+
+bool __libcpp_semaphore_wait(__libcpp_semaphore_t* __sem)
+{
+  return WaitForSingleObjectEx(*(PHANDLE)__sem, INFINITE, false) ==
+         WAIT_OBJECT_0;
+}
+
+bool __libcpp_semaphore_wait_timed(__libcpp_semaphore_t* __sem,
+                                   chrono::nanoseconds const& __ns)
+{
+  chrono::milliseconds __ms = std::chrono::ceil<chrono::milliseconds>(__ns);
+  return WaitForSingleObjectEx(*(PHANDLE)__sem, __ms.count(), false) ==
+         WAIT_OBJECT_0;
+}
+
 _LIBCPP_END_NAMESPACE_STD