1848b8605Smrg/************************************************************************** 2848b8605Smrg * 3848b8605Smrg * Copyright 1999-2006 Brian Paul 4848b8605Smrg * Copyright 2008 VMware, Inc. 5848b8605Smrg * All Rights Reserved. 6848b8605Smrg * 7848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8848b8605Smrg * copy of this software and associated documentation files (the "Software"), 9848b8605Smrg * to deal in the Software without restriction, including without limitation 10848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 12848b8605Smrg * Software is furnished to do so, subject to the following conditions: 13848b8605Smrg * 14848b8605Smrg * The above copyright notice and this permission notice shall be included 15848b8605Smrg * in all copies or substantial portions of the Software. 16848b8605Smrg * 17848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 24848b8605Smrg * 25848b8605Smrg **************************************************************************/ 26848b8605Smrg 27848b8605Smrg 28848b8605Smrg/** 29848b8605Smrg * @file 30848b8605Smrg * 31848b8605Smrg * Thread, mutex, condition variable, barrier, semaphore and 32848b8605Smrg * thread-specific data functions. 33848b8605Smrg */ 34848b8605Smrg 35848b8605Smrg 36848b8605Smrg#ifndef OS_THREAD_H_ 37848b8605Smrg#define OS_THREAD_H_ 38848b8605Smrg 39848b8605Smrg 40848b8605Smrg#include "pipe/p_compiler.h" 41848b8605Smrg#include "util/u_debug.h" /* for assert */ 42b8e80941Smrg#include "util/u_thread.h" 43848b8605Smrg 44848b8605Smrg 45b8e80941Smrg#define pipe_mutex_assert_locked(mutex) \ 46b8e80941Smrg __pipe_mutex_assert_locked(&(mutex)) 47848b8605Smrg 48b8e80941Smrgstatic inline void 49b8e80941Smrg__pipe_mutex_assert_locked(mtx_t *mutex) 50848b8605Smrg{ 51b8e80941Smrg#ifdef DEBUG 52b8e80941Smrg /* NOTE: this would not work for recursive mutexes, but 53b8e80941Smrg * mtx_t doesn't support those 54b8e80941Smrg */ 55b8e80941Smrg int ret = mtx_trylock(mutex); 56b8e80941Smrg assert(ret == thrd_busy); 57b8e80941Smrg if (ret == thrd_success) 58b8e80941Smrg mtx_unlock(mutex); 59848b8605Smrg#else 60b8e80941Smrg (void)mutex; 61848b8605Smrg#endif 62848b8605Smrg} 63848b8605Smrg 64848b8605Smrg 65848b8605Smrg/* 66848b8605Smrg * Semaphores 67848b8605Smrg */ 68848b8605Smrg 69848b8605Smrgtypedef struct 70848b8605Smrg{ 71b8e80941Smrg mtx_t mutex; 72b8e80941Smrg cnd_t cond; 73848b8605Smrg int counter; 74848b8605Smrg} pipe_semaphore; 75848b8605Smrg 76848b8605Smrg 77b8e80941Smrgstatic inline void 78848b8605Smrgpipe_semaphore_init(pipe_semaphore *sema, int init_val) 79848b8605Smrg{ 80b8e80941Smrg (void) mtx_init(&sema->mutex, mtx_plain); 81b8e80941Smrg cnd_init(&sema->cond); 82848b8605Smrg sema->counter = init_val; 83848b8605Smrg} 84848b8605Smrg 85b8e80941Smrgstatic inline void 86848b8605Smrgpipe_semaphore_destroy(pipe_semaphore *sema) 87848b8605Smrg{ 88b8e80941Smrg mtx_destroy(&sema->mutex); 89b8e80941Smrg cnd_destroy(&sema->cond); 90848b8605Smrg} 91848b8605Smrg 92848b8605Smrg/** Signal/increment semaphore counter */ 93b8e80941Smrgstatic inline void 94848b8605Smrgpipe_semaphore_signal(pipe_semaphore *sema) 95848b8605Smrg{ 96b8e80941Smrg mtx_lock(&sema->mutex); 97848b8605Smrg sema->counter++; 98b8e80941Smrg cnd_signal(&sema->cond); 99b8e80941Smrg mtx_unlock(&sema->mutex); 100848b8605Smrg} 101848b8605Smrg 102848b8605Smrg/** Wait for semaphore counter to be greater than zero */ 103b8e80941Smrgstatic inline void 104848b8605Smrgpipe_semaphore_wait(pipe_semaphore *sema) 105848b8605Smrg{ 106b8e80941Smrg mtx_lock(&sema->mutex); 107848b8605Smrg while (sema->counter <= 0) { 108b8e80941Smrg cnd_wait(&sema->cond, &sema->mutex); 109848b8605Smrg } 110848b8605Smrg sema->counter--; 111b8e80941Smrg mtx_unlock(&sema->mutex); 112848b8605Smrg} 113848b8605Smrg 114848b8605Smrg 115848b8605Smrg 116848b8605Smrg/* 117848b8605Smrg * Thread-specific data. 118848b8605Smrg */ 119848b8605Smrg 120848b8605Smrgtypedef struct { 121848b8605Smrg tss_t key; 122848b8605Smrg int initMagic; 123848b8605Smrg} pipe_tsd; 124848b8605Smrg 125848b8605Smrg 126848b8605Smrg#define PIPE_TSD_INIT_MAGIC 0xff8adc98 127848b8605Smrg 128848b8605Smrg 129b8e80941Smrgstatic inline void 130848b8605Smrgpipe_tsd_init(pipe_tsd *tsd) 131848b8605Smrg{ 132848b8605Smrg if (tss_create(&tsd->key, NULL/*free*/) != 0) { 133848b8605Smrg exit(-1); 134848b8605Smrg } 135848b8605Smrg tsd->initMagic = PIPE_TSD_INIT_MAGIC; 136848b8605Smrg} 137848b8605Smrg 138b8e80941Smrgstatic inline void * 139848b8605Smrgpipe_tsd_get(pipe_tsd *tsd) 140848b8605Smrg{ 141848b8605Smrg if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) { 142848b8605Smrg pipe_tsd_init(tsd); 143848b8605Smrg } 144848b8605Smrg return tss_get(tsd->key); 145848b8605Smrg} 146848b8605Smrg 147b8e80941Smrgstatic inline void 148848b8605Smrgpipe_tsd_set(pipe_tsd *tsd, void *value) 149848b8605Smrg{ 150848b8605Smrg if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) { 151848b8605Smrg pipe_tsd_init(tsd); 152848b8605Smrg } 153848b8605Smrg if (tss_set(tsd->key, value) != 0) { 154848b8605Smrg exit(-1); 155848b8605Smrg } 156848b8605Smrg} 157848b8605Smrg 158848b8605Smrg 159848b8605Smrg 160b8e80941Smrg/* 161b8e80941Smrg * Thread statistics. 162b8e80941Smrg */ 163b8e80941Smrg 164b8e80941Smrg/* Return the time of the current thread's CPU time clock. */ 165b8e80941Smrgstatic inline int64_t 166b8e80941Smrgpipe_current_thread_get_time_nano(void) 167b8e80941Smrg{ 168b8e80941Smrg#if defined(HAVE_PTHREAD) 169b8e80941Smrg return u_thread_get_time_nano(pthread_self()); 170b8e80941Smrg#else 171b8e80941Smrg return 0; 172b8e80941Smrg#endif 173b8e80941Smrg} 174b8e80941Smrg 175848b8605Smrg#endif /* OS_THREAD_H_ */ 176