Files

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 */