1*8d67ca89SAndroid Build Coastguard Worker /* 2*8d67ca89SAndroid Build Coastguard Worker * Copyright (C) 2019 The Android Open Source Project 3*8d67ca89SAndroid Build Coastguard Worker * All rights reserved. 4*8d67ca89SAndroid Build Coastguard Worker * 5*8d67ca89SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without 6*8d67ca89SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions 7*8d67ca89SAndroid Build Coastguard Worker * are met: 8*8d67ca89SAndroid Build Coastguard Worker * * Redistributions of source code must retain the above copyright 9*8d67ca89SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer. 10*8d67ca89SAndroid Build Coastguard Worker * * Redistributions in binary form must reproduce the above copyright 11*8d67ca89SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in 12*8d67ca89SAndroid Build Coastguard Worker * the documentation and/or other materials provided with the 13*8d67ca89SAndroid Build Coastguard Worker * distribution. 14*8d67ca89SAndroid Build Coastguard Worker * 15*8d67ca89SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16*8d67ca89SAndroid Build Coastguard Worker * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17*8d67ca89SAndroid Build Coastguard Worker * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18*8d67ca89SAndroid Build Coastguard Worker * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19*8d67ca89SAndroid Build Coastguard Worker * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20*8d67ca89SAndroid Build Coastguard Worker * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21*8d67ca89SAndroid Build Coastguard Worker * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22*8d67ca89SAndroid Build Coastguard Worker * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23*8d67ca89SAndroid Build Coastguard Worker * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24*8d67ca89SAndroid Build Coastguard Worker * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25*8d67ca89SAndroid Build Coastguard Worker * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26*8d67ca89SAndroid Build Coastguard Worker * SUCH DAMAGE. 27*8d67ca89SAndroid Build Coastguard Worker */ 28*8d67ca89SAndroid Build Coastguard Worker 29*8d67ca89SAndroid Build Coastguard Worker #pragma once 30*8d67ca89SAndroid Build Coastguard Worker 31*8d67ca89SAndroid Build Coastguard Worker /** 32*8d67ca89SAndroid Build Coastguard Worker * @file threads.h 33*8d67ca89SAndroid Build Coastguard Worker * @brief C11 threads. 34*8d67ca89SAndroid Build Coastguard Worker */ 35*8d67ca89SAndroid Build Coastguard Worker 36*8d67ca89SAndroid Build Coastguard Worker #include <sys/cdefs.h> 37*8d67ca89SAndroid Build Coastguard Worker 38*8d67ca89SAndroid Build Coastguard Worker #include <pthread.h> 39*8d67ca89SAndroid Build Coastguard Worker #include <time.h> 40*8d67ca89SAndroid Build Coastguard Worker 41*8d67ca89SAndroid Build Coastguard Worker #define ONCE_FLAG_INIT PTHREAD_ONCE_INIT 42*8d67ca89SAndroid Build Coastguard Worker #define TSS_DTOR_ITERATIONS PTHREAD_DESTRUCTOR_ITERATIONS 43*8d67ca89SAndroid Build Coastguard Worker 44*8d67ca89SAndroid Build Coastguard Worker /** The type for a condition variable. */ 45*8d67ca89SAndroid Build Coastguard Worker typedef pthread_cond_t cnd_t; 46*8d67ca89SAndroid Build Coastguard Worker /** The type for a thread. */ 47*8d67ca89SAndroid Build Coastguard Worker typedef pthread_t thrd_t; 48*8d67ca89SAndroid Build Coastguard Worker /** The type for a thread-specific storage key. */ 49*8d67ca89SAndroid Build Coastguard Worker typedef pthread_key_t tss_t; 50*8d67ca89SAndroid Build Coastguard Worker /** The type for a mutex. */ 51*8d67ca89SAndroid Build Coastguard Worker typedef pthread_mutex_t mtx_t; 52*8d67ca89SAndroid Build Coastguard Worker 53*8d67ca89SAndroid Build Coastguard Worker /** The type for a thread-specific storage destructor. */ 54*8d67ca89SAndroid Build Coastguard Worker typedef void (*tss_dtor_t)(void* _Nullable); 55*8d67ca89SAndroid Build Coastguard Worker /** The type of the function passed to thrd_create() to create a new thread. */ 56*8d67ca89SAndroid Build Coastguard Worker typedef int (*thrd_start_t)(void* _Nullable); 57*8d67ca89SAndroid Build Coastguard Worker 58*8d67ca89SAndroid Build Coastguard Worker /** The type used by call_once(). */ 59*8d67ca89SAndroid Build Coastguard Worker typedef pthread_once_t once_flag; 60*8d67ca89SAndroid Build Coastguard Worker 61*8d67ca89SAndroid Build Coastguard Worker enum { 62*8d67ca89SAndroid Build Coastguard Worker mtx_plain = 0x1, 63*8d67ca89SAndroid Build Coastguard Worker mtx_recursive = 0x2, 64*8d67ca89SAndroid Build Coastguard Worker mtx_timed = 0x4, 65*8d67ca89SAndroid Build Coastguard Worker }; 66*8d67ca89SAndroid Build Coastguard Worker 67*8d67ca89SAndroid Build Coastguard Worker enum { 68*8d67ca89SAndroid Build Coastguard Worker thrd_success = 0, 69*8d67ca89SAndroid Build Coastguard Worker thrd_busy = 1, 70*8d67ca89SAndroid Build Coastguard Worker thrd_error = 2, 71*8d67ca89SAndroid Build Coastguard Worker thrd_nomem = 3, 72*8d67ca89SAndroid Build Coastguard Worker thrd_timedout = 4, 73*8d67ca89SAndroid Build Coastguard Worker }; 74*8d67ca89SAndroid Build Coastguard Worker 75*8d67ca89SAndroid Build Coastguard Worker /* `thread_local` is a keyword in C++11 and C23; C11 had `_Thread_local` instead. */ 76*8d67ca89SAndroid Build Coastguard Worker #if !defined(__cplusplus) && (__STDC_VERSION__ >= 201112L && __STDC_VERSION__ < 202311L) 77*8d67ca89SAndroid Build Coastguard Worker # undef thread_local 78*8d67ca89SAndroid Build Coastguard Worker # define thread_local _Thread_local 79*8d67ca89SAndroid Build Coastguard Worker #endif 80*8d67ca89SAndroid Build Coastguard Worker 81*8d67ca89SAndroid Build Coastguard Worker __BEGIN_DECLS 82*8d67ca89SAndroid Build Coastguard Worker 83*8d67ca89SAndroid Build Coastguard Worker #if __ANDROID_API__ >= 30 84*8d67ca89SAndroid Build Coastguard Worker // This file is implemented as static inlines before API level 30. 85*8d67ca89SAndroid Build Coastguard Worker 86*8d67ca89SAndroid Build Coastguard Worker /** Uses `__flag` to ensure that `__function` is called exactly once. */ 87*8d67ca89SAndroid Build Coastguard Worker void call_once(once_flag* _Nonnull __flag, void (* _Nonnull __function)(void)) __INTRODUCED_IN(30); 88*8d67ca89SAndroid Build Coastguard Worker 89*8d67ca89SAndroid Build Coastguard Worker 90*8d67ca89SAndroid Build Coastguard Worker 91*8d67ca89SAndroid Build Coastguard Worker /** 92*8d67ca89SAndroid Build Coastguard Worker * Unblocks all threads blocked on `__cond`. 93*8d67ca89SAndroid Build Coastguard Worker */ 94*8d67ca89SAndroid Build Coastguard Worker int cnd_broadcast(cnd_t* _Nonnull __cond) __INTRODUCED_IN(30); 95*8d67ca89SAndroid Build Coastguard Worker 96*8d67ca89SAndroid Build Coastguard Worker /** 97*8d67ca89SAndroid Build Coastguard Worker * Destroys a condition variable. 98*8d67ca89SAndroid Build Coastguard Worker */ 99*8d67ca89SAndroid Build Coastguard Worker void cnd_destroy(cnd_t* _Nonnull __cond) __INTRODUCED_IN(30); 100*8d67ca89SAndroid Build Coastguard Worker 101*8d67ca89SAndroid Build Coastguard Worker /** 102*8d67ca89SAndroid Build Coastguard Worker * Creates a condition variable. 103*8d67ca89SAndroid Build Coastguard Worker */ 104*8d67ca89SAndroid Build Coastguard Worker int cnd_init(cnd_t* _Nonnull __cond) __INTRODUCED_IN(30); 105*8d67ca89SAndroid Build Coastguard Worker 106*8d67ca89SAndroid Build Coastguard Worker /** 107*8d67ca89SAndroid Build Coastguard Worker * Unblocks one thread blocked on `__cond`. 108*8d67ca89SAndroid Build Coastguard Worker */ 109*8d67ca89SAndroid Build Coastguard Worker int cnd_signal(cnd_t* _Nonnull __cond) __INTRODUCED_IN(30); 110*8d67ca89SAndroid Build Coastguard Worker 111*8d67ca89SAndroid Build Coastguard Worker /** 112*8d67ca89SAndroid Build Coastguard Worker * Unlocks `__mutex` and blocks until `__cond` is signaled or `__timeout` occurs. 113*8d67ca89SAndroid Build Coastguard Worker */ 114*8d67ca89SAndroid Build Coastguard Worker int cnd_timedwait(cnd_t* _Nonnull __cond, mtx_t* _Nonnull __mutex, const struct timespec* _Nonnull __timeout) 115*8d67ca89SAndroid Build Coastguard Worker __INTRODUCED_IN(30); 116*8d67ca89SAndroid Build Coastguard Worker 117*8d67ca89SAndroid Build Coastguard Worker /** 118*8d67ca89SAndroid Build Coastguard Worker * Unlocks `__mutex` and blocks until `__cond` is signaled. 119*8d67ca89SAndroid Build Coastguard Worker */ 120*8d67ca89SAndroid Build Coastguard Worker int cnd_wait(cnd_t* _Nonnull __cond, mtx_t* _Nonnull __mutex) __INTRODUCED_IN(30); 121*8d67ca89SAndroid Build Coastguard Worker 122*8d67ca89SAndroid Build Coastguard Worker 123*8d67ca89SAndroid Build Coastguard Worker 124*8d67ca89SAndroid Build Coastguard Worker /** 125*8d67ca89SAndroid Build Coastguard Worker * Destroys a mutex. 126*8d67ca89SAndroid Build Coastguard Worker */ 127*8d67ca89SAndroid Build Coastguard Worker void mtx_destroy(mtx_t* _Nonnull __mutex) __INTRODUCED_IN(30); 128*8d67ca89SAndroid Build Coastguard Worker 129*8d67ca89SAndroid Build Coastguard Worker /** 130*8d67ca89SAndroid Build Coastguard Worker * Creates a mutex. 131*8d67ca89SAndroid Build Coastguard Worker */ 132*8d67ca89SAndroid Build Coastguard Worker int mtx_init(mtx_t* _Nonnull __mutex, int __type) __INTRODUCED_IN(30); 133*8d67ca89SAndroid Build Coastguard Worker 134*8d67ca89SAndroid Build Coastguard Worker /** 135*8d67ca89SAndroid Build Coastguard Worker * Blocks until `__mutex` is acquired. 136*8d67ca89SAndroid Build Coastguard Worker */ 137*8d67ca89SAndroid Build Coastguard Worker int mtx_lock(mtx_t* _Nonnull __mutex) __INTRODUCED_IN(30); 138*8d67ca89SAndroid Build Coastguard Worker 139*8d67ca89SAndroid Build Coastguard Worker /** 140*8d67ca89SAndroid Build Coastguard Worker * Blocks until `__mutex` is acquired or `__timeout` expires. 141*8d67ca89SAndroid Build Coastguard Worker */ 142*8d67ca89SAndroid Build Coastguard Worker int mtx_timedlock(mtx_t* _Nonnull __mutex, const struct timespec* _Nonnull __timeout) __INTRODUCED_IN(30); 143*8d67ca89SAndroid Build Coastguard Worker 144*8d67ca89SAndroid Build Coastguard Worker /** 145*8d67ca89SAndroid Build Coastguard Worker * Acquires `__mutex` or returns `thrd_busy`. 146*8d67ca89SAndroid Build Coastguard Worker */ 147*8d67ca89SAndroid Build Coastguard Worker int mtx_trylock(mtx_t* _Nonnull __mutex) __INTRODUCED_IN(30); 148*8d67ca89SAndroid Build Coastguard Worker 149*8d67ca89SAndroid Build Coastguard Worker /** 150*8d67ca89SAndroid Build Coastguard Worker * Unlocks `__mutex`. 151*8d67ca89SAndroid Build Coastguard Worker */ 152*8d67ca89SAndroid Build Coastguard Worker int mtx_unlock(mtx_t* _Nonnull __mutex) __INTRODUCED_IN(30); 153*8d67ca89SAndroid Build Coastguard Worker 154*8d67ca89SAndroid Build Coastguard Worker 155*8d67ca89SAndroid Build Coastguard Worker 156*8d67ca89SAndroid Build Coastguard Worker /** 157*8d67ca89SAndroid Build Coastguard Worker * Creates a new thread running `__function(__arg)`, and sets `*__thrd` to 158*8d67ca89SAndroid Build Coastguard Worker * the new thread. 159*8d67ca89SAndroid Build Coastguard Worker */ 160*8d67ca89SAndroid Build Coastguard Worker int thrd_create(thrd_t* _Nonnull __thrd, thrd_start_t _Nonnull __function, void* _Nullable __arg) __INTRODUCED_IN(30); 161*8d67ca89SAndroid Build Coastguard Worker 162*8d67ca89SAndroid Build Coastguard Worker /** 163*8d67ca89SAndroid Build Coastguard Worker * Returns the `thrd_t` corresponding to the caller. 164*8d67ca89SAndroid Build Coastguard Worker */ 165*8d67ca89SAndroid Build Coastguard Worker thrd_t thrd_current(void) __INTRODUCED_IN(30); 166*8d67ca89SAndroid Build Coastguard Worker 167*8d67ca89SAndroid Build Coastguard Worker /** 168*8d67ca89SAndroid Build Coastguard Worker * Tells the OS to automatically dispose of `__thrd` when it exits. 169*8d67ca89SAndroid Build Coastguard Worker */ 170*8d67ca89SAndroid Build Coastguard Worker int thrd_detach(thrd_t __thrd) __INTRODUCED_IN(30); 171*8d67ca89SAndroid Build Coastguard Worker 172*8d67ca89SAndroid Build Coastguard Worker /** 173*8d67ca89SAndroid Build Coastguard Worker * Tests whether two threads are the same thread. 174*8d67ca89SAndroid Build Coastguard Worker */ 175*8d67ca89SAndroid Build Coastguard Worker int thrd_equal(thrd_t __lhs, thrd_t __rhs) __INTRODUCED_IN(30); 176*8d67ca89SAndroid Build Coastguard Worker 177*8d67ca89SAndroid Build Coastguard Worker /** 178*8d67ca89SAndroid Build Coastguard Worker * Terminates the calling thread, setting its result to `__result`. 179*8d67ca89SAndroid Build Coastguard Worker */ 180*8d67ca89SAndroid Build Coastguard Worker void thrd_exit(int __result) __noreturn __INTRODUCED_IN(30); 181*8d67ca89SAndroid Build Coastguard Worker 182*8d67ca89SAndroid Build Coastguard Worker /** 183*8d67ca89SAndroid Build Coastguard Worker * Blocks until `__thrd` terminates. If `__result` is not null, `*__result` 184*8d67ca89SAndroid Build Coastguard Worker * is set to the exiting thread's result. 185*8d67ca89SAndroid Build Coastguard Worker */ 186*8d67ca89SAndroid Build Coastguard Worker int thrd_join(thrd_t __thrd, int* _Nullable __result) __INTRODUCED_IN(30); 187*8d67ca89SAndroid Build Coastguard Worker 188*8d67ca89SAndroid Build Coastguard Worker /** 189*8d67ca89SAndroid Build Coastguard Worker * Blocks the caller for at least `__duration` unless a signal is delivered. 190*8d67ca89SAndroid Build Coastguard Worker * If a signal causes the sleep to end early and `__remaining` is not null, 191*8d67ca89SAndroid Build Coastguard Worker * `*__remaining` is set to the time remaining. 192*8d67ca89SAndroid Build Coastguard Worker * 193*8d67ca89SAndroid Build Coastguard Worker * Returns 0 on success, or -1 if a signal was delivered. 194*8d67ca89SAndroid Build Coastguard Worker */ 195*8d67ca89SAndroid Build Coastguard Worker int thrd_sleep(const struct timespec* _Nonnull __duration, struct timespec* _Nullable __remaining) __INTRODUCED_IN(30); 196*8d67ca89SAndroid Build Coastguard Worker 197*8d67ca89SAndroid Build Coastguard Worker /** 198*8d67ca89SAndroid Build Coastguard Worker * Request that other threads should be scheduled. 199*8d67ca89SAndroid Build Coastguard Worker */ 200*8d67ca89SAndroid Build Coastguard Worker void thrd_yield(void) __INTRODUCED_IN(30); 201*8d67ca89SAndroid Build Coastguard Worker 202*8d67ca89SAndroid Build Coastguard Worker 203*8d67ca89SAndroid Build Coastguard Worker 204*8d67ca89SAndroid Build Coastguard Worker /** 205*8d67ca89SAndroid Build Coastguard Worker * Creates a thread-specific storage key with the associated destructor (which 206*8d67ca89SAndroid Build Coastguard Worker * may be null). 207*8d67ca89SAndroid Build Coastguard Worker */ 208*8d67ca89SAndroid Build Coastguard Worker int tss_create(tss_t* _Nonnull __key, tss_dtor_t _Nullable __dtor) __INTRODUCED_IN(30); 209*8d67ca89SAndroid Build Coastguard Worker 210*8d67ca89SAndroid Build Coastguard Worker /** 211*8d67ca89SAndroid Build Coastguard Worker * Destroys a thread-specific storage key. 212*8d67ca89SAndroid Build Coastguard Worker */ 213*8d67ca89SAndroid Build Coastguard Worker void tss_delete(tss_t __key) __INTRODUCED_IN(30); 214*8d67ca89SAndroid Build Coastguard Worker 215*8d67ca89SAndroid Build Coastguard Worker /** 216*8d67ca89SAndroid Build Coastguard Worker * Returns the value for the current thread held in the thread-specific storage 217*8d67ca89SAndroid Build Coastguard Worker * identified by `__key`. 218*8d67ca89SAndroid Build Coastguard Worker */ 219*8d67ca89SAndroid Build Coastguard Worker void* _Nullable tss_get(tss_t __key) __INTRODUCED_IN(30); 220*8d67ca89SAndroid Build Coastguard Worker 221*8d67ca89SAndroid Build Coastguard Worker /** 222*8d67ca89SAndroid Build Coastguard Worker * Sets the current thread's value for the thread-specific storage identified 223*8d67ca89SAndroid Build Coastguard Worker * by `__key` to `__value`. 224*8d67ca89SAndroid Build Coastguard Worker */ 225*8d67ca89SAndroid Build Coastguard Worker int tss_set(tss_t __key, void* _Nonnull __value) __INTRODUCED_IN(30); 226*8d67ca89SAndroid Build Coastguard Worker 227*8d67ca89SAndroid Build Coastguard Worker #endif 228*8d67ca89SAndroid Build Coastguard Worker 229*8d67ca89SAndroid Build Coastguard Worker __END_DECLS 230*8d67ca89SAndroid Build Coastguard Worker 231*8d67ca89SAndroid Build Coastguard Worker #include <android/legacy_threads_inlines.h> 232