summaryrefslogtreecommitdiff
path: root/kit/threads.posix.c
diff options
context:
space:
mode:
Diffstat (limited to 'kit/threads.posix.c')
-rw-r--r--kit/threads.posix.c271
1 files changed, 0 insertions, 271 deletions
diff --git a/kit/threads.posix.c b/kit/threads.posix.c
deleted file mode 100644
index 44465a3..0000000
--- a/kit/threads.posix.c
+++ /dev/null
@@ -1,271 +0,0 @@
-#include "threads.h"
-
-#ifndef KIT_DISABLE_SYSTEM_THREADS
-# include "allocator.h"
-
-# if !defined(_WIN32) || defined(__CYGWIN__)
-# include <assert.h>
-# include <errno.h>
-# include <limits.h>
-# include <sched.h>
-# include <stdlib.h>
-# include <unistd.h>
-
-# ifndef PTHREAD_STACK_MIN
-# define PTHREAD_STACK_MIN 16384
-# endif
-
-/*
-Configuration macro:
-
- EMULATED_THREADS_USE_NATIVE_TIMEDLOCK
- Use pthread_mutex_timedlock() for `mtx_timedlock()'
- Otherwise use mtx_trylock() + *busy loop* emulation.
-*/
-# if !defined(__CYGWIN__) && !defined(__APPLE__) && \
- !defined(__NetBSD__)
-# define EMULATED_THREADS_USE_NATIVE_TIMEDLOCK
-# endif
-
-/*
-Implementation limits:
- - Conditionally emulation for "mutex with timeout"
- (see EMULATED_THREADS_USE_NATIVE_TIMEDLOCK macro)
-*/
-typedef struct {
- thrd_start_t func;
- void *arg;
-} impl_thrd_param_t;
-
-static void *impl_thrd_routine(void *p) {
- impl_thrd_param_t pack = *((impl_thrd_param_t *) p);
- kit_alloc_dispatch(NULL, KIT_DEALLOCATE, 0, 0, p);
- return (void *) (intptr_t) pack.func(pack.arg);
-}
-
-void call_once(once_flag *flag, void (*func)(void)) {
- pthread_once(flag, func);
-}
-
-int cnd_broadcast(cnd_t *cond) {
- assert(cond != NULL);
- return (pthread_cond_broadcast(cond) == 0) ? thrd_success
- : thrd_error;
-}
-
-void cnd_destroy(cnd_t *cond) {
- assert(cond);
- pthread_cond_destroy(cond);
-}
-
-int cnd_init(cnd_t *cond) {
- assert(cond != NULL);
- return (pthread_cond_init(cond, NULL) == 0) ? thrd_success
- : thrd_error;
-}
-
-int cnd_signal(cnd_t *cond) {
- assert(cond != NULL);
- return (pthread_cond_signal(cond) == 0) ? thrd_success : thrd_error;
-}
-
-int cnd_timedwait(cnd_t *cond, mtx_t *mtx,
- struct timespec const *abs_time) {
- int rt;
-
- assert(mtx != NULL);
- assert(cond != NULL);
- assert(abs_time != NULL);
-
- rt = pthread_cond_timedwait(cond, mtx, abs_time);
- if (rt == ETIMEDOUT)
- return thrd_timedout;
- return (rt == 0) ? thrd_success : thrd_error;
-}
-
-int cnd_wait(cnd_t *cond, mtx_t *mtx) {
- assert(mtx != NULL);
- assert(cond != NULL);
- return (pthread_cond_wait(cond, mtx) == 0) ? thrd_success
- : thrd_error;
-}
-
-void mtx_destroy(mtx_t *mtx) {
- assert(mtx != NULL);
- pthread_mutex_destroy(mtx);
-}
-
-/*
- * XXX: Workaround when building with -O0 and without pthreads link.
- *
- * In such cases constant folding and dead code elimination won't be
- * available, thus the compiler will always add the pthread_mutexattr*
- * functions into the binary. As we try to link, we'll fail as the
- * symbols are unresolved.
- *
- * Ideally we'll enable the optimisations locally, yet that does not
- * seem to work.
- *
- * So the alternative workaround is to annotate the symbols as weak.
- * Thus the linker will be happy and things don't clash when building
- * with -O1 or greater.
- */
-# if defined(KIT_HAVE_FUNC_ATTRIBUTE_WEAK) && !defined(__CYGWIN__)
-__attribute__((weak)) int pthread_mutexattr_init(
- pthread_mutexattr_t *attr);
-
-__attribute__((weak)) int pthread_mutexattr_settype(
- pthread_mutexattr_t *attr, int type);
-
-__attribute__((weak)) int pthread_mutexattr_destroy(
- pthread_mutexattr_t *attr);
-# endif
-
-int mtx_init(mtx_t *mtx, int type) {
-# ifdef KIT_HAVE_PTHREAD_MUTEXATTR_SETTYPE
- pthread_mutexattr_t attr;
-# endif
- assert(mtx != NULL);
- if (type != mtx_plain && type != mtx_timed &&
- type != (mtx_plain | mtx_recursive) &&
- type != (mtx_timed | mtx_recursive))
- return thrd_error;
-
- if ((type & mtx_recursive) == 0) {
- pthread_mutex_init(mtx, NULL);
- return thrd_success;
- }
-
-# ifdef KIT_HAVE_PTHREAD_MUTEXATTR_SETTYPE
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(mtx, &attr);
- pthread_mutexattr_destroy(&attr);
- return thrd_success;
-# else
- return thrd_error;
-# endif
-}
-
-int mtx_lock(mtx_t *mtx) {
- assert(mtx != NULL);
- return (pthread_mutex_lock(mtx) == 0) ? thrd_success : thrd_error;
-}
-
-int mtx_timedlock(mtx_t *mtx, const struct timespec *ts) {
- assert(mtx != NULL);
- assert(ts != NULL);
-
- {
-# ifdef EMULATED_THREADS_USE_NATIVE_TIMEDLOCK
- int rt;
- rt = pthread_mutex_timedlock(mtx, ts);
- if (rt == 0)
- return thrd_success;
- return (rt == ETIMEDOUT) ? thrd_timedout : thrd_error;
-# else
- time_t expire = time(NULL);
- expire += ts->tv_sec;
- while (mtx_trylock(mtx) != thrd_success) {
- time_t now = time(NULL);
- if (expire < now)
- return thrd_timedout;
- // busy loop!
- thrd_yield();
- }
- return thrd_success;
-# endif
- }
-}
-
-int mtx_trylock(mtx_t *mtx) {
- assert(mtx != NULL);
- return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy;
-}
-
-int mtx_unlock(mtx_t *mtx) {
- assert(mtx != NULL);
- return (pthread_mutex_unlock(mtx) == 0) ? thrd_success : thrd_error;
-}
-
-int thrd_create_with_stack(thrd_t *thr, thrd_start_t func, void *arg,
- ptrdiff_t const require_stack_size) {
- impl_thrd_param_t *pack;
- assert(thr != NULL);
- assert(require_stack_size == 0 ||
- require_stack_size >= PTHREAD_STACK_MIN);
- pthread_attr_t attr;
- pthread_attr_t *attr_p = NULL;
- if (require_stack_size > 0) {
- ptrdiff_t const page_size = (ptrdiff_t) sysconf(_SC_PAGESIZE);
- ptrdiff_t const delta = require_stack_size % page_size;
- ptrdiff_t const stack_size = delta == 0 ? require_stack_size
- : require_stack_size +
- page_size - delta;
- if (pthread_attr_init(&attr) != 0)
- return thrd_nomem;
- if (pthread_attr_setstacksize(&attr, (size_t) stack_size) != 0)
- return thrd_wrong_stack_size;
- attr_p = &attr;
- }
-
- pack = (impl_thrd_param_t *) kit_alloc_dispatch(
- NULL, KIT_ALLOCATE, sizeof(impl_thrd_param_t), 0, NULL);
- if (!pack) {
- if (attr_p)
- pthread_attr_destroy(attr_p);
- return thrd_nomem;
- }
- pack->func = func;
- pack->arg = arg;
- if (pthread_create(thr, attr_p, impl_thrd_routine, pack) != 0) {
- kit_alloc_dispatch(NULL, KIT_DEALLOCATE, 0, 0, pack);
- if (attr_p)
- pthread_attr_destroy(attr_p);
- return thrd_error;
- }
- if (attr_p)
- pthread_attr_destroy(attr_p);
- return thrd_success;
-}
-
-int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) {
- return thrd_create_with_stack(thr, func, arg, 0);
-}
-thrd_t thrd_current(void) {
- return pthread_self();
-}
-
-int thrd_detach(thrd_t thr) {
- return (pthread_detach(thr) == 0) ? thrd_success : thrd_error;
-}
-
-int thrd_equal(thrd_t thr0, thrd_t thr1) {
- return pthread_equal(thr0, thr1);
-}
-
-_Noreturn void thrd_exit(int res) {
- pthread_exit((void *) (intptr_t) res);
-}
-
-int thrd_join(thrd_t thr, int *res) {
- void *code;
- if (pthread_join(thr, &code) != 0)
- return thrd_error;
- if (res)
- *res = (int) (intptr_t) code;
- return thrd_success;
-}
-
-int thrd_sleep(const struct timespec *time_point,
- struct timespec *remaining) {
- assert(time_point != NULL);
- return nanosleep(time_point, remaining);
-}
-
-void thrd_yield(void) {
- sched_yield();
-}
-
-# endif
-#endif