diff --git a/lib/libc/common/CMakeLists.txt b/lib/libc/common/CMakeLists.txt index a52d8dc8d4..a99ec825a0 100644 --- a/lib/libc/common/CMakeLists.txt +++ b/lib/libc/common/CMakeLists.txt @@ -12,6 +12,7 @@ zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_THRD source/thrd/cnd.c source/thrd/mtx.c source/thrd/thrd.c + source/thrd/tss.c ) # Prevent compiler from optimizing calloc into an infinite recursive call diff --git a/lib/libc/common/include/machine/_threads.h b/lib/libc/common/include/machine/_threads.h index 0b82b87650..2742384599 100644 --- a/lib/libc/common/include/machine/_threads.h +++ b/lib/libc/common/include/machine/_threads.h @@ -14,6 +14,7 @@ extern "C" { typedef int cnd_t; typedef int mtx_t; typedef int thrd_t; +typedef int tss_t; #ifdef __cplusplus } diff --git a/lib/libc/common/include/threads.h b/lib/libc/common/include/threads.h index f4a52f74b1..c7d2314444 100644 --- a/lib/libc/common/include/threads.h +++ b/lib/libc/common/include/threads.h @@ -63,6 +63,17 @@ int cnd_signal(cnd_t *cond); int cnd_broadcast(cnd_t *cond); void cnd_destroy(cnd_t *cond); +#ifndef thread_local +#define thread_local _Thread_local +#endif + +typedef void (*tss_dtor_t)(void *val); + +int tss_create(tss_t *key, tss_dtor_t destructor); +void *tss_get(tss_t key); +int tss_set(tss_t key, void *val); +void tss_delete(tss_t key); + #ifdef __cplusplus } #endif diff --git a/lib/libc/common/source/thrd/tss.c b/lib/libc/common/source/thrd/tss.c new file mode 100644 index 0000000000..4b110d1717 --- /dev/null +++ b/lib/libc/common/source/thrd/tss.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include + +int tss_create(tss_t *key, tss_dtor_t destructor) +{ + switch (pthread_key_create(key, destructor)) { + case 0: + return thrd_success; + case EAGAIN: + return thrd_busy; + case ENOMEM: + return thrd_nomem; + default: + return thrd_error; + } +} + +void *tss_get(tss_t key) +{ + return pthread_getspecific(key); +} + +int tss_set(tss_t key, void *val) +{ + switch (pthread_setspecific(key, val)) { + case 0: + return thrd_success; + case ENOMEM: + return thrd_nomem; + default: + return thrd_error; + } +} + +void tss_delete(tss_t key) +{ + (void)pthread_key_delete(key); +}