1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #ifndef _THREADS_H_ 30 #define _THREADS_H_ 31 32 #include <time.h> 33 34 /* 35 * The C11 threads interface. 36 * 37 * This interface is implemented as a light-weight wrapper around 38 * <pthread.h>. To prevent namespace pollution, the once_flag object, 39 * its corresponding ONCE_FLAG_INIT and TSS_DTOR_ITERATIONS have been 40 * copied from this header file. They must be kept in sync. 41 */ 42 43 typedef struct pthread_cond *cnd_t; 44 typedef struct pthread_mutex *mtx_t; 45 typedef struct pthread *thrd_t; 46 typedef int tss_t; 47 48 typedef struct { 49 int __state; 50 mtx_t __mutex; 51 } once_flag; 52 53 typedef void (*tss_dtor_t)(void *); 54 typedef int (*thrd_start_t)(void *); 55 56 enum { 57 mtx_plain = 0x1, 58 mtx_recursive = 0x2, 59 mtx_timed = 0x4 60 }; 61 62 enum { 63 thrd_busy = 1, 64 thrd_error = 2, 65 thrd_nomem = 3, 66 thrd_success = 4, 67 thrd_timedout = 5 68 }; 69 70 #if !defined(__cplusplus) || __cplusplus < 201103L 71 #define thread_local _Thread_local 72 #endif 73 #define ONCE_FLAG_INIT { 0, NULL } 74 #define TSS_DTOR_ITERATIONS 4 75 76 __BEGIN_DECLS 77 void call_once(once_flag *, void (*)(void)); 78 int cnd_broadcast(cnd_t *); 79 void cnd_destroy(cnd_t *); 80 int cnd_init(cnd_t *); 81 int cnd_signal(cnd_t *); 82 int cnd_timedwait(cnd_t *__restrict, mtx_t *__restrict __mtx, 83 const struct timespec *__restrict) 84 __requires_exclusive(*__mtx); 85 int cnd_wait(cnd_t *, mtx_t *__mtx) 86 __requires_exclusive(*__mtx); 87 void mtx_destroy(mtx_t *__mtx) 88 __requires_unlocked(*__mtx); 89 int mtx_init(mtx_t *__mtx, int) 90 __requires_unlocked(*__mtx); 91 int mtx_lock(mtx_t *__mtx) 92 __locks_exclusive(*__mtx); 93 int mtx_timedlock(mtx_t *__restrict __mtx, 94 const struct timespec *__restrict) 95 __trylocks_exclusive(thrd_success, *__mtx); 96 int mtx_trylock(mtx_t *__mtx) 97 __trylocks_exclusive(thrd_success, *__mtx); 98 int mtx_unlock(mtx_t *__mtx) 99 __unlocks(*__mtx); 100 int thrd_create(thrd_t *, thrd_start_t, void *); 101 thrd_t thrd_current(void); 102 int thrd_detach(thrd_t); 103 int thrd_equal(thrd_t, thrd_t); 104 _Noreturn void 105 thrd_exit(int); 106 int thrd_join(thrd_t, int *); 107 int thrd_sleep(const struct timespec *, struct timespec *); 108 void thrd_yield(void); 109 int tss_create(tss_t *, tss_dtor_t); 110 void tss_delete(tss_t); 111 void * tss_get(tss_t); 112 int tss_set(tss_t, void *); 113 __END_DECLS 114 115 #endif /* !_THREADS_H_ */ 116