summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorNicolai Hähnle <[email protected]>2017-10-22 17:38:45 +0200
committerNicolai Hähnle <[email protected]>2017-11-09 11:57:22 +0100
commitf1a364878431c8c5f4fd38b40b9766449e49f552 (patch)
tree6ef17660b1942b4b28e1e7001e96334a11eac7b2 /include
parentc50743f61c533fe8bfed0a432ef74fcf6b4cea24 (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')
-rw-r--r--include/c11/threads.h11
-rw-r--r--include/c11/threads_posix.h39
-rw-r--r--include/c11/threads_win32.h50
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