diff options
author | Nicolai Hähnle <[email protected]> | 2017-10-22 17:38:45 +0200 |
---|---|---|
committer | Nicolai Hähnle <[email protected]> | 2017-11-09 11:57:22 +0100 |
commit | f1a364878431c8c5f4fd38b40b9766449e49f552 (patch) | |
tree | 6ef17660b1942b4b28e1e7001e96334a11eac7b2 /include/c11 | |
parent | c50743f61c533fe8bfed0a432ef74fcf6b4cea24 (diff) |
threads: update for late C11 changes
C11 threads were changed to use struct timespec instead of xtime, and
thrd_sleep got a second argument.
See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1554.htm and
http://en.cppreference.com/w/c/thread/{thrd_sleep,cnd_timedwait,mtx_timedlock}
Note that cnd_timedwait is spec'd to be relative to TIME_UTC / CLOCK_REALTIME.
v2: Fix Windows build errors. Tested with a default Appveyor config
that uses Visual Studio 2013. Judging from Brian's email and
random internet sources, Visual Studio 2015 does have timespec
and timespec_get, hence the _MSC_VER-based guard which I have
not tested.
Cc: Jose Fonseca <[email protected]>
Cc: Brian Paul <[email protected]>
Reviewed-by: Marek Olšák <[email protected]> (v1)
Diffstat (limited to 'include/c11')
-rw-r--r-- | include/c11/threads.h | 11 | ||||
-rw-r--r-- | include/c11/threads_posix.h | 39 | ||||
-rw-r--r-- | include/c11/threads_win32.h | 50 |
3 files changed, 47 insertions, 53 deletions
diff --git a/include/c11/threads.h b/include/c11/threads.h index 573348d8091..3c3f23a8ab8 100644 --- a/include/c11/threads.h +++ b/include/c11/threads.h @@ -30,9 +30,6 @@ #define EMULATED_THREADS_H_INCLUDED_ #include <time.h> -#ifdef _MSC_VER -#include <thr/xtimec.h> // for xtime -#endif #ifndef TIME_UTC #define TIME_UTC 1 @@ -44,14 +41,6 @@ typedef void (*tss_dtor_t)(void*); typedef int (*thrd_start_t)(void*); -#ifndef _MSC_VER -struct xtime { - time_t sec; - long nsec; -}; -typedef struct xtime xtime; -#endif - /*-------------------- enumeration constants --------------------*/ enum { diff --git a/include/c11/threads_posix.h b/include/c11/threads_posix.h index 43e803ee8d1..7bf6a0f6ef6 100644 --- a/include/c11/threads_posix.h +++ b/include/c11/threads_posix.h @@ -132,19 +132,15 @@ cnd_signal(cnd_t *cond) // 7.25.3.5 static inline int -cnd_timedwait(cnd_t *cond, mtx_t *mtx, const xtime *xt) +cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *abs_time) { - struct timespec abs_time; int rt; assert(mtx != NULL); assert(cond != NULL); - assert(xt != NULL); + assert(abs_time != NULL); - abs_time.tv_sec = xt->sec; - abs_time.tv_nsec = xt->nsec; - - rt = pthread_cond_timedwait(cond, mtx, &abs_time); + rt = pthread_cond_timedwait(cond, mtx, abs_time); if (rt == ETIMEDOUT) return thrd_busy; return (rt == 0) ? thrd_success : thrd_error; @@ -235,24 +231,21 @@ thrd_yield(void); // 7.25.4.4 static inline int -mtx_timedlock(mtx_t *mtx, const xtime *xt) +mtx_timedlock(mtx_t *mtx, const struct timespec *ts) { assert(mtx != NULL); - assert(xt != NULL); + assert(ts != NULL); { #ifdef EMULATED_THREADS_USE_NATIVE_TIMEDLOCK - struct timespec ts; int rt; - ts.tv_sec = xt->sec; - ts.tv_nsec = xt->nsec; - rt = pthread_mutex_timedlock(mtx, &ts); + rt = pthread_mutex_timedlock(mtx, ts); if (rt == 0) return thrd_success; return (rt == ETIMEDOUT) ? thrd_busy : thrd_error; #else time_t expire = time(NULL); - expire += xt->sec; + expire += ts->tv_sec; while (mtx_trylock(mtx) != thrd_success) { time_t now = time(NULL); if (expire < now) @@ -342,13 +335,10 @@ thrd_join(thrd_t thr, int *res) // 7.25.5.7 static inline void -thrd_sleep(const xtime *xt) +thrd_sleep(const struct timespec *time_point, struct timespec *remaining) { - struct timespec req; - assert(xt); - req.tv_sec = xt->sec; - req.tv_nsec = xt->nsec; - nanosleep(&req, NULL); + assert(time_point != NULL); + nanosleep(time_point, remaining); } // 7.25.5.8 @@ -392,14 +382,15 @@ tss_set(tss_t key, void *val) /*-------------------- 7.25.7 Time functions --------------------*/ // 7.25.6.1 +#if 0 static inline int -xtime_get(xtime *xt, int base) +timespec_get(struct timespec *ts, int base) { - if (!xt) return 0; + if (!ts) return 0; if (base == TIME_UTC) { - xt->sec = time(NULL); - xt->nsec = 0; + clock_gettime(CLOCK_REALTIME, ts); return base; } return 0; } +#endif diff --git a/include/c11/threads_win32.h b/include/c11/threads_win32.h index af7df4b9ef5..77d923aaf49 100644 --- a/include/c11/threads_win32.h +++ b/include/c11/threads_win32.h @@ -75,6 +75,17 @@ Configuration macro: #error EMULATED_THREADS_USE_NATIVE_CV requires _WIN32_WINNT>=0x0600 #endif +/* Visual Studio 2015 and later */ +#if _MSC_VER >= 1900 +#define HAVE_TIMESPEC +#endif + +#ifndef HAVE_TIMESPEC +struct timespec { + time_t tv_sec; + long tv_nsec; +}; +#endif /*---------------------------- macros ----------------------------*/ #ifdef EMULATED_THREADS_USE_NATIVE_CALL_ONCE @@ -146,9 +157,9 @@ static unsigned __stdcall impl_thrd_routine(void *p) return (unsigned)code; } -static DWORD impl_xtime2msec(const xtime *xt) +static DWORD impl_timespec2msec(const struct timespec *ts) { - return (DWORD)((xt->sec * 1000U) + (xt->nsec / 1000000L)); + return (DWORD)((ts->tv_sec * 1000U) + (ts->tv_nsec / 1000000L)); } #ifdef EMULATED_THREADS_USE_NATIVE_CALL_ONCE @@ -206,7 +217,7 @@ static void impl_cond_do_signal(cnd_t *cond, int broadcast) ReleaseSemaphore(cond->sem_queue, nsignal, NULL); } -static int impl_cond_do_wait(cnd_t *cond, mtx_t *mtx, const xtime *xt) +static int impl_cond_do_wait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts) { int nleft = 0; int ngone = 0; @@ -219,7 +230,7 @@ static int impl_cond_do_wait(cnd_t *cond, mtx_t *mtx, const xtime *xt) mtx_unlock(mtx); - w = WaitForSingleObject(cond->sem_queue, xt ? impl_xtime2msec(xt) : INFINITE); + w = WaitForSingleObject(cond->sem_queue, ts ? impl_timespec2msec(ts) : INFINITE); timeout = (w == WAIT_TIMEOUT); EnterCriticalSection(&cond->monitor); @@ -378,15 +389,15 @@ cnd_signal(cnd_t *cond) // 7.25.3.5 static inline int -cnd_timedwait(cnd_t *cond, mtx_t *mtx, const xtime *xt) +cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *abs_time) { - if (!cond || !mtx || !xt) return thrd_error; + if (!cond || !mtx || !abs_time) return thrd_error; #ifdef EMULATED_THREADS_USE_NATIVE_CV - if (SleepConditionVariableCS(&cond->condvar, mtx, impl_xtime2msec(xt))) + if (SleepConditionVariableCS(&cond->condvar, mtx, impl_timespec2msec(abs_time))) return thrd_success; return (GetLastError() == ERROR_TIMEOUT) ? thrd_busy : thrd_error; #else - return impl_cond_do_wait(cond, mtx, xt); + return impl_cond_do_wait(cond, mtx, abs_time); #endif } @@ -438,12 +449,12 @@ mtx_lock(mtx_t *mtx) // 7.25.4.4 static inline int -mtx_timedlock(mtx_t *mtx, const xtime *xt) +mtx_timedlock(mtx_t *mtx, const struct timespec *ts) { time_t expire, now; - if (!mtx || !xt) return thrd_error; + if (!mtx || !ts) return thrd_error; expire = time(NULL); - expire += xt->sec; + expire += ts->tv_sec; while (mtx_trylock(mtx) != thrd_success) { now = time(NULL); if (expire < now) @@ -579,10 +590,11 @@ thrd_join(thrd_t thr, int *res) // 7.25.5.7 static inline void -thrd_sleep(const xtime *xt) +thrd_sleep(const struct timespec *time_point, struct timespec *remaining) { - assert(xt); - Sleep(impl_xtime2msec(xt)); + assert(time_point); + assert(!remaining); /* not implemented */ + Sleep(impl_timespec2msec(time_point)); } // 7.25.5.8 @@ -633,14 +645,16 @@ tss_set(tss_t key, void *val) /*-------------------- 7.25.7 Time functions --------------------*/ // 7.25.6.1 +#ifndef HAVE_TIMESPEC static inline int -xtime_get(xtime *xt, int base) +timespec_get(struct timespec *ts, int base) { - if (!xt) return 0; + if (!ts) return 0; if (base == TIME_UTC) { - xt->sec = time(NULL); - xt->nsec = 0; + ts->tv_sec = time(NULL); + ts->tv_nsec = 0; return base; } return 0; } +#endif |