1cdc920a0Smrg/************************************************************************** 2cdc920a0Smrg * 3cdc920a0Smrg * Copyright 1999-2006 Brian Paul 4af69d88dSmrg * Copyright 2008 VMware, Inc. 5cdc920a0Smrg * All Rights Reserved. 6cdc920a0Smrg * 7cdc920a0Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8cdc920a0Smrg * copy of this software and associated documentation files (the "Software"), 9cdc920a0Smrg * to deal in the Software without restriction, including without limitation 10cdc920a0Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11cdc920a0Smrg * and/or sell copies of the Software, and to permit persons to whom the 12cdc920a0Smrg * Software is furnished to do so, subject to the following conditions: 13cdc920a0Smrg * 14cdc920a0Smrg * The above copyright notice and this permission notice shall be included 15cdc920a0Smrg * in all copies or substantial portions of the Software. 16cdc920a0Smrg * 17cdc920a0Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18cdc920a0Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19cdc920a0Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE. 24af69d88dSmrg * 25cdc920a0Smrg **************************************************************************/ 26cdc920a0Smrg 27cdc920a0Smrg 28cdc920a0Smrg/** 29cdc920a0Smrg * @file 30cdc920a0Smrg * 31cdc920a0Smrg * Thread, mutex, condition variable, barrier, semaphore and 32cdc920a0Smrg * thread-specific data functions. 33cdc920a0Smrg */ 34cdc920a0Smrg 35cdc920a0Smrg 36cdc920a0Smrg#ifndef OS_THREAD_H_ 37cdc920a0Smrg#define OS_THREAD_H_ 38cdc920a0Smrg 39cdc920a0Smrg 40cdc920a0Smrg#include "pipe/p_compiler.h" 41cdc920a0Smrg#include "util/u_debug.h" /* for assert */ 4201e04c3fSmrg#include "util/u_thread.h" 43cdc920a0Smrg 44cdc920a0Smrg 4501e04c3fSmrg#define pipe_mutex_assert_locked(mutex) \ 4601e04c3fSmrg __pipe_mutex_assert_locked(&(mutex)) 47cdc920a0Smrg 4801e04c3fSmrgstatic inline void 4901e04c3fSmrg__pipe_mutex_assert_locked(mtx_t *mutex) 50cdc920a0Smrg{ 5101e04c3fSmrg#ifdef DEBUG 5201e04c3fSmrg /* NOTE: this would not work for recursive mutexes, but 5301e04c3fSmrg * mtx_t doesn't support those 5401e04c3fSmrg */ 5501e04c3fSmrg int ret = mtx_trylock(mutex); 5601e04c3fSmrg assert(ret == thrd_busy); 5701e04c3fSmrg if (ret == thrd_success) 5801e04c3fSmrg mtx_unlock(mutex); 59af69d88dSmrg#else 6001e04c3fSmrg (void)mutex; 61af69d88dSmrg#endif 62cdc920a0Smrg} 63cdc920a0Smrg 64cdc920a0Smrg 65cdc920a0Smrg/* 66cdc920a0Smrg * Semaphores 67cdc920a0Smrg */ 68cdc920a0Smrg 69cdc920a0Smrgtypedef struct 70cdc920a0Smrg{ 7101e04c3fSmrg mtx_t mutex; 7201e04c3fSmrg cnd_t cond; 73cdc920a0Smrg int counter; 74cdc920a0Smrg} pipe_semaphore; 75cdc920a0Smrg 76cdc920a0Smrg 7701e04c3fSmrgstatic inline void 78cdc920a0Smrgpipe_semaphore_init(pipe_semaphore *sema, int init_val) 79cdc920a0Smrg{ 8001e04c3fSmrg (void) mtx_init(&sema->mutex, mtx_plain); 8101e04c3fSmrg cnd_init(&sema->cond); 82cdc920a0Smrg sema->counter = init_val; 83cdc920a0Smrg} 84cdc920a0Smrg 8501e04c3fSmrgstatic inline void 86cdc920a0Smrgpipe_semaphore_destroy(pipe_semaphore *sema) 87cdc920a0Smrg{ 8801e04c3fSmrg mtx_destroy(&sema->mutex); 8901e04c3fSmrg cnd_destroy(&sema->cond); 90cdc920a0Smrg} 91cdc920a0Smrg 92cdc920a0Smrg/** Signal/increment semaphore counter */ 9301e04c3fSmrgstatic inline void 94cdc920a0Smrgpipe_semaphore_signal(pipe_semaphore *sema) 95cdc920a0Smrg{ 9601e04c3fSmrg mtx_lock(&sema->mutex); 97cdc920a0Smrg sema->counter++; 9801e04c3fSmrg cnd_signal(&sema->cond); 9901e04c3fSmrg mtx_unlock(&sema->mutex); 100cdc920a0Smrg} 101cdc920a0Smrg 102cdc920a0Smrg/** Wait for semaphore counter to be greater than zero */ 10301e04c3fSmrgstatic inline void 104cdc920a0Smrgpipe_semaphore_wait(pipe_semaphore *sema) 105cdc920a0Smrg{ 10601e04c3fSmrg mtx_lock(&sema->mutex); 107cdc920a0Smrg while (sema->counter <= 0) { 10801e04c3fSmrg cnd_wait(&sema->cond, &sema->mutex); 109cdc920a0Smrg } 110cdc920a0Smrg sema->counter--; 11101e04c3fSmrg mtx_unlock(&sema->mutex); 112cdc920a0Smrg} 113cdc920a0Smrg 114cdc920a0Smrg 115cdc920a0Smrg 116cdc920a0Smrg/* 117cdc920a0Smrg * Thread-specific data. 118cdc920a0Smrg */ 119cdc920a0Smrg 120cdc920a0Smrgtypedef struct { 121af69d88dSmrg tss_t key; 122cdc920a0Smrg int initMagic; 123cdc920a0Smrg} pipe_tsd; 124cdc920a0Smrg 125cdc920a0Smrg 126cdc920a0Smrg#define PIPE_TSD_INIT_MAGIC 0xff8adc98 127cdc920a0Smrg 128cdc920a0Smrg 12901e04c3fSmrgstatic inline void 130cdc920a0Smrgpipe_tsd_init(pipe_tsd *tsd) 131cdc920a0Smrg{ 132af69d88dSmrg if (tss_create(&tsd->key, NULL/*free*/) != 0) { 133cdc920a0Smrg exit(-1); 134cdc920a0Smrg } 135cdc920a0Smrg tsd->initMagic = PIPE_TSD_INIT_MAGIC; 136cdc920a0Smrg} 137cdc920a0Smrg 13801e04c3fSmrgstatic inline void * 139cdc920a0Smrgpipe_tsd_get(pipe_tsd *tsd) 140cdc920a0Smrg{ 141cdc920a0Smrg if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) { 142cdc920a0Smrg pipe_tsd_init(tsd); 143cdc920a0Smrg } 144af69d88dSmrg return tss_get(tsd->key); 145cdc920a0Smrg} 146cdc920a0Smrg 14701e04c3fSmrgstatic inline void 148cdc920a0Smrgpipe_tsd_set(pipe_tsd *tsd, void *value) 149cdc920a0Smrg{ 150cdc920a0Smrg if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) { 151cdc920a0Smrg pipe_tsd_init(tsd); 152cdc920a0Smrg } 153af69d88dSmrg if (tss_set(tsd->key, value) != 0) { 154cdc920a0Smrg exit(-1); 155cdc920a0Smrg } 156cdc920a0Smrg} 157cdc920a0Smrg 158cdc920a0Smrg#endif /* OS_THREAD_H_ */ 159