#ifndef VLIBC_THREADS_H #define VLIBC_THREADS_H /* * vlibc — . * * 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 #if VLIBC_HAS_HEADER_THREADS_H #ifdef __cplusplus extern "C" { #endif /* Forward-declared: the real definition lives in (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 */