#error EMULATED_THREADS_USE_NATIVE_CV requires _WIN32_WINNT>=0x0600
#endif
+/* Visual Studio 2015 and later */
+#ifdef _MSC_VER
+#define HAVE_TIMESPEC_GET
+#endif
/*---------------------------- macros ----------------------------*/
#ifdef EMULATED_THREADS_USE_NATIVE_CALL_ONCE
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
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;
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);
// 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
}
// 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)
HANDLE hCurrentThread;
BOOL bRet;
- /* GetCurrentThread() returns a pseudo-handle, which is useless. We need
- * to call DuplicateHandle to get a real handle. However the handle value
- * will not match the one returned by thread_create.
+ /* GetCurrentThread() returns a pseudo-handle, which we need
+ * to pass to DuplicateHandle(). Only the resulting handle can be used
+ * from other threads.
+ *
+ * Note that neither handle can be compared to the one by thread_create.
+ * Only the thread IDs - as returned by GetThreadId() and GetCurrentThreadId()
+ * can be compared directly.
*
* Other potential solutions would be:
* - define thrd_t as a thread Ids, but this would mean we'd need to OpenThread for many operations
// 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
/*-------------------- 7.25.7 Time functions --------------------*/
// 7.25.6.1
+#ifndef HAVE_TIMESPEC_GET
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