1/************************************************************************** 2 * 3 * Copyright 1999-2006 Brian Paul 4 * Copyright 2008 VMware, Inc. 5 * All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 * OTHER DEALINGS IN THE SOFTWARE. 24 * 25 **************************************************************************/ 26 27 28/** 29 * @file 30 * 31 * Thread, mutex, condition variable, barrier, semaphore and 32 * thread-specific data functions. 33 */ 34 35 36#ifndef OS_THREAD_H_ 37#define OS_THREAD_H_ 38 39 40#include "pipe/p_compiler.h" 41#include "util/u_debug.h" /* for assert */ 42#include "util/u_thread.h" 43 44 45#define pipe_mutex_assert_locked(mutex) \ 46 __pipe_mutex_assert_locked(&(mutex)) 47 48static inline void 49__pipe_mutex_assert_locked(mtx_t *mutex) 50{ 51#ifdef DEBUG 52 /* NOTE: this would not work for recursive mutexes, but 53 * mtx_t doesn't support those 54 */ 55 int ret = mtx_trylock(mutex); 56 assert(ret == thrd_busy); 57 if (ret == thrd_success) 58 mtx_unlock(mutex); 59#else 60 (void)mutex; 61#endif 62} 63 64 65/* 66 * Semaphores 67 */ 68 69typedef struct 70{ 71 mtx_t mutex; 72 cnd_t cond; 73 int counter; 74} pipe_semaphore; 75 76 77static inline void 78pipe_semaphore_init(pipe_semaphore *sema, int init_val) 79{ 80 (void) mtx_init(&sema->mutex, mtx_plain); 81 cnd_init(&sema->cond); 82 sema->counter = init_val; 83} 84 85static inline void 86pipe_semaphore_destroy(pipe_semaphore *sema) 87{ 88 mtx_destroy(&sema->mutex); 89 cnd_destroy(&sema->cond); 90} 91 92/** Signal/increment semaphore counter */ 93static inline void 94pipe_semaphore_signal(pipe_semaphore *sema) 95{ 96 mtx_lock(&sema->mutex); 97 sema->counter++; 98 cnd_signal(&sema->cond); 99 mtx_unlock(&sema->mutex); 100} 101 102/** Wait for semaphore counter to be greater than zero */ 103static inline void 104pipe_semaphore_wait(pipe_semaphore *sema) 105{ 106 mtx_lock(&sema->mutex); 107 while (sema->counter <= 0) { 108 cnd_wait(&sema->cond, &sema->mutex); 109 } 110 sema->counter--; 111 mtx_unlock(&sema->mutex); 112} 113 114#endif /* OS_THREAD_H_ */ 115