X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/beac10d6593fee948759c05d956b83db6803f2ec..1b96e9580714d7a677d10a8e286b3f8a2bddc6f5:/src/thread-posix.h?ds=sidebyside diff --git a/src/thread-posix.h b/src/thread-posix.h new file mode 100644 index 0000000..b1cd990 --- /dev/null +++ b/src/thread-posix.h @@ -0,0 +1,68 @@ +/* + * Copyright © 2024 Nick Bowler + * + * Helpers for hosts using POSIX threading (pthreads) API. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#if USE_POSIX_THREADS_WEAK +# pragma weak pthread_key_create +# pragma weak pthread_getspecific +# pragma weak pthread_setspecific +#endif + +static struct { + union { + pthread_key_t mt; +#if USE_POSIX_THREADS_WEAK + void *st; +#endif + } u; + +#if USE_POSIX_THREADS_WEAK + signed char valid; +#else + bool valid; +#endif +} tls_key; +#define tls_key_valid (tls_key.valid != 0) + +static void tls_key_init(void) +{ + if (pthread_in_use()) + tls_key.valid = !pthread_key_create(&tls_key.u.mt, free); + else + tls_key.valid = -1; +} + +static void *tls_get(void) +{ +#if USE_POSIX_THREADS_WEAK + if (tls_key.valid < 0) + return tls_key.u.st; +#endif + return pthread_getspecific(tls_key.u.mt); +} + +static int tls_set(void *p) +{ +#if USE_POSIX_THREADS_WEAK + if (tls_key.valid < 0) + return (tls_key.u.st = p, 1); +#endif + return !pthread_setspecific(tls_key.u.mt, p); +}