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:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user