|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef _GLTHREAD_COND_H |
|
|
#define _GLTHREAD_COND_H |
|
|
|
|
|
|
|
|
#if !_GL_CONFIG_H_INCLUDED |
|
|
#error "Please include config.h first." |
|
|
#endif |
|
|
|
|
|
#include <errno.h> |
|
|
#include <stdlib.h> |
|
|
#include <time.h> |
|
|
|
|
|
#include "glthread/lock.h" |
|
|
|
|
|
#if !defined c11_threads_in_use |
|
|
# if HAVE_THREADS_H && USE_POSIX_THREADS_FROM_LIBC |
|
|
# define c11_threads_in_use() 1 |
|
|
# elif HAVE_THREADS_H && USE_POSIX_THREADS_WEAK |
|
|
# include <threads.h> |
|
|
# pragma weak thrd_exit |
|
|
# define c11_threads_in_use() (thrd_exit != NULL) |
|
|
# else |
|
|
# define c11_threads_in_use() 0 |
|
|
# endif |
|
|
#endif |
|
|
|
|
|
_GL_INLINE_HEADER_BEGIN |
|
|
#ifndef _GLTHREAD_COND_INLINE |
|
|
# define _GLTHREAD_COND_INLINE _GL_INLINE |
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#if USE_ISOC_THREADS || USE_ISOC_AND_POSIX_THREADS |
|
|
|
|
|
|
|
|
|
|
|
# include <threads.h> |
|
|
|
|
|
# ifdef __cplusplus |
|
|
extern "C" { |
|
|
# endif |
|
|
|
|
|
|
|
|
|
|
|
typedef struct |
|
|
{ |
|
|
int volatile init_needed; |
|
|
once_flag init_once; |
|
|
void (*init_func) (void); |
|
|
cnd_t condition; |
|
|
} |
|
|
gl_cond_t; |
|
|
# define gl_cond_define(STORAGECLASS, NAME) \ |
|
|
STORAGECLASS gl_cond_t NAME; |
|
|
# define gl_cond_define_initialized(STORAGECLASS, NAME) \ |
|
|
static void _atomic_init_##NAME (void); \ |
|
|
STORAGECLASS gl_cond_t NAME = \ |
|
|
{ 1, ONCE_FLAG_INIT, _atomic_init_##NAME }; \ |
|
|
static void _atomic_init_##NAME (void) \ |
|
|
{ \ |
|
|
if (glthread_cond_init (&(NAME))) \ |
|
|
abort (); \ |
|
|
} |
|
|
extern int glthread_cond_init (gl_cond_t *condition); |
|
|
extern int glthread_cond_wait (gl_cond_t *condition, gl_lock_t *lock); |
|
|
extern int glthread_cond_timedwait (gl_cond_t *condition, gl_lock_t *lock, |
|
|
const struct timespec *abstime); |
|
|
extern int glthread_cond_signal (gl_cond_t *condition); |
|
|
extern int glthread_cond_broadcast (gl_cond_t *condition); |
|
|
extern int glthread_cond_destroy (gl_cond_t *condition); |
|
|
|
|
|
# ifdef __cplusplus |
|
|
} |
|
|
# endif |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#if USE_POSIX_THREADS |
|
|
|
|
|
|
|
|
|
|
|
# include <pthread.h> |
|
|
|
|
|
# ifdef __cplusplus |
|
|
extern "C" { |
|
|
# endif |
|
|
|
|
|
# if PTHREAD_IN_USE_DETECTION_HARD |
|
|
|
|
|
|
|
|
# define pthread_in_use() \ |
|
|
glthread_in_use () |
|
|
extern int glthread_in_use (void); |
|
|
|
|
|
# endif |
|
|
|
|
|
# if USE_POSIX_THREADS_WEAK |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# pragma weak pthread_cond_init |
|
|
# pragma weak pthread_cond_wait |
|
|
# pragma weak pthread_cond_timedwait |
|
|
# pragma weak pthread_cond_signal |
|
|
# pragma weak pthread_cond_broadcast |
|
|
# pragma weak pthread_cond_destroy |
|
|
# ifndef pthread_self |
|
|
# pragma weak pthread_self |
|
|
# endif |
|
|
|
|
|
# if !PTHREAD_IN_USE_DETECTION_HARD |
|
|
# pragma weak pthread_mutexattr_gettype |
|
|
# define pthread_in_use() \ |
|
|
(pthread_mutexattr_gettype != NULL || c11_threads_in_use ()) |
|
|
# endif |
|
|
|
|
|
# else |
|
|
|
|
|
# if !PTHREAD_IN_USE_DETECTION_HARD |
|
|
# define pthread_in_use() 1 |
|
|
# endif |
|
|
|
|
|
# endif |
|
|
|
|
|
|
|
|
|
|
|
typedef pthread_cond_t gl_cond_t; |
|
|
# define gl_cond_define(STORAGECLASS, NAME) \ |
|
|
STORAGECLASS gl_cond_t NAME; |
|
|
# define gl_cond_define_initialized(STORAGECLASS, NAME) \ |
|
|
STORAGECLASS gl_cond_t NAME = gl_cond_initializer; |
|
|
# define gl_cond_initializer \ |
|
|
PTHREAD_COND_INITIALIZER |
|
|
# define glthread_cond_init(COND) \ |
|
|
(pthread_in_use () ? pthread_cond_init (COND, NULL) : 0) |
|
|
# define glthread_cond_wait(COND, LOCK) \ |
|
|
(pthread_in_use () ? pthread_cond_wait (COND, LOCK) : 0) |
|
|
# define glthread_cond_timedwait(COND, LOCK, ABSTIME) \ |
|
|
(pthread_in_use () ? pthread_cond_timedwait (COND, LOCK, ABSTIME) : 0) |
|
|
# define glthread_cond_signal(COND) \ |
|
|
(pthread_in_use () ? pthread_cond_signal (COND) : 0) |
|
|
# define glthread_cond_broadcast(COND) \ |
|
|
(pthread_in_use () ? pthread_cond_broadcast (COND) : 0) |
|
|
# define glthread_cond_destroy(COND) \ |
|
|
(pthread_in_use () ? pthread_cond_destroy (COND) : 0) |
|
|
|
|
|
# ifdef __cplusplus |
|
|
} |
|
|
# endif |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#if USE_WINDOWS_THREADS |
|
|
|
|
|
# define WIN32_LEAN_AND_MEAN |
|
|
# include <windows.h> |
|
|
|
|
|
# include "windows-cond.h" |
|
|
|
|
|
# ifdef __cplusplus |
|
|
extern "C" { |
|
|
# endif |
|
|
|
|
|
|
|
|
|
|
|
typedef glwthread_cond_t gl_cond_t; |
|
|
# define gl_cond_define(STORAGECLASS, NAME) \ |
|
|
STORAGECLASS gl_cond_t NAME; |
|
|
# define gl_cond_define_initialized(STORAGECLASS, NAME) \ |
|
|
STORAGECLASS gl_cond_t NAME = gl_cond_initializer; |
|
|
# define gl_cond_initializer \ |
|
|
GLWTHREAD_COND_INIT |
|
|
# define glthread_cond_init(COND) \ |
|
|
glwthread_cond_init (COND) |
|
|
# define glthread_cond_wait(COND, LOCK) \ |
|
|
glwthread_cond_wait (COND, LOCK, \ |
|
|
(int (*) (void *)) glwthread_mutex_lock, \ |
|
|
(int (*) (void *)) glwthread_mutex_unlock) |
|
|
# define glthread_cond_timedwait(COND, LOCK, ABSTIME) \ |
|
|
glwthread_cond_timedwait (COND, LOCK, \ |
|
|
(int (*) (void *)) glwthread_mutex_lock, \ |
|
|
(int (*) (void *)) glwthread_mutex_unlock, \ |
|
|
ABSTIME) |
|
|
# define glthread_cond_signal(COND) \ |
|
|
glwthread_cond_signal (COND) |
|
|
# define glthread_cond_broadcast(COND) \ |
|
|
glwthread_cond_broadcast (COND) |
|
|
# define glthread_cond_destroy(COND) \ |
|
|
glwthread_cond_destroy (COND) |
|
|
|
|
|
# ifdef __cplusplus |
|
|
} |
|
|
# endif |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#if !(USE_ISOC_THREADS || USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS || USE_WINDOWS_THREADS) |
|
|
|
|
|
|
|
|
|
|
|
typedef int gl_cond_t; |
|
|
# define gl_cond_define(STORAGECLASS, NAME) |
|
|
# define gl_cond_define_initialized(STORAGECLASS, NAME) |
|
|
# define glthread_cond_init(COND) 0 |
|
|
# define glthread_cond_wait(COND, LOCK) 0 |
|
|
# define glthread_cond_timedwait(COND, LOCK, ABSTIME) 0 |
|
|
# define glthread_cond_signal(COND) 0 |
|
|
# define glthread_cond_broadcast(COND) 0 |
|
|
# define glthread_cond_destroy(COND) 0 |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus |
|
|
extern "C" { |
|
|
#endif |
|
|
|
|
|
#define gl_cond_init(COND) \ |
|
|
do \ |
|
|
{ \ |
|
|
if (glthread_cond_init (&COND)) \ |
|
|
abort (); \ |
|
|
} \ |
|
|
while (0) |
|
|
#define gl_cond_wait(COND, LOCK) \ |
|
|
do \ |
|
|
{ \ |
|
|
if (glthread_cond_wait (&COND, &LOCK)) \ |
|
|
abort (); \ |
|
|
} \ |
|
|
while (0) |
|
|
#define gl_cond_timedwait(COND, LOCK, ABSTIME) \ |
|
|
gl_cond_timedwait_func (&COND, &LOCK, ABSTIME) |
|
|
_GLTHREAD_COND_INLINE bool |
|
|
gl_cond_timedwait_func (gl_cond_t *cond, gl_lock_t *lock, struct timespec *abstime) |
|
|
{ |
|
|
int err = glthread_cond_timedwait (cond, lock, abstime); |
|
|
if (err == ETIMEDOUT) |
|
|
return true; |
|
|
if (err != 0) |
|
|
abort (); |
|
|
return false; |
|
|
} |
|
|
#define gl_cond_signal(COND) \ |
|
|
do \ |
|
|
{ \ |
|
|
if (glthread_cond_signal (&COND)) \ |
|
|
abort (); \ |
|
|
} \ |
|
|
while (0) |
|
|
#define gl_cond_broadcast(COND) \ |
|
|
do \ |
|
|
{ \ |
|
|
if (glthread_cond_broadcast (&COND)) \ |
|
|
abort (); \ |
|
|
} \ |
|
|
while (0) |
|
|
#define gl_cond_destroy(COND) \ |
|
|
do \ |
|
|
{ \ |
|
|
if (glthread_cond_destroy (&COND)) \ |
|
|
abort (); \ |
|
|
} \ |
|
|
while (0) |
|
|
|
|
|
#ifdef __cplusplus |
|
|
} |
|
|
#endif |
|
|
|
|
|
_GL_INLINE_HEADER_END |
|
|
|
|
|
#endif |
|
|
|