Skip to content

Commit 1773eec

Browse files
committed
[libcxx] Implement semaphores for windows
Also add WIN32_LEAN_AND_MEAN before including windows.h, for consistency with other sources. Differential Revision: https://reviews.llvm.org/D97539
1 parent 579fd02 commit 1773eec

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

libcxx/include/__threading_support

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <chrono>
1616
#include <iosfwd>
1717
#include <errno.h>
18+
#include <limits>
1819

1920
#ifdef __MVS__
2021
# include <__support/ibm/nanosleep.h>
@@ -149,6 +150,9 @@ typedef void* __libcpp_condvar_t;
149150

150151
// Semaphore
151152
typedef void* __libcpp_semaphore_t;
153+
#if defined(_LIBCPP_HAS_THREAD_API_WIN32)
154+
# define _LIBCPP_SEMAPHORE_MAX (::std::numeric_limits<long>::max())
155+
#endif
152156

153157
// Execute Once
154158
typedef void* __libcpp_exec_once_flag;

libcxx/src/support/win32/thread_win32.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
//===----------------------------------------------------------------------===//
99

1010
#include <__threading_support>
11+
#define NOMINMAX
12+
#define WIN32_LEAN_AND_MEAN
1113
#include <windows.h>
1214
#include <process.h>
1315
#include <fibersapi.h>
@@ -37,6 +39,9 @@ static_assert(alignof(__libcpp_thread_t) == alignof(HANDLE), "");
3739
static_assert(sizeof(__libcpp_tls_key) == sizeof(DWORD), "");
3840
static_assert(alignof(__libcpp_tls_key) == alignof(DWORD), "");
3941

42+
static_assert(sizeof(__libcpp_semaphore_t) == sizeof(HANDLE), "");
43+
static_assert(alignof(__libcpp_semaphore_t) == alignof(HANDLE), "");
44+
4045
// Mutex
4146
int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
4247
{
@@ -272,4 +277,37 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
272277
return 0;
273278
}
274279

280+
// Semaphores
281+
bool __libcpp_semaphore_init(__libcpp_semaphore_t* __sem, int __init)
282+
{
283+
*(PHANDLE)__sem = CreateSemaphoreEx(nullptr, __init, _LIBCPP_SEMAPHORE_MAX,
284+
nullptr, 0, SEMAPHORE_ALL_ACCESS);
285+
return *__sem != nullptr;
286+
}
287+
288+
bool __libcpp_semaphore_destroy(__libcpp_semaphore_t* __sem)
289+
{
290+
CloseHandle(*(PHANDLE)__sem);
291+
return true;
292+
}
293+
294+
bool __libcpp_semaphore_post(__libcpp_semaphore_t* __sem)
295+
{
296+
return ReleaseSemaphore(*(PHANDLE)__sem, 1, nullptr);
297+
}
298+
299+
bool __libcpp_semaphore_wait(__libcpp_semaphore_t* __sem)
300+
{
301+
return WaitForSingleObjectEx(*(PHANDLE)__sem, INFINITE, false) ==
302+
WAIT_OBJECT_0;
303+
}
304+
305+
bool __libcpp_semaphore_wait_timed(__libcpp_semaphore_t* __sem,
306+
chrono::nanoseconds const& __ns)
307+
{
308+
chrono::milliseconds __ms = std::chrono::ceil<chrono::milliseconds>(__ns);
309+
return WaitForSingleObjectEx(*(PHANDLE)__sem, __ms.count(), false) ==
310+
WAIT_OBJECT_0;
311+
}
312+
275313
_LIBCPP_END_NAMESPACE_STD

0 commit comments

Comments
 (0)