Lely core libraries
2.2.5
|
Go to the documentation of this file.
26 #if !LELY_NO_THREADS && _WIN32 && !LELY_HAVE_PTHREAD_H
38 struct once_info *next;
48 static volatile LONG once_lock;
54 static struct once_info *once_list;
60 static struct once_info once_fast;
95 static thread_local
struct thrd_info *thrd_self;
101 static void thrd_start(
void *arglist);
110 if (InterlockedCompareExchange(flag, 0, 0))
113 struct once_info *info;
114 struct once_info **pinfo;
117 while (InterlockedCompareExchange(&once_lock, 1, 0))
122 for (pinfo = &once_list; *pinfo && (*pinfo)->flag != flag;
123 pinfo = &(*pinfo)->next)
130 info = malloc(
sizeof(*info));
143 InterlockedExchange(&once_lock, 0);
147 if (!InterlockedCompareExchange(info->flag, 0, 0)) {
149 InterlockedExchange(info->flag, 1);
153 while (InterlockedCompareExchange(&once_lock, 1, 0))
158 for (pinfo = &once_list; (*pinfo)->flag != flag;
159 pinfo = &(*pinfo)->next)
166 if (info == &once_fast)
172 InterlockedExchange(&once_lock, 0);
178 WakeAllConditionVariable(cond);
192 InitializeConditionVariable(cond);
200 WakeConditionVariable(cond);
208 struct timespec now = { 0, 0 };
213 LONGLONG llMilliseconds =
214 (LONGLONG)(ts->tv_sec - now.tv_sec) * 1000
215 + (ts->tv_nsec - now.tv_nsec + 999999l)
217 if (llMilliseconds < 0)
219 DWORD dwMilliseconds = llMilliseconds <= MAX_SLEEP_MS
220 ? (DWORD)llMilliseconds
222 DWORD dwResult = SleepConditionVariableCS(
223 cond, mtx, dwMilliseconds);
226 if (GetLastError() != ERROR_TIMEOUT)
230 }
while (now.tv_sec < ts->tv_sec || (now.tv_sec == ts->tv_sec
231 && now.tv_nsec < ts->tv_nsec));
240 return SleepConditionVariableCS(cond, mtx, INFINITE)
249 DeleteCriticalSection(mtx);
258 InitializeCriticalSection(mtx);
266 EnterCriticalSection(mtx);
289 LeaveCriticalSection(mtx);
297 struct thrd_info *info = malloc(
sizeof(*info));
307 info->stat = THRD_STARTED;
309 if (_beginthread(&thrd_start, 0, info) == (uintptr_t)-1) {
330 struct thrd_info *info = (
struct thrd_info *)thr;
333 if (info->stat == THRD_STOPPED) {
340 assert(info->stat != THRD_DETACHED);
341 info->stat = THRD_DETACHED;
357 struct thrd_info *info = (
struct thrd_info *)
thrd_current();
362 if (info->stat == THRD_DETACHED) {
369 assert(info->stat != THRD_STOPPED);
370 info->stat = THRD_STOPPED;
383 struct thrd_info *info = (
struct thrd_info *)thr;
386 while (info->stat == THRD_STARTED) {
390 if (info->stat != THRD_STOPPED) {
407 thrd_sleep(
const struct timespec *duration,
struct timespec *remaining)
410 int res = nanosleep(duration, remaining);
412 res = errno == EINTR ? -1 : -2;
427 DWORD dwFlsIndex = FlsAlloc(dtor);
428 if (dwFlsIndex == FLS_OUT_OF_INDEXES)
445 return FlsGetValue(key);
455 thrd_start(
void *arglist)
459 struct thrd_info *info = (
struct thrd_info *)
thrd_current();
464 #endif // !LELY_NO_THREADS && _WIN32 && !LELY_HAVE_PTHREAD_H
int cnd_signal(cnd_t *cond)
Unblocks one of the threads that are blocked on the condition variable at cond at the time of the cal...
void tss_delete(tss_t key)
Releases any resources used by the thread-specific storage identified by key.
void mtx_destroy(mtx_t *mtx)
Releases any resources used by the mutex at mtx.
int thrd_detach(thrd_t thr)
Tells the operating system to dispose of any resources allocated to the thread identified by thr when...
int mtx_trylock(mtx_t *mtx)
Endeavors to lock the mutex at mtx.
void(* tss_dtor_t)(void *)
The function pointer type used for a destructor for a thread-specific storage pointer.
pthread_t thrd_t
A complete object type that holds an identifier for a thread.
@ thrd_nomem
Indicates that the requested operation failed because it was unable to allocate memory.
int mtx_lock(mtx_t *mtx)
Blocks until it locks the mutex at mtx.
_Noreturn void thrd_exit(int res)
Terminates execution of the calling thread and sets its result code to res.
void * tss_get(tss_t key)
Returns the value for the current thread held in the thread-specific storage identified by key.
@ thrd_error
Indicates that the requested operation failed.
pthread_key_t tss_t
A complete object type that holds an identifier for a thread-specific storage pointer.
pthread_mutex_t mtx_t
A complete object type that holds an identifier for a mutex.
pthread_cond_t cnd_t
A complete object type that holds an identifier for a condition variable.
@ thrd_success
Indicates that the requested operation succeeded.
int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts)
Atomically unlocks the mutex at mtx and endeavors to block until the condition variable at cond is si...
int mtx_unlock(mtx_t *mtx)
Unlocks the mutex at mtx.
#define _Noreturn
A function declared with a _Noreturn function specifier SHALL not return to its caller.
thrd_t thrd_current(void)
Identifies the thread that called it.
pthread_once_t once_flag
A complete object type that holds a flag for use by call_once().
int mtx_timedlock(mtx_t *mtx, const struct timespec *ts)
Endeavors to block until it locks the mutex at mtx or until after the TIME_UTC-based calendar time at...
int cnd_wait(cnd_t *cond, mtx_t *mtx)
Atomically unlocks the mutex at mtx and endeavors to block until the condition variable at cond is si...
int thrd_equal(thrd_t thr0, thrd_t thr1)
Determines whether the thread identified by thr0 refers to the thread identified by thr1.
int thrd_sleep(const struct timespec *duration, struct timespec *remaining)
Suspends execution of the calling thread until either the interval specified by duration has elapsed ...
int thrd_join(thrd_t thr, int *res)
Joins the thread identified by thr with the current thread by blocking until the other thread has ter...
int tss_set(tss_t key, void *val)
Sets the value for the current thread held in the thread-specific storage identified by key to val.
@ thrd_busy
Indicates that the requested operation failed because a resource requested by a test and return funct...
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
Creates a new thread executing func(arg).
void cnd_destroy(cnd_t *cond)
Releases all resources used by the condition variable at cond.
@ thrd_timedout
Indicates that the time specified in the call was reached without acquiring the requested resource.
int cnd_init(cnd_t *cond)
Creates a condition variable.
int timespec_get(struct timespec *ts, int base)
Sets the interval at ts to hold the current calendar time based on the specified time base.
void thrd_yield(void)
Endeavors to permit other threads to run, even if the current thread would ordinarily continue to run...
void call_once(once_flag *flag, void(*func)(void))
Uses the once_flag at flag to ensure that func is called exactly once, the first time the call_once()...
int cnd_broadcast(cnd_t *cond)
Unblocks all of the threads that are blocked on the condition variable at cond at the time of the cal...
int(* thrd_start_t)(void *)
The function pointer type that is passed to thrd_create() to create a new thread.
int tss_create(tss_t *key, tss_dtor_t dtor)
Creates a thread-specific storage pointer with destructor dtor, which may be NULL.
@ mtx_timed
A mutex type that supports timeout (not available with the native Windows API).
int mtx_init(mtx_t *mtx, int type)
Creates a mutex object with properties indicated by type, which must have one of the four values:
@ mtx_plain
A mutex type that supports neither timeout nor test and return.