mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Threading] Add ConditionVariable support.
Swift Concurrency would like to be able to use condition variables. Add support to the threading packages. rdar://100236038
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
#define SWIFT_THREADING_IMPL_C11_H
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
|
||||
#include <threads.h>
|
||||
@@ -36,13 +37,13 @@ namespace threading_impl {
|
||||
swift::threading::fatal(#expr " failed with error %d\n", res_); \
|
||||
} while (0)
|
||||
|
||||
#define SWIFT_C11THREADS_RETURN_TRUE_OR_FALSE(expr) \
|
||||
#define SWIFT_C11THREADS_RETURN_TRUE_OR_FALSE(falseerr, expr) \
|
||||
do { \
|
||||
int res_ = (expr); \
|
||||
switch (res_) { \
|
||||
case thrd_success: \
|
||||
return true; \
|
||||
case thrd_busy: \
|
||||
case falseerr: \
|
||||
return false; \
|
||||
default: \
|
||||
swift::threading::fatal(#expr " failed with error (%d)\n", res_); \
|
||||
@@ -78,7 +79,7 @@ inline void mutex_unlock(mutex_handle &handle) {
|
||||
SWIFT_C11THREADS_CHECK(::mtx_unlock(&handle));
|
||||
}
|
||||
inline bool mutex_try_lock(mutex_handle &handle) {
|
||||
SWIFT_C11THREADS_RETURN_TRUE_OR_FALSE(::mtx_trylock(&handle));
|
||||
SWIFT_C11THREADS_RETURN_TRUE_OR_FALSE(thrd_busy, ::mtx_trylock(&handle));
|
||||
}
|
||||
|
||||
inline void mutex_unsafe_lock(mutex_handle &handle) {
|
||||
@@ -134,7 +135,7 @@ inline void lazy_mutex_unlock(lazy_mutex_handle &handle) {
|
||||
}
|
||||
inline bool lazy_mutex_try_lock(lazy_mutex_handle &handle) {
|
||||
lazy_mutex_init(handle);
|
||||
SWIFT_C11THREADS_RETURN_TRUE_OR_FALSE(::mtx_trylock(&handle.mutex));
|
||||
SWIFT_C11THREADS_RETURN_TRUE_OR_FALSE(thrd_busy, ::mtx_trylock(&handle.mutex));
|
||||
}
|
||||
|
||||
inline void lazy_mutex_unsafe_lock(lazy_mutex_handle &handle) {
|
||||
@@ -146,6 +147,53 @@ inline void lazy_mutex_unsafe_unlock(lazy_mutex_handle &handle) {
|
||||
(void)::mtx_unlock(&handle.mutex);
|
||||
}
|
||||
|
||||
// .. ConditionVariable support ..............................................
|
||||
|
||||
struct cond_handle {
|
||||
::cnd_t condition;
|
||||
::mtx_t mutex;
|
||||
};
|
||||
|
||||
inline void cond_init(cond_handle &handle) {
|
||||
SWIFT_C11THREADS_CHECK(::cnd_init(&handle.condition));
|
||||
SWIFT_C11THREADS_CHECK(::mtx_init(&handle.mutex, ::mtx_plain));
|
||||
}
|
||||
inline void cond_destroy(cond_handle &handle) {
|
||||
::cnd_destroy(&handle.condition);
|
||||
::mtx_destroy(&handle.mutex);
|
||||
}
|
||||
inline void cond_lock(cond_handle &handle) {
|
||||
SWIFT_C11THREADS_CHECK(::mtx_lock(&handle.mutex));
|
||||
}
|
||||
inline void cond_unlock(cond_handle &handle) {
|
||||
SWIFT_C11THREADS_CHECK(::mtx_unlock(&handle.mutex));
|
||||
}
|
||||
inline void cond_signal(cond_handle &handle) {
|
||||
SWIFT_C11THREADS_CHECK(::cnd_signal(&handle.condition));
|
||||
}
|
||||
inline void cond_broadcast(cond_handle &handle) {
|
||||
SWIFT_C11THREADS_CHECK(::cnd_broadcast(&handle.condition));
|
||||
}
|
||||
inline void cond_wait(cond_handle &handle) {
|
||||
SWIFT_C11THREADS_CHECK(::cnd_wait(&handle.condition, &handle.mutex));
|
||||
}
|
||||
template <class Rep, class Period>
|
||||
inline bool cond_wait(cond_handle &handle,
|
||||
std::chrono::duration<Rep, Period> duration) {
|
||||
auto deadline = std::chrono::system_clock::now() + duration;
|
||||
return cond_wait(handle, deadline);
|
||||
}
|
||||
inline bool cond_wait(cond_handle &handle,
|
||||
std::chrono::system_clock::time_point deadline) {
|
||||
auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
deadline.time_since_epoch()).count();
|
||||
struct ::timespec ts = { ::time_t(ns / 1000000000), long(ns % 1000000000) };
|
||||
SWIFT_C11THREADS_RETURN_TRUE_OR_FALSE(
|
||||
thrd_timedout,
|
||||
::cnd_timedwait(&handle.condition, &handle.mutex, &ts)
|
||||
);
|
||||
}
|
||||
|
||||
// .. Once ...................................................................
|
||||
|
||||
typedef std::atomic<std::intptr_t> once_t;
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <os/lock.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "llvm/ADT/Optional.h"
|
||||
|
||||
#include "swift/Threading/Errors.h"
|
||||
@@ -28,6 +30,26 @@
|
||||
namespace swift {
|
||||
namespace threading_impl {
|
||||
|
||||
#define SWIFT_PTHREADS_CHECK(expr) \
|
||||
do { \
|
||||
int res_ = (expr); \
|
||||
if (res_ != 0) \
|
||||
swift::threading::fatal(#expr " failed with error %d\n", res_); \
|
||||
} while (0)
|
||||
|
||||
#define SWIFT_PTHREADS_RETURN_TRUE_OR_FALSE(falseerr, expr) \
|
||||
do { \
|
||||
int res_ = (expr); \
|
||||
switch (res_) { \
|
||||
case 0: \
|
||||
return true; \
|
||||
case falseerr: \
|
||||
return false; \
|
||||
default: \
|
||||
swift::threading::fatal(#expr " failed with error (%d)\n", res_); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// .. Thread related things ..................................................
|
||||
|
||||
using thread_id = ::pthread_t;
|
||||
@@ -102,6 +124,55 @@ inline void lazy_mutex_unsafe_unlock(lazy_mutex_handle &handle) {
|
||||
::os_unfair_lock_unlock(&handle);
|
||||
}
|
||||
|
||||
// .. ConditionVariable support ..............................................
|
||||
|
||||
struct cond_handle {
|
||||
::pthread_cond_t condition;
|
||||
::pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
inline void cond_init(cond_handle &handle) {
|
||||
handle.condition = PTHREAD_COND_INITIALIZER;
|
||||
handle.mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
}
|
||||
inline void cond_destroy(cond_handle &handle) {
|
||||
SWIFT_PTHREADS_CHECK(::pthread_cond_destroy(&handle.condition));
|
||||
SWIFT_PTHREADS_CHECK(::pthread_mutex_destroy(&handle.mutex));
|
||||
}
|
||||
inline void cond_lock(cond_handle &handle) {
|
||||
SWIFT_PTHREADS_CHECK(::pthread_mutex_lock(&handle.mutex));
|
||||
}
|
||||
inline void cond_unlock(cond_handle &handle) {
|
||||
SWIFT_PTHREADS_CHECK(::pthread_mutex_unlock(&handle.mutex));
|
||||
}
|
||||
inline void cond_signal(cond_handle &handle) {
|
||||
SWIFT_PTHREADS_CHECK(::pthread_cond_signal(&handle.condition));
|
||||
}
|
||||
inline void cond_broadcast(cond_handle &handle) {
|
||||
SWIFT_PTHREADS_CHECK(::pthread_cond_broadcast(&handle.condition));
|
||||
}
|
||||
inline void cond_wait(cond_handle &handle) {
|
||||
SWIFT_PTHREADS_CHECK(::pthread_cond_wait(&handle.condition, &handle.mutex));
|
||||
}
|
||||
template <class Rep, class Period>
|
||||
inline bool cond_wait(cond_handle &handle,
|
||||
std::chrono::duration<Rep, Period> duration) {
|
||||
auto deadline = std::chrono::time_point_cast<
|
||||
std::chrono::system_clock::duration>(std::chrono::system_clock::now()
|
||||
+ duration);
|
||||
return cond_wait(handle, deadline);
|
||||
}
|
||||
inline bool cond_wait(cond_handle &handle,
|
||||
std::chrono::system_clock::time_point deadline) {
|
||||
auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
deadline.time_since_epoch()).count();
|
||||
struct ::timespec ts = { ::time_t(ns / 1000000000), long(ns % 1000000000) };
|
||||
SWIFT_PTHREADS_RETURN_TRUE_OR_FALSE(
|
||||
ETIMEDOUT,
|
||||
::pthread_cond_timedwait(&handle.condition, &handle.mutex, &ts)
|
||||
);
|
||||
}
|
||||
|
||||
// .. Once ...................................................................
|
||||
|
||||
using once_t = ::dispatch_once_t;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//==--- Pthreads.h - Threading abstraction implementation ------ -*-C++ -*-===//
|
||||
//==--- Linux.h - Threading abstraction implementation --------- -*-C++ -*-===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <pthread.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <optional>
|
||||
|
||||
#include "llvm/ADT/Optional.h"
|
||||
@@ -39,13 +40,13 @@ namespace threading_impl {
|
||||
swift::threading::fatal(#expr " failed with error %d\n", res_); \
|
||||
} while (0)
|
||||
|
||||
#define SWIFT_LINUXTHREADS_RETURN_TRUE_OR_FALSE(expr) \
|
||||
#define SWIFT_LINUXTHREADS_RETURN_TRUE_OR_FALSE(falseerr, expr) \
|
||||
do { \
|
||||
int res_ = (expr); \
|
||||
switch (res_) { \
|
||||
case 0: \
|
||||
return true; \
|
||||
case EBUSY: \
|
||||
case falseerr: \
|
||||
return false; \
|
||||
default: \
|
||||
swift::threading::fatal(#expr " failed with error (%d)\n", res_); \
|
||||
@@ -93,7 +94,8 @@ inline void mutex_unlock(mutex_handle &handle) {
|
||||
SWIFT_LINUXTHREADS_CHECK(::pthread_mutex_unlock(&handle));
|
||||
}
|
||||
inline bool mutex_try_lock(mutex_handle &handle) {
|
||||
SWIFT_LINUXTHREADS_RETURN_TRUE_OR_FALSE(::pthread_mutex_trylock(&handle));
|
||||
SWIFT_LINUXTHREADS_RETURN_TRUE_OR_FALSE(EBUSY,
|
||||
::pthread_mutex_trylock(&handle));
|
||||
}
|
||||
|
||||
inline void mutex_unsafe_lock(mutex_handle &handle) {
|
||||
@@ -121,7 +123,8 @@ inline void lazy_mutex_unlock(lazy_mutex_handle &handle) {
|
||||
SWIFT_LINUXTHREADS_CHECK(::pthread_mutex_unlock(&handle));
|
||||
}
|
||||
inline bool lazy_mutex_try_lock(lazy_mutex_handle &handle) {
|
||||
SWIFT_LINUXTHREADS_RETURN_TRUE_OR_FALSE(::pthread_mutex_trylock(&handle));
|
||||
SWIFT_LINUXTHREADS_RETURN_TRUE_OR_FALSE(EBUSY,
|
||||
::pthread_mutex_trylock(&handle));
|
||||
}
|
||||
|
||||
inline void lazy_mutex_unsafe_lock(lazy_mutex_handle &handle) {
|
||||
@@ -131,6 +134,55 @@ inline void lazy_mutex_unsafe_unlock(lazy_mutex_handle &handle) {
|
||||
(void)::pthread_mutex_unlock(&handle);
|
||||
}
|
||||
|
||||
// .. ConditionVariable support ..............................................
|
||||
|
||||
struct cond_handle {
|
||||
::pthread_cond_t condition;
|
||||
::pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
inline void cond_init(cond_handle &handle) {
|
||||
handle.condition = PTHREAD_COND_INITIALIZER;
|
||||
handle.mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
}
|
||||
inline void cond_destroy(cond_handle &handle) {
|
||||
SWIFT_LINUXTHREADS_CHECK(::pthread_cond_destroy(&handle.condition));
|
||||
SWIFT_LINUXTHREADS_CHECK(::pthread_mutex_destroy(&handle.mutex));
|
||||
}
|
||||
inline void cond_lock(cond_handle &handle) {
|
||||
SWIFT_LINUXTHREADS_CHECK(::pthread_mutex_lock(&handle.mutex));
|
||||
}
|
||||
inline void cond_unlock(cond_handle &handle) {
|
||||
SWIFT_LINUXTHREADS_CHECK(::pthread_mutex_unlock(&handle.mutex));
|
||||
}
|
||||
inline void cond_signal(cond_handle &handle) {
|
||||
SWIFT_LINUXTHREADS_CHECK(::pthread_cond_signal(&handle.condition));
|
||||
}
|
||||
inline void cond_broadcast(cond_handle &handle) {
|
||||
SWIFT_LINUXTHREADS_CHECK(::pthread_cond_broadcast(&handle.condition));
|
||||
}
|
||||
inline void cond_wait(cond_handle &handle) {
|
||||
SWIFT_LINUXTHREADS_CHECK(::pthread_cond_wait(&handle.condition, &handle.mutex));
|
||||
}
|
||||
template <class Rep, class Period>
|
||||
inline bool cond_wait(cond_handle &handle,
|
||||
std::chrono::duration<Rep, Period> duration) {
|
||||
auto deadline = std::chrono::time_point_cast<
|
||||
std::chrono::system_clock::duration>(std::chrono::system_clock::now()
|
||||
+ duration);
|
||||
return cond_wait(handle, deadline);
|
||||
}
|
||||
inline bool cond_wait(cond_handle &handle,
|
||||
std::chrono::system_clock::time_point deadline) {
|
||||
auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
deadline.time_since_epoch()).count();
|
||||
struct ::timespec ts = { ::time_t(ns / 1000000000), long(ns % 1000000000) };
|
||||
SWIFT_LINUXTHREADS_RETURN_TRUE_OR_FALSE(
|
||||
ETIMEDOUT,
|
||||
::pthread_cond_timedwait(&handle.condition, &handle.mutex, &ts)
|
||||
);
|
||||
}
|
||||
|
||||
// .. Once ...................................................................
|
||||
|
||||
struct once_t {
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
#include "llvm/ADT/Optional.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace swift {
|
||||
namespace threading_impl {
|
||||
|
||||
@@ -57,6 +59,27 @@ inline bool lazy_mutex_try_lock(lazy_mutex_handle &handle) { return true; }
|
||||
inline void lazy_mutex_unsafe_lock(lazy_mutex_handle &handle) {}
|
||||
inline void lazy_mutex_unsafe_unlock(lazy_mutex_handle &handle) {}
|
||||
|
||||
// .. ConditionVariable support ..............................................
|
||||
|
||||
using cond_handle = unsigned;
|
||||
|
||||
inline void cond_init(cond_handle &handle) {}
|
||||
inline void cond_destroy(cond_handle &handle) {}
|
||||
inline void cond_lock(cond_handle &handle) {}
|
||||
inline void cond_unlock(cond_handle &handle) {}
|
||||
inline void cond_signal(cond_handle &handle) {}
|
||||
inline void cond_broadcast(cond_handle &handle) {}
|
||||
inline void cond_wait(cond_handle &handle) {}
|
||||
template <class Rep, class Period>
|
||||
inline bool cond_wait(cond_handle &handle,
|
||||
std::chrono::duration<Rep, Period> duration) {
|
||||
return true;
|
||||
}
|
||||
inline bool cond_wait(cond_handle &handle,
|
||||
std::chrono::system_clock::time_point deadline) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// .. Once ...................................................................
|
||||
|
||||
typedef bool once_t;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <pthread.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
|
||||
#include "llvm/ADT/Optional.h"
|
||||
@@ -37,13 +38,13 @@ namespace threading_impl {
|
||||
swift::threading::fatal(#expr " failed with error %d\n", res_); \
|
||||
} while (0)
|
||||
|
||||
#define SWIFT_PTHREADS_RETURN_TRUE_OR_FALSE(expr) \
|
||||
#define SWIFT_PTHREADS_RETURN_TRUE_OR_FALSE(falseerr, expr) \
|
||||
do { \
|
||||
int res_ = (expr); \
|
||||
switch (res_) { \
|
||||
case 0: \
|
||||
return true; \
|
||||
case EBUSY: \
|
||||
case falseerr: \
|
||||
return false; \
|
||||
default: \
|
||||
swift::threading::fatal(#expr " failed with error (%d)\n", res_); \
|
||||
@@ -91,7 +92,7 @@ inline void mutex_unlock(mutex_handle &handle) {
|
||||
SWIFT_PTHREADS_CHECK(::pthread_mutex_unlock(&handle));
|
||||
}
|
||||
inline bool mutex_try_lock(mutex_handle &handle) {
|
||||
SWIFT_PTHREADS_RETURN_TRUE_OR_FALSE(::pthread_mutex_trylock(&handle));
|
||||
SWIFT_PTHREADS_RETURN_TRUE_OR_FALSE(EBUSY, ::pthread_mutex_trylock(&handle));
|
||||
}
|
||||
|
||||
inline void mutex_unsafe_lock(mutex_handle &handle) {
|
||||
@@ -119,7 +120,7 @@ inline void lazy_mutex_unlock(lazy_mutex_handle &handle) {
|
||||
SWIFT_PTHREADS_CHECK(::pthread_mutex_unlock(&handle));
|
||||
}
|
||||
inline bool lazy_mutex_try_lock(lazy_mutex_handle &handle) {
|
||||
SWIFT_PTHREADS_RETURN_TRUE_OR_FALSE(::pthread_mutex_trylock(&handle));
|
||||
SWIFT_PTHREADS_RETURN_TRUE_OR_FALSE(EBUSY, ::pthread_mutex_trylock(&handle));
|
||||
}
|
||||
|
||||
inline void lazy_mutex_unsafe_lock(lazy_mutex_handle &handle) {
|
||||
@@ -129,6 +130,55 @@ inline void lazy_mutex_unsafe_unlock(lazy_mutex_handle &handle) {
|
||||
(void)::pthread_mutex_unlock(&handle);
|
||||
}
|
||||
|
||||
// .. ConditionVariable support ..............................................
|
||||
|
||||
struct cond_handle {
|
||||
::pthread_cond_t condition;
|
||||
::pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
inline void cond_init(cond_handle &handle) {
|
||||
handle.condition = PTHREAD_COND_INITIALIZER;
|
||||
handle.mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
}
|
||||
inline void cond_destroy(cond_handle &handle) {
|
||||
SWIFT_PTHREADS_CHECK(::pthread_cond_destroy(&handle.condition));
|
||||
SWIFT_PTHREADS_CHECK(::pthread_mutex_destroy(&handle.mutex));
|
||||
}
|
||||
inline void cond_lock(cond_handle &handle) {
|
||||
SWIFT_PTHREADS_CHECK(::pthread_mutex_lock(&handle.mutex));
|
||||
}
|
||||
inline void cond_unlock(cond_handle &handle) {
|
||||
SWIFT_PTHREADS_CHECK(::pthread_mutex_unlock(&handle.mutex));
|
||||
}
|
||||
inline void cond_signal(cond_handle &handle) {
|
||||
SWIFT_PTHREADS_CHECK(::pthread_cond_signal(&handle.condition));
|
||||
}
|
||||
inline void cond_broadcast(cond_handle &handle) {
|
||||
SWIFT_PTHREADS_CHECK(::pthread_cond_broadcast(&handle.condition));
|
||||
}
|
||||
inline void cond_wait(cond_handle &handle) {
|
||||
SWIFT_PTHREADS_CHECK(::pthread_cond_wait(&handle.condition, &handle.mutex));
|
||||
}
|
||||
template <class Rep, class Period>
|
||||
inline bool cond_wait(cond_handle &handle,
|
||||
std::chrono::duration<Rep, Period> duration) {
|
||||
auto deadline = std::chrono::time_point_cast<
|
||||
std::chrono::system_clock::duration>(std::chrono::system_clock::now()
|
||||
+ duration);
|
||||
return cond_wait(handle, deadline);
|
||||
}
|
||||
inline bool cond_wait(cond_handle &handle,
|
||||
std::chrono::system_clock::time_point deadline) {
|
||||
auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
deadline.time_since_epoch()).count();
|
||||
struct ::timespec ts = { ::time_t(ns / 1000000000), long(ns % 1000000000) };
|
||||
SWIFT_PTHREADS_RETURN_TRUE_OR_FALSE(
|
||||
ETIMEDOUT,
|
||||
::pthread_cond_timedwait(&handle.condition, &handle.mutex, &ts)
|
||||
);
|
||||
}
|
||||
|
||||
// .. Once ...................................................................
|
||||
|
||||
using once_t = std::atomic<std::intptr_t>;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "Win32/Win32Defs.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <atomic>
|
||||
|
||||
#include "llvm/ADT/Optional.h"
|
||||
@@ -86,6 +87,54 @@ inline void lazy_mutex_unsafe_unlock(lazy_mutex_handle &handle) {
|
||||
ReleaseSRWLockExclusive(&handle);
|
||||
}
|
||||
|
||||
// .. ConditionVariable support ..............................................
|
||||
|
||||
struct cond_handle {
|
||||
SWIFT_CONDITION_VARIABLE condition;
|
||||
SWIFT_SRWLOCK lock;
|
||||
};
|
||||
|
||||
inline void cond_init(cond_handle &handle) {
|
||||
handle.condition = CONDITION_VARIABLE_INIT;
|
||||
handle.lock = SRWLOCK_INIT;
|
||||
}
|
||||
inline void cond_destroy(cond_handle &handle) {}
|
||||
inline void cond_lock(cond_handle &handle) {
|
||||
AcquireSRWLockExclusive(&handle.lock);
|
||||
}
|
||||
inline void cond_unlock(cond_handle &handle) {
|
||||
ReleaseSRWLockExclusive(&handle.lock);
|
||||
}
|
||||
inline void cond_signal(cond_handle &handle) {
|
||||
WakeConditionVariable(&handle.condition);
|
||||
}
|
||||
inline void cond_broadcast(cond_handle &handle) {
|
||||
WakeAllConditionVariable(&handle.condition);
|
||||
}
|
||||
inline void cond_wait(cond_handle &handle) {
|
||||
SleepConditionVariableSRW(&handle.condition,
|
||||
&handle.lock,
|
||||
INFINITE,
|
||||
0);
|
||||
}
|
||||
template <class Rep, class Period>
|
||||
inline bool cond_wait(cond_handle &handle,
|
||||
std::chrono::duration<Rep, Period> duration) {
|
||||
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(duration);
|
||||
return SleepConditionVariableSRW(&handle.condition,
|
||||
&handle.lock,
|
||||
DWORD(ms.count()),
|
||||
0);
|
||||
}
|
||||
inline bool cond_wait(cond_handle &handle,
|
||||
std::chrono::system_clock::time_point deadline) {
|
||||
std::chrono::system_clock::duration duration =
|
||||
deadline - std::chrono::system_clock::now();
|
||||
if (duration < std::chrono::system_clock::duration::zero())
|
||||
duration = std::chrono::system_clock::duration::zero();
|
||||
return cond_wait(handle, duration);
|
||||
}
|
||||
|
||||
// .. Once ...................................................................
|
||||
|
||||
typedef std::atomic<intptr_t> once_t;
|
||||
|
||||
@@ -36,18 +36,30 @@ typedef unsigned char BYTE;
|
||||
typedef BYTE BOOLEAN;
|
||||
typedef int BOOL;
|
||||
typedef unsigned long DWORD;
|
||||
typedef unsigned long ULONG;
|
||||
|
||||
typedef VOID(NTAPI *PFLS_CALLBACK_FUNCTION)(PVOID lpFlsData);
|
||||
|
||||
typedef struct _RTL_SRWLOCK *PRTL_SRWLOCK;
|
||||
typedef PRTL_SRWLOCK PSRWLOCK;
|
||||
|
||||
typedef struct _RTL_CONDITION_VARIABLE *PRTL_CONDITION_VARIABLE;
|
||||
typedef PRTL_CONDITION_VARIABLE PCONDITION_VARIABLE;
|
||||
|
||||
// These have to be #defines, to avoid problems with <windows.h>
|
||||
#define RTL_SRWLOCK_INIT \
|
||||
{ 0 }
|
||||
#define SRWLOCK_INIT RTL_SRWLOCK_INIT
|
||||
#define FLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF)
|
||||
|
||||
#define RTL_CONDITION_VARIABLE_INIT {0}
|
||||
#define CONDITION_VARIABLE_INIT RTL_CONDITION_VARIABLE_INIT
|
||||
|
||||
#define RTL_CONDITION_VARIABLE_LOCKMODE_SHARED 0x1
|
||||
#define CONDITION_VARIABLE_LOCKMODE_SHARED RTL_CONDITION_VARIABLE_LOCKMODE_SHARED
|
||||
|
||||
#define INFINITE 0xFFFFFFFF // Infinite timeout
|
||||
|
||||
extern "C" {
|
||||
WINBASEAPI DWORD WINAPI GetCurrentThreadId(VOID);
|
||||
|
||||
@@ -56,6 +68,22 @@ WINBASEAPI VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK SRWLock);
|
||||
WINBASEAPI VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK SRWLock);
|
||||
WINBASEAPI BOOLEAN WINAPI TryAcquireSRWLockExclusive(PSRWLOCK SRWLock);
|
||||
|
||||
WINBASEAPI VOID WINAPI InitializeConditionVariable(
|
||||
PCONDITION_VARIABLE ConditionVariable
|
||||
);
|
||||
WINBASEAPI VOID WINAPI WakeConditionVariable(
|
||||
PCONDITION_VARIABLE ConditionVariable
|
||||
);
|
||||
WINBASEAPI VOID WINAPI WakeAllConditionVariable(
|
||||
PCONDITION_VARIABLE ConditionVariable
|
||||
);
|
||||
WINBASEAPI BOOL WINAPI SleepConditionVariableSRW(
|
||||
PCONDITION_VARIABLE ConditionVariable,
|
||||
PSRWLOCK SRWLock,
|
||||
DWORD dwMilliseconds,
|
||||
ULONG Flags
|
||||
);
|
||||
|
||||
WINBASEAPI DWORD WINAPI FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback);
|
||||
WINBASEAPI PVOID WINAPI FlsGetValue(DWORD dwFlsIndex);
|
||||
WINBASEAPI BOOL WINAPI FlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData);
|
||||
@@ -86,6 +114,33 @@ inline BOOLEAN TryAcquireSRWLockExclusive(PSWIFT_SRWLOCK SRWLock) {
|
||||
return ::TryAcquireSRWLockExclusive(reinterpret_cast<PSRWLOCK>(SRWLock));
|
||||
}
|
||||
|
||||
// Similarly we have the same problem with _RTL_CONDITION_VARIABLE
|
||||
struct SWIFT_CONDITION_VARIABLE {
|
||||
PVOID Ptr;
|
||||
};
|
||||
|
||||
typedef SWIFT_CONDITION_VARIABLE *PSWIFT_CONDITION_VARIABLE;
|
||||
|
||||
inline VOID InitializeConditionVariable(PSWIFT_CONDITION_VARIABLE CondVar) {
|
||||
::InitializeConditionVariable(reinterpret_cast<PCONDITION_VARIABLE>(CondVar));
|
||||
}
|
||||
inline VOID WakeConditionVariable(PSWIFT_CONDITION_VARIABLE CondVar) {
|
||||
::WakeConditionVariable(reinterpret_cast<PCONDITION_VARIABLE>(CondVar));
|
||||
}
|
||||
inline VOID WakeAllConditionVariable(PSWIFT_CONDITION_VARIABLE CondVar) {
|
||||
::WakeAllConditionVariable(reinterpret_cast<PCONDITION_VARIABLE>(CondVar));
|
||||
}
|
||||
inline BOOL SleepConditionVariableSRW(PSWIFT_CONDITION_VARIABLE CondVar,
|
||||
PSWIFT_SRWLOCK SRWLock,
|
||||
DWORD dwMilliseconds,
|
||||
ULONG Flags) {
|
||||
return ::SleepConditionVariableSRW(
|
||||
reinterpret_cast<PCONDITION_VARIABLE>(CondVar),
|
||||
reinterpret_cast<PSRWLOCK>(SRWLock),
|
||||
dwMilliseconds,
|
||||
Flags);
|
||||
}
|
||||
|
||||
} // namespace threading_impl
|
||||
} // namespace swift
|
||||
|
||||
|
||||
Reference in New Issue
Block a user