diff --git a/headers/posix/pthread.h b/headers/posix/pthread.h index 5bdea8b735..7135649c6e 100644 --- a/headers/posix/pthread.h +++ b/headers/posix/pthread.h @@ -49,6 +49,9 @@ #define PTHREAD_PRIO_INHERIT 1 #define PTHREAD_PRIO_PROTECT 2 +#define PTHREAD_DESTRUCTOR_ITERATIONS 4 + + /* private structure */ struct __pthread_cleanup_handler { struct __pthread_cleanup_handler *previous; diff --git a/headers/posix/threads.h b/headers/posix/threads.h index 3d8c9c1d17..58658e5d68 100644 --- a/headers/posix/threads.h +++ b/headers/posix/threads.h @@ -37,9 +37,21 @@ #include #include +typedef pthread_cond_t cnd_t; +typedef pthread_mutex_t mtx_t; typedef pthread_t thrd_t; +typedef pthread_key_t tss_t; +typedef pthread_once_t once_flag; + +typedef void (*tss_dtor_t)(void *); typedef int (*thrd_start_t)(void *); +enum { + mtx_plain = 0x1, + mtx_recursive = 0x2, + mtx_timed = 0x4 +}; + enum { thrd_busy = 1, thrd_error = 2, @@ -48,10 +60,31 @@ enum { thrd_timedout = 5 }; +#if !defined(__cplusplus) || __cplusplus < 201103L +#define thread_local _Thread_local +#endif +#define ONCE_FLAG_INIT { 0 } +#define TSS_DTOR_ITERATIONS 4 + #ifdef __cplusplus extern "C" { #endif +void call_once(once_flag *, void (*)(void)); +int cnd_broadcast(cnd_t *); +void cnd_destroy(cnd_t *); +int cnd_init(cnd_t *); +int cnd_signal(cnd_t *); +int cnd_timedwait(cnd_t *__restrict, mtx_t *__restrict __mtx, + const struct timespec *__restrict); +int cnd_wait(cnd_t *, mtx_t *__mtx); +void mtx_destroy(mtx_t *__mtx); +int mtx_init(mtx_t *__mtx, int); +int mtx_lock(mtx_t *__mtx); +int mtx_timedlock(mtx_t *__restrict __mtx, + const struct timespec *__restrict); +int mtx_trylock(mtx_t *__mtx); +int mtx_unlock(mtx_t *__mtx); int thrd_create(thrd_t *thread, thrd_start_t, void *); thrd_t thrd_current(void); int thrd_detach(thrd_t); @@ -62,6 +95,11 @@ int thrd_join(thrd_t, int *); int thrd_sleep(const struct timespec *, struct timespec *); void thrd_yield(void); +int tss_create(tss_t *, tss_dtor_t); +void tss_delete(tss_t); +void * tss_get(tss_t); +int tss_set(tss_t, void *); + #ifdef __cplusplus } #endif diff --git a/src/system/libroot/posix/Jamfile b/src/system/libroot/posix/Jamfile index 3271dce2c5..c26c1f9c73 100644 --- a/src/system/libroot/posix/Jamfile +++ b/src/system/libroot/posix/Jamfile @@ -19,7 +19,8 @@ for architectureObject in [ MultiArchSubDirSetup ] { } - local threadsLib = threads.c ; + local threadsLib = call_once.c cnd.c mtx.c threads.c tss.c ; + SEARCH_SOURCE += [ FDirName $(SUBDIR) libstdthreads ] ; if $(HAIKU_CC_IS_LEGACY_GCC_$(architecture)) = 1 { # the threads library is not available on gcc2 threadsLib = ; diff --git a/src/system/libroot/posix/libstdthreads/call_once.c b/src/system/libroot/posix/libstdthreads/call_once.c new file mode 100644 index 0000000000..2b97558e16 --- /dev/null +++ b/src/system/libroot/posix/libstdthreads/call_once.c @@ -0,0 +1,43 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 Ed Schouten + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include + +#include "threads.h" + +void +call_once(once_flag *flag, void (*func)(void)) +{ + + (void)pthread_once((pthread_once_t *)flag, func); +} + +_Static_assert(sizeof(once_flag) == sizeof(pthread_once_t), + "once_flag must be of the same size as pthread_once_t"); diff --git a/src/system/libroot/posix/libstdthreads/cnd.c b/src/system/libroot/posix/libstdthreads/cnd.c new file mode 100644 index 0000000000..6e61313074 --- /dev/null +++ b/src/system/libroot/posix/libstdthreads/cnd.c @@ -0,0 +1,97 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 Ed Schouten + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include + +#include "threads.h" + +int +cnd_broadcast(cnd_t *cond) +{ + + if (pthread_cond_broadcast(cond) != 0) + return (thrd_error); + return (thrd_success); +} + +void +cnd_destroy(cnd_t *cond) +{ + + (void)pthread_cond_destroy(cond); +} + +int +cnd_init(cnd_t *cond) +{ + + switch (pthread_cond_init(cond, NULL)) { + case 0: + return (thrd_success); + case ENOMEM: + return (thrd_nomem); + default: + return (thrd_error); + } +} + +int +cnd_signal(cnd_t *cond) +{ + + if (pthread_cond_signal(cond) != 0) + return (thrd_error); + return (thrd_success); +} + +int +cnd_timedwait(cnd_t *restrict cond, mtx_t *restrict mtx, + const struct timespec *restrict ts) +{ + + switch (pthread_cond_timedwait(cond, mtx, ts)) { + case 0: + return (thrd_success); + case ETIMEDOUT: + return (thrd_timedout); + default: + return (thrd_error); + } +} + +int +cnd_wait(cnd_t *cond, mtx_t *mtx) +{ + + if (pthread_cond_wait(cond, mtx) != 0) + return (thrd_error); + return (thrd_success); +} diff --git a/src/system/libroot/posix/libstdthreads/mtx.c b/src/system/libroot/posix/libstdthreads/mtx.c new file mode 100644 index 0000000000..f321e79b89 --- /dev/null +++ b/src/system/libroot/posix/libstdthreads/mtx.c @@ -0,0 +1,115 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 Ed Schouten + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include + +#include "threads.h" + +void +mtx_destroy(mtx_t *mtx) +{ + + (void)pthread_mutex_destroy(mtx); +} + +int +mtx_init(mtx_t *mtx, int type) +{ + pthread_mutexattr_t attr; + int mt; + + switch (type) { + case mtx_plain: + case mtx_timed: + mt = PTHREAD_MUTEX_NORMAL; + break; + case mtx_plain | mtx_recursive: + case mtx_timed | mtx_recursive: + mt = PTHREAD_MUTEX_RECURSIVE; + break; + default: + return (thrd_error); + } + + if (pthread_mutexattr_init(&attr) != 0) + return (thrd_error); + if (pthread_mutexattr_settype(&attr, mt) != 0) + return (thrd_error); + if (pthread_mutex_init(mtx, &attr) != 0) + return (thrd_error); + return (thrd_success); +} + +int +mtx_lock(mtx_t *mtx) +{ + + if (pthread_mutex_lock(mtx) != 0) + return (thrd_error); + return (thrd_success); +} + +int +mtx_timedlock(mtx_t *restrict mtx, const struct timespec *restrict ts) +{ + + switch (pthread_mutex_timedlock(mtx, ts)) { + case 0: + return (thrd_success); + case ETIMEDOUT: + return (thrd_timedout); + default: + return (thrd_error); + } +} + +int +mtx_trylock(mtx_t *mtx) +{ + + switch (pthread_mutex_trylock(mtx)) { + case 0: + return (thrd_success); + case EBUSY: + return (thrd_busy); + default: + return (thrd_error); + } +} + +int +mtx_unlock(mtx_t *mtx) +{ + + if (pthread_mutex_unlock(mtx) != 0) + return (thrd_error); + return (thrd_success); +} diff --git a/src/system/libroot/posix/libstdthreads/tss.c b/src/system/libroot/posix/libstdthreads/tss.c new file mode 100644 index 0000000000..a42f3375c4 --- /dev/null +++ b/src/system/libroot/posix/libstdthreads/tss.c @@ -0,0 +1,69 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 Ed Schouten + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + + +#include + +#include "threads.h" + +int +tss_create(tss_t *key, tss_dtor_t dtor) +{ + + if (pthread_key_create(key, dtor) != 0) + return (thrd_error); + return (thrd_success); +} + +void +tss_delete(tss_t key) +{ + + (void)pthread_key_delete(key); +} + +void * +tss_get(tss_t key) +{ + + return (pthread_getspecific(key)); +} + +int +tss_set(tss_t key, void *val) +{ + + if (pthread_setspecific(key, val) != 0) + return (thrd_error); + return (thrd_success); +} + +_Static_assert(TSS_DTOR_ITERATIONS == PTHREAD_DESTRUCTOR_ITERATIONS, + "TSS_DTOR_ITERATIONS must be identical to PTHREAD_DESTRUCTOR_ITERATIONS");