1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 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 * $FreeBSD$ 29 */ 30 31 #ifndef _THREADS_H_ 32 #define _THREADS_H_ 33 34 #include <time.h> 35 36 /* 37 * The C11 threads interface. 38 * 39 * This interface is implemented as a light-weight wrapper around 40 * <pthread.h>. To prevent namespace pollution, the once_flag object, 41 * its corresponding ONCE_FLAG_INIT and TSS_DTOR_ITERATIONS have been 42 * copied from this header file. They must be kept in sync. 43 */ 44 45 typedef struct pthread_cond *cnd_t; 46 typedef struct pthread_mutex *mtx_t; 47 typedef struct pthread *thrd_t; 48 typedef int tss_t; 49 50 typedef struct { 51 int __state; 52 mtx_t __mutex; 53 } once_flag; 54 55 typedef void (*tss_dtor_t)(void *); 56 typedef int (*thrd_start_t)(void *); 57 58 enum { 59 mtx_plain = 0x1, 60 mtx_recursive = 0x2, 61 mtx_timed = 0x4 62 }; 63 64 enum { 65 thrd_busy = 1, 66 thrd_error = 2, 67 thrd_nomem = 3, 68 thrd_success = 4, 69 thrd_timedout = 5 70 }; 71 72 #if !defined(__cplusplus) || __cplusplus < 201103L 73 #define thread_local _Thread_local 74 #endif 75 #define ONCE_FLAG_INIT { 0, NULL } 76 #define TSS_DTOR_ITERATIONS 4 77 78 __BEGIN_DECLS 79 void call_once(once_flag *, void (*)(void)); 80 int cnd_broadcast(cnd_t *); 81 void cnd_destroy(cnd_t *); 82 int cnd_init(cnd_t *); 83 int cnd_signal(cnd_t *); 84 int cnd_timedwait(cnd_t *__restrict, mtx_t *__restrict __mtx, 85 const struct timespec *__restrict) 86 __requires_exclusive(*__mtx); 87 int cnd_wait(cnd_t *, mtx_t *__mtx) 88 __requires_exclusive(*__mtx); 89 void mtx_destroy(mtx_t *__mtx) 90 __requires_unlocked(*__mtx); 91 int mtx_init(mtx_t *__mtx, int) 92 __requires_unlocked(*__mtx); 93 int mtx_lock(mtx_t *__mtx) 94 __locks_exclusive(*__mtx); 95 int mtx_timedlock(mtx_t *__restrict __mtx, 96 const struct timespec *__restrict) 97 __trylocks_exclusive(thrd_success, *__mtx); 98 int mtx_trylock(mtx_t *__mtx) 99 __trylocks_exclusive(thrd_success, *__mtx); 100 int mtx_unlock(mtx_t *__mtx) 101 __unlocks(*__mtx); 102 int thrd_create(thrd_t *, thrd_start_t, void *); 103 thrd_t thrd_current(void); 104 int thrd_detach(thrd_t); 105 int thrd_equal(thrd_t, thrd_t); 106 _Noreturn void 107 thrd_exit(int); 108 int thrd_join(thrd_t, int *); 109 int thrd_sleep(const struct timespec *, struct timespec *); 110 void thrd_yield(void); 111 int tss_create(tss_t *, tss_dtor_t); 112 void tss_delete(tss_t); 113 void * tss_get(tss_t); 114 int tss_set(tss_t, void *); 115 __END_DECLS 116 117 #endif /* !_THREADS_H_ */ 118