mirror of
https://github.com/glfw/glfw.git
synced 2024-11-29 21:37:27 +00:00
Updated TinyCThread.
This commit is contained in:
parent
b4d0223faa
commit
a49c61f1a7
@ -21,13 +21,6 @@ freely, subject to the following restrictions:
|
|||||||
distribution.
|
distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Activate some POSIX functionality (e.g. recursive mutexes) */
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#if !defined(_XOPEN_SOURCE) || (_XOPEN_SOURCE < 500)
|
|
||||||
#undef _XOPEN_SOURCE
|
|
||||||
#define _XOPEN_SOURCE 500
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "tinycthread.h"
|
#include "tinycthread.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@ -99,9 +92,11 @@ int mtx_lock(mtx_t *mtx)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int mtx_timedlock(mtx_t *mtx, const xtime *xt)
|
int mtx_timedlock(mtx_t *mtx, const struct timespec *ts)
|
||||||
{
|
{
|
||||||
/* FIXME! */
|
/* FIXME! */
|
||||||
|
(void)mtx;
|
||||||
|
(void)ts;
|
||||||
return thrd_error;
|
return thrd_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,21 +285,21 @@ int cnd_wait(cnd_t *cond, mtx_t *mtx)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const xtime *xt)
|
int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts)
|
||||||
{
|
{
|
||||||
#if defined(_TTHREAD_WIN32_)
|
#if defined(_TTHREAD_WIN32_)
|
||||||
xtime now;
|
struct timespec now;
|
||||||
DWORD delta;
|
if (clock_gettime(TIME_UTC, &now) == 0)
|
||||||
xtime_get(&now, TIME_UTC);
|
{
|
||||||
delta = (xt->sec - now.sec) * 1000 +
|
DWORD delta = (ts->tv_sec - now.tv_sec) * 1000 +
|
||||||
(xt->nsec - now.nsec + 500000) / 1000000;
|
(ts->tv_nsec - now.tv_nsec + 500000) / 1000000;
|
||||||
return _cnd_timedwait_win32(cond, mtx, delta);
|
return _cnd_timedwait_win32(cond, mtx, delta);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return thrd_error;
|
||||||
#else
|
#else
|
||||||
struct timespec ts;
|
|
||||||
int ret;
|
int ret;
|
||||||
ts.tv_sec = xt->sec;
|
ret = pthread_cond_timedwait(cond, mtx, ts);
|
||||||
ts.tv_nsec = xt->nsec;
|
|
||||||
ret = pthread_cond_timedwait(cond, mtx, &ts);
|
|
||||||
if (ret == ETIMEDOUT)
|
if (ret == ETIMEDOUT)
|
||||||
{
|
{
|
||||||
return thrd_timeout;
|
return thrd_timeout;
|
||||||
@ -322,9 +317,9 @@ typedef struct {
|
|||||||
|
|
||||||
/* Thread wrapper function. */
|
/* Thread wrapper function. */
|
||||||
#if defined(_TTHREAD_WIN32_)
|
#if defined(_TTHREAD_WIN32_)
|
||||||
unsigned WINAPI _thrd_wrapper_function(void * aArg)
|
static unsigned WINAPI _thrd_wrapper_function(void * aArg)
|
||||||
#elif defined(_TTHREAD_POSIX_)
|
#elif defined(_TTHREAD_POSIX_)
|
||||||
void * _thrd_wrapper_function(void * aArg)
|
static void * _thrd_wrapper_function(void * aArg)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
thrd_start_t fun;
|
thrd_start_t fun;
|
||||||
@ -401,6 +396,7 @@ thrd_t thrd_current(void)
|
|||||||
int thrd_detach(thrd_t thr)
|
int thrd_detach(thrd_t thr)
|
||||||
{
|
{
|
||||||
/* FIXME! */
|
/* FIXME! */
|
||||||
|
(void)thr;
|
||||||
return thrd_error;
|
return thrd_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,9 +456,9 @@ int thrd_join(thrd_t thr, int *res)
|
|||||||
return thrd_success;
|
return thrd_success;
|
||||||
}
|
}
|
||||||
|
|
||||||
void thrd_sleep(const xtime *xt)
|
int thrd_sleep(const struct timespec *time_point, struct timespec *remaining)
|
||||||
{
|
{
|
||||||
xtime now;
|
struct timespec now;
|
||||||
#if defined(_TTHREAD_WIN32_)
|
#if defined(_TTHREAD_WIN32_)
|
||||||
DWORD delta;
|
DWORD delta;
|
||||||
#else
|
#else
|
||||||
@ -470,20 +466,21 @@ void thrd_sleep(const xtime *xt)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Get the current time */
|
/* Get the current time */
|
||||||
xtime_get(&now, TIME_UTC);
|
if (clock_gettime(TIME_UTC, &now) != 0)
|
||||||
|
return -2; // FIXME: Some specific error code?
|
||||||
|
|
||||||
#if defined(_TTHREAD_WIN32_)
|
#if defined(_TTHREAD_WIN32_)
|
||||||
/* Delta in milliseconds */
|
/* Delta in milliseconds */
|
||||||
delta = (xt->sec - now.sec) * 1000 +
|
delta = (time_point->tv_sec - now.tv_sec) * 1000 +
|
||||||
(xt->nsec - now.nsec + 500000) / 1000000;
|
(time_point->tv_nsec - now.tv_nsec + 500000) / 1000000;
|
||||||
if (delta > 0)
|
if (delta > 0)
|
||||||
{
|
{
|
||||||
Sleep(delta);
|
Sleep(delta);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* Delta in microseconds */
|
/* Delta in microseconds */
|
||||||
delta = (xt->sec - now.sec) * 1000000L +
|
delta = (time_point->tv_sec - now.tv_sec) * 1000000L +
|
||||||
(xt->nsec - now.nsec + 500L) / 1000L;
|
(time_point->tv_nsec - now.tv_nsec + 500L) / 1000L;
|
||||||
|
|
||||||
/* On some systems, the usleep argument must be < 1000000 */
|
/* On some systems, the usleep argument must be < 1000000 */
|
||||||
while (delta > 999999L)
|
while (delta > 999999L)
|
||||||
@ -496,6 +493,14 @@ void thrd_sleep(const xtime *xt)
|
|||||||
usleep((useconds_t)delta);
|
usleep((useconds_t)delta);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* We don't support waking up prematurely (yet) */
|
||||||
|
if (remaining)
|
||||||
|
{
|
||||||
|
remaining->tv_sec = 0;
|
||||||
|
remaining->tv_nsec = 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void thrd_yield(void)
|
void thrd_yield(void)
|
||||||
@ -563,26 +568,21 @@ int tss_set(tss_t key, void *val)
|
|||||||
return thrd_success;
|
return thrd_success;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xtime_get(xtime *xt, int base)
|
#if defined(_TTHREAD_EMULATE_CLOCK_GETTIME_)
|
||||||
|
int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts)
|
||||||
{
|
{
|
||||||
if (base == TIME_UTC)
|
|
||||||
{
|
|
||||||
#if defined(_TTHREAD_WIN32_)
|
#if defined(_TTHREAD_WIN32_)
|
||||||
struct _timeb tb;
|
struct _timeb tb;
|
||||||
_ftime(&tb);
|
_ftime(&tb);
|
||||||
xt->sec = (time_t)tb.time;
|
ts->tv_sec = (time_t)tb.time;
|
||||||
xt->nsec = 1000000 * (long)tb.millitm;
|
ts->tv_nsec = 1000000L * (long)tb.millitm;
|
||||||
#else
|
#else
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
xt->sec = (time_t)tv.tv_sec;
|
ts->tv_sec = (time_t)tv.tv_sec;
|
||||||
xt->nsec = 1000 * (long)tv.tv_usec;
|
ts->tv_nsec = 1000L * (long)tv.tv_usec;
|
||||||
#endif
|
#endif
|
||||||
return base;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif // _TTHREAD_EMULATE_CLOCK_GETTIME_
|
||||||
|
|
||||||
|
@ -57,6 +57,22 @@ freely, subject to the following restrictions:
|
|||||||
#define _TTHREAD_PLATFORM_DEFINED_
|
#define _TTHREAD_PLATFORM_DEFINED_
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Activate some POSIX functionality (e.g. clock_gettime and recursive mutexes) */
|
||||||
|
#if defined(_TTHREAD_POSIX_)
|
||||||
|
#undef _FEATURES_H
|
||||||
|
#if !defined(_GNU_SOURCE)
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#endif
|
||||||
|
#if !defined(_POSIX_C_SOURCE) || ((_POSIX_C_SOURCE - 0) < 199309L)
|
||||||
|
#undef _POSIX_C_SOURCE
|
||||||
|
#define _POSIX_C_SOURCE 199309L
|
||||||
|
#endif
|
||||||
|
#if !defined(_XOPEN_SOURCE) || ((_XOPEN_SOURCE - 0) < 500)
|
||||||
|
#undef _XOPEN_SOURCE
|
||||||
|
#define _XOPEN_SOURCE 500
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Generic includes */
|
/* Generic includes */
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
@ -75,10 +91,42 @@ freely, subject to the following restrictions:
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Workaround for missing TIME_UTC: If time.h doesn't provide TIME_UTC,
|
||||||
|
it's quite likely that libc does not support it either. Hence, fall back to
|
||||||
|
the only other supported time specifier: CLOCK_REALTIME (and if that fails,
|
||||||
|
we're probably emulating clock_gettime anyway, so anything goes). */
|
||||||
|
#ifndef TIME_UTC
|
||||||
|
#ifdef CLOCK_REALTIME
|
||||||
|
#define TIME_UTC CLOCK_REALTIME
|
||||||
|
#else
|
||||||
|
#define TIME_UTC 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Workaround for missing clock_gettime (most Windows compilers, afaik) */
|
||||||
|
#if defined(_TTHREAD_WIN32_)
|
||||||
|
#define _TTHREAD_EMULATE_CLOCK_GETTIME_
|
||||||
|
/* Emulate struct timespec */
|
||||||
|
struct _ttherad_timespec {
|
||||||
|
time_t tv_sec;
|
||||||
|
long tv_nsec;
|
||||||
|
};
|
||||||
|
#define timespec _ttherad_timespec
|
||||||
|
|
||||||
|
/* Emulate clockid_t */
|
||||||
|
typedef int _tthread_clockid_t;
|
||||||
|
#define clockid_t _tthread_clockid_t
|
||||||
|
|
||||||
|
/* Emulate clock_gettime */
|
||||||
|
int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts);
|
||||||
|
#define clock_gettime _tthread_clock_gettime
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/** TinyCThread version (major number). */
|
/** TinyCThread version (major number). */
|
||||||
#define TINYCTHREAD_VERSION_MAJOR 1
|
#define TINYCTHREAD_VERSION_MAJOR 1
|
||||||
/** TinyCThread version (minor number). */
|
/** TinyCThread version (minor number). */
|
||||||
#define TINYCTHREAD_VERSION_MINOR 0
|
#define TINYCTHREAD_VERSION_MINOR 1
|
||||||
/** TinyCThread version (full version). */
|
/** TinyCThread version (full version). */
|
||||||
#define TINYCTHREAD_VERSION (TINYCTHREAD_VERSION_MAJOR * 100 + TINYCTHREAD_VERSION_MINOR)
|
#define TINYCTHREAD_VERSION (TINYCTHREAD_VERSION_MAJOR * 100 + TINYCTHREAD_VERSION_MINOR)
|
||||||
|
|
||||||
@ -101,7 +149,7 @@ freely, subject to the following restrictions:
|
|||||||
* @hideinitializer
|
* @hideinitializer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* FIXME: Check for a PROPER value of __STDC_VERSION__ to know if we have C11 or */
|
/* FIXME: Check for a PROPER value of __STDC_VERSION__ to know if we have C11 */
|
||||||
#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201102L)) && !defined(_Thread_local)
|
#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201102L)) && !defined(_Thread_local)
|
||||||
#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
|
#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
|
||||||
#define _Thread_local __thread
|
#define _Thread_local __thread
|
||||||
@ -126,12 +174,6 @@ freely, subject to the following restrictions:
|
|||||||
#define mtx_try 4
|
#define mtx_try 4
|
||||||
#define mtx_recursive 8
|
#define mtx_recursive 8
|
||||||
|
|
||||||
/** Time specification */
|
|
||||||
typedef struct {
|
|
||||||
time_t sec; /**< Seconds */
|
|
||||||
long nsec; /**< Nanoseconds */
|
|
||||||
} xtime;
|
|
||||||
|
|
||||||
/* Mutex */
|
/* Mutex */
|
||||||
#if defined(_TTHREAD_WIN32_)
|
#if defined(_TTHREAD_WIN32_)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -174,7 +216,7 @@ int mtx_lock(mtx_t *mtx);
|
|||||||
|
|
||||||
/** NOT YET IMPLEMENTED.
|
/** NOT YET IMPLEMENTED.
|
||||||
*/
|
*/
|
||||||
int mtx_timedlock(mtx_t *mtx, const xtime *xt);
|
int mtx_timedlock(mtx_t *mtx, const struct timespec *ts);
|
||||||
|
|
||||||
/** Try to lock the given mutex.
|
/** Try to lock the given mutex.
|
||||||
* The specified mutex shall support either test and return or timeout. If the
|
* The specified mutex shall support either test and return or timeout. If the
|
||||||
@ -260,7 +302,7 @@ int cnd_wait(cnd_t *cond, mtx_t *mtx);
|
|||||||
* specified in the call was reached without acquiring the requested resource, or
|
* specified in the call was reached without acquiring the requested resource, or
|
||||||
* @ref thrd_error if the request could not be honored.
|
* @ref thrd_error if the request could not be honored.
|
||||||
*/
|
*/
|
||||||
int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const xtime *xt);
|
int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts);
|
||||||
|
|
||||||
/* Thread */
|
/* Thread */
|
||||||
#if defined(_TTHREAD_WIN32_)
|
#if defined(_TTHREAD_WIN32_)
|
||||||
@ -326,11 +368,16 @@ void thrd_exit(int res);
|
|||||||
int thrd_join(thrd_t thr, int *res);
|
int thrd_join(thrd_t thr, int *res);
|
||||||
|
|
||||||
/** Put the calling thread to sleep.
|
/** Put the calling thread to sleep.
|
||||||
* Suspend execution of the calling thread until after the time specified by the
|
* Suspend execution of the calling thread.
|
||||||
* xtime object.
|
* @param time_point A point in time at which the thread will resume (absolute time).
|
||||||
* @param xt A point in time at which the thread will resume (absolute time).
|
* @param remaining If non-NULL, this parameter will hold the remaining time until
|
||||||
|
* time_point upon return. This will typically be zero, but if
|
||||||
|
* the thread was woken up by a signal that is not ignored before
|
||||||
|
* time_point was reached @c remaining will hold a positive
|
||||||
|
* time.
|
||||||
|
* @return 0 (zero) on successful sleep, or -1 if an interrupt occurred.
|
||||||
*/
|
*/
|
||||||
void thrd_sleep(const xtime *xt);
|
int thrd_sleep(const struct timespec *time_point, struct timespec *remaining);
|
||||||
|
|
||||||
/** Yield execution to another thread.
|
/** Yield execution to another thread.
|
||||||
* Permit other threads to run, even if the current thread would ordinarily
|
* Permit other threads to run, even if the current thread would ordinarily
|
||||||
@ -385,20 +432,6 @@ void *tss_get(tss_t key);
|
|||||||
*/
|
*/
|
||||||
int tss_set(tss_t key, void *val);
|
int tss_set(tss_t key, void *val);
|
||||||
|
|
||||||
/* Timing */
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
TIME_UTC = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Get the current time.
|
|
||||||
* Set the xtime object to hold the current time based on the given time base.
|
|
||||||
* @param xt Will be filled out with the current time.
|
|
||||||
* @param base Time base (must be @c TIME_UTC).
|
|
||||||
* @return The non-zero value @c base if the function is successful, otherwise
|
|
||||||
* it returns zero.
|
|
||||||
*/
|
|
||||||
int xtime_get(xtime *xt, int base);
|
|
||||||
|
|
||||||
#endif /* _TINYTHREAD_H_ */
|
#endif /* _TINYTHREAD_H_ */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user