1 /* 2 * Copyright 2002-2007, 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_lock(mutex *m); 65 extern void mutex_unlock(mutex *m); 66 67 extern status_t benaphore_init(benaphore *ben, const char *name); 68 extern void benaphore_destroy(benaphore *ben); 69 70 static inline status_t 71 benaphore_lock_etc(benaphore *ben, uint32 flags, bigtime_t timeout) 72 { 73 if (atomic_add(&ben->count, -1) <= 0) 74 return acquire_sem_etc(ben->sem, 1, flags, timeout); 75 76 return B_OK; 77 } 78 79 80 static inline status_t 81 benaphore_lock(benaphore *ben) 82 { 83 if (atomic_add(&ben->count, -1) <= 0) 84 return acquire_sem(ben->sem); 85 86 return B_OK; 87 } 88 89 90 static inline status_t 91 benaphore_unlock(benaphore *ben) 92 { 93 if (atomic_add(&ben->count, 1) < 0) 94 return release_sem(ben->sem); 95 96 return B_OK; 97 } 98 99 extern status_t rw_lock_init(rw_lock *lock, const char *name); 100 extern void rw_lock_destroy(rw_lock *lock); 101 extern status_t rw_lock_read_lock(rw_lock *lock); 102 extern status_t rw_lock_read_unlock(rw_lock *lock); 103 extern status_t rw_lock_write_lock(rw_lock *lock); 104 extern status_t rw_lock_write_unlock(rw_lock *lock); 105 106 #ifdef __cplusplus 107 } 108 #endif 109 110 #endif /* _KERNEL_LOCK_H */ 111