191 lines
3.9 KiB
C
191 lines
3.9 KiB
C
#ifndef VLIBC_THREADS_H
|
|
#define VLIBC_THREADS_H
|
|
|
|
/*
|
|
* vlibc — <threads.h>.
|
|
*
|
|
* C11 threads. STUB: the header lands here (level-1 gate) but every
|
|
* function is implemented by the threads todo (#45), which wraps them as
|
|
* thin aliases over the pthread layer. Until then, user code compiles
|
|
* against these declarations and linking resolves once #45 lands.
|
|
*
|
|
* The types are placeholder shapes for now; #45 owns their final form (the
|
|
* pthread-backed layout) and may refine them in place.
|
|
*/
|
|
|
|
#include <vlibc/features.h>
|
|
|
|
#if VLIBC_HAS_HEADER_THREADS_H
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* Forward-declared: the real definition lives in <time.h> (later todo). */
|
|
struct timespec;
|
|
|
|
/* Thread identifier (x86_64: matches pthread_t's unsigned long). */
|
|
typedef unsigned long thrd_t;
|
|
|
|
/* Start routine of a thread. */
|
|
typedef int (*thrd_start_t)(void *);
|
|
|
|
/* Destructor run when a thread exits. */
|
|
typedef void (*tss_dtor_t)(void *);
|
|
|
|
/* Mutex. */
|
|
typedef struct
|
|
{
|
|
unsigned long opaque;
|
|
} mtx_t;
|
|
|
|
/* Condition variable. */
|
|
typedef struct
|
|
{
|
|
unsigned long opaque;
|
|
} cnd_t;
|
|
|
|
/* Thread-specific storage key. */
|
|
typedef struct
|
|
{
|
|
unsigned long opaque;
|
|
} tss_t;
|
|
|
|
/* call_once state. */
|
|
typedef struct
|
|
{
|
|
unsigned long opaque;
|
|
} once_flag;
|
|
|
|
/* Initializer for a once_flag object. */
|
|
#define ONCE_FLAG_INIT {0}
|
|
|
|
/* Upper bound on tss_dtor_t invocations per key at thread exit. */
|
|
#define TSS_DTOR_ITERATIONS 4
|
|
|
|
/* Mutex kinds for mtx_init. */
|
|
enum
|
|
{
|
|
mtx_plain = 0,
|
|
mtx_recursive = 1,
|
|
mtx_timed = 2
|
|
};
|
|
|
|
/* Result codes shared by the thrd_* and mtx_* functions. */
|
|
enum
|
|
{
|
|
thrd_success = 0,
|
|
thrd_busy = 1,
|
|
thrd_error = 2,
|
|
thrd_nomem = 3,
|
|
thrd_timedout = 4
|
|
};
|
|
|
|
/* Create a thread running func(arg); stores its id through thr. */
|
|
int
|
|
thrd_create(thrd_t *thr, thrd_start_t func, void *arg);
|
|
|
|
/* Non-zero iff lhs and rhs name the same thread. */
|
|
int
|
|
thrd_equal(thrd_t lhs, thrd_t rhs);
|
|
|
|
/* Identifier of the calling thread. */
|
|
thrd_t
|
|
thrd_current(void);
|
|
|
|
/* Sleep for the interval in *duration; *remaining gets the unslept part. */
|
|
int
|
|
thrd_sleep(const struct timespec *duration, struct timespec *remaining);
|
|
|
|
/* Yield the processor to other runnable threads. */
|
|
void
|
|
thrd_yield(void);
|
|
|
|
/* Terminate the calling thread, reporting res. */
|
|
_Noreturn void
|
|
thrd_exit(int res);
|
|
|
|
/* Detach thr so its resources are released on exit. */
|
|
int
|
|
thrd_detach(thrd_t thr);
|
|
|
|
/* Wait for thr to exit; stores its result through *res when non-NULL. */
|
|
int
|
|
thrd_join(thrd_t thr, int *res);
|
|
|
|
/* Initialize *mtx with the given kind. */
|
|
int
|
|
mtx_init(mtx_t *mtx, int type);
|
|
|
|
/* Lock *mtx, blocking if needed. */
|
|
int
|
|
mtx_lock(mtx_t *mtx);
|
|
|
|
/* Lock *mtx, blocking at most until *ts. */
|
|
int
|
|
mtx_timedlock(mtx_t *restrict mtx, const struct timespec *restrict ts);
|
|
|
|
/* Lock *mtx unless another thread holds it (thrd_busy). */
|
|
int
|
|
mtx_trylock(mtx_t *mtx);
|
|
|
|
/* Unlock *mtx. */
|
|
int
|
|
mtx_unlock(mtx_t *mtx);
|
|
|
|
/* Release *mtx's resources. */
|
|
void
|
|
mtx_destroy(mtx_t *mtx);
|
|
|
|
/* Run func exactly once per once_flag object. */
|
|
void
|
|
call_once(once_flag *flag, void (*func)(void));
|
|
|
|
/* Initialize *cnd. */
|
|
int
|
|
cnd_init(cnd_t *cnd);
|
|
|
|
/* Wake one thread waiting on *cnd. */
|
|
int
|
|
cnd_signal(cnd_t *cnd);
|
|
|
|
/* Wake all threads waiting on *cnd. */
|
|
int
|
|
cnd_broadcast(cnd_t *cnd);
|
|
|
|
/* Wait on *cnd; *mtx must be locked by the caller. */
|
|
int
|
|
cnd_wait(cnd_t *cnd, mtx_t *mtx);
|
|
|
|
/* Wait on *cnd at most until *ts. */
|
|
int
|
|
cnd_timedwait(cnd_t *restrict cnd, mtx_t *restrict mtx, const struct timespec *restrict ts);
|
|
|
|
/* Release *cnd's resources. */
|
|
void
|
|
cnd_destroy(cnd_t *cnd);
|
|
|
|
/* Create a thread-specific key *key; dtor may be NULL. */
|
|
int
|
|
tss_create(tss_t *key, tss_dtor_t dtor);
|
|
|
|
/* Value stored for *key in the calling thread (NULL when unset). */
|
|
void *
|
|
tss_get(tss_t key);
|
|
|
|
/* Store val under *key for the calling thread. */
|
|
int
|
|
tss_set(tss_t key, void *val);
|
|
|
|
/* Release *key; the key may not be used afterwards. */
|
|
void
|
|
tss_delete(tss_t key);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* VLIBC_HAS_HEADER_THREADS_H */
|
|
|
|
#endif /* VLIBC_THREADS_H */
|