1 /* 2 * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 * 5 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. 6 * Distributed under the terms of the NewOS License. 7 */ 8 #ifndef _KERNEL_LOCK_H 9 #define _KERNEL_LOCK_H 10 11 12 #include <OS.h> 13 #include <debug.h> 14 15 typedef struct recursive_lock { 16 sem_id sem; 17 thread_id holder; 18 int recursion; 19 } recursive_lock; 20 21 typedef struct mutex { 22 sem_id sem; 23 thread_id holder; 24 } mutex; 25 26 typedef struct benaphore { 27 sem_id sem; 28 int32 count; 29 } benaphore; 30 31 // Note: this is currently a trivial r/w lock implementation 32 // it will be replaced with something better later - this 33 // or a similar API will be made publically available at this point. 34 typedef struct rw_lock { 35 sem_id sem; 36 int32 count; 37 benaphore writeLock; 38 } rw_lock; 39 40 #define RW_MAX_READERS 1000000 41 42 #if 0 && KDEBUG // XXX disable this for now, it causes problems when including thread.h here 43 # include <thread.h> 44 #define ASSERT_LOCKED_RECURSIVE(r) { ASSERT(thread_get_current_thread_id() == (r)->holder); } 45 #define ASSERT_LOCKED_MUTEX(m) { ASSERT(thread_get_current_thread_id() == (m)->holder); } 46 #else 47 #define ASSERT_LOCKED_RECURSIVE(r) 48 #define ASSERT_LOCKED_MUTEX(m) 49 #endif 50 51 52 #ifdef __cplusplus 53 extern "C" { 54 #endif 55 56 extern status_t recursive_lock_init(recursive_lock *lock, const char *name); 57 extern void recursive_lock_destroy(recursive_lock *lock); 58 extern status_t recursive_lock_lock(recursive_lock *lock); 59 extern void recursive_lock_unlock(recursive_lock *lock); 60 extern int32 recursive_lock_get_recursion(recursive_lock *lock); 61 62 extern status_t mutex_init(mutex *m, const char *name); 63 extern void mutex_destroy(mutex *m); 64 extern status_t mutex_trylock(mutex *mutex); 65 extern status_t mutex_lock(mutex *m); 66 extern void mutex_unlock(mutex *m); 67 68 extern status_t benaphore_init(benaphore *ben, const char *name); 69 extern void benaphore_destroy(benaphore *ben); 70 71 static inline status_t 72 benaphore_lock_etc(benaphore *ben, uint32 flags, bigtime_t timeout) 73 { 74 if (atomic_add(&ben->count, -1) <= 0) 75 return acquire_sem_etc(ben->sem, 1, flags, timeout); 76 77 return B_OK; 78 } 79 80 81 static inline status_t 82 benaphore_lock(benaphore *ben) 83 { 84 #ifdef KDEBUG 85 return acquire_sem(ben->sem); 86 #else 87 if (atomic_add(&ben->count, -1) <= 0) 88 return acquire_sem(ben->sem); 89 90 return B_OK; 91 #endif 92 } 93 94 95 static inline status_t 96 benaphore_unlock(benaphore *ben) 97 { 98 #ifdef KDEBUG 99 return release_sem(ben->sem); 100 #else 101 if (atomic_add(&ben->count, 1) < 0) 102 return release_sem(ben->sem); 103 104 return B_OK; 105 #endif 106 } 107 108 extern status_t rw_lock_init(rw_lock *lock, const char *name); 109 extern void rw_lock_destroy(rw_lock *lock); 110 extern status_t rw_lock_read_lock(rw_lock *lock); 111 extern status_t rw_lock_read_unlock(rw_lock *lock); 112 extern status_t rw_lock_write_lock(rw_lock *lock); 113 extern status_t rw_lock_write_unlock(rw_lock *lock); 114 115 #ifdef __cplusplus 116 } 117 #endif 118 119 #endif /* _KERNEL_LOCK_H */ 120