1 /* 2 * Copyright 2002-2004, 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 #ifdef DEBUG 43 # include <thread.h> 44 #endif 45 #define ASSERT_LOCKED_RECURSIVE(r) { ASSERT(thread_get_current_thread_id() == (r)->holder); } 46 #define ASSERT_LOCKED_MUTEX(m) { ASSERT(thread_get_current_thread_id() == (m)->holder); } 47 48 49 #ifdef __cplusplus 50 extern "C" { 51 #endif 52 53 extern status_t recursive_lock_init(recursive_lock *lock, const char *name); 54 extern void recursive_lock_destroy(recursive_lock *lock); 55 extern bool recursive_lock_lock(recursive_lock *lock); 56 extern bool recursive_lock_unlock(recursive_lock *lock); 57 extern int recursive_lock_get_recursion(recursive_lock *lock); 58 59 extern status_t mutex_init(mutex *m, const char *name); 60 extern void mutex_destroy(mutex *m); 61 extern void mutex_lock(mutex *m); 62 extern void mutex_unlock(mutex *m); 63 64 extern status_t benaphore_init(benaphore *ben, const char *name); 65 extern void benaphore_destroy(benaphore *ben); 66 67 static inline status_t 68 benaphore_lock_etc(benaphore *ben, uint32 flags, bigtime_t timeout) 69 { 70 if (atomic_add(&ben->count, -1) <= 0) 71 return acquire_sem_etc(ben->sem, 1, flags, timeout); 72 73 return B_OK; 74 } 75 76 77 static inline status_t 78 benaphore_lock(benaphore *ben) 79 { 80 if (atomic_add(&ben->count, -1) <= 0) 81 return acquire_sem(ben->sem); 82 83 return B_OK; 84 } 85 86 87 static inline status_t 88 benaphore_unlock(benaphore *ben) 89 { 90 if (atomic_add(&ben->count, 1) < 0) 91 return release_sem(ben->sem); 92 93 return B_OK; 94 } 95 96 extern status_t rw_lock_init(rw_lock *lock, const char *name); 97 extern void rw_lock_destroy(rw_lock *lock); 98 extern status_t rw_lock_read_lock(rw_lock *lock); 99 extern status_t rw_lock_read_unlock(rw_lock *lock); 100 extern status_t rw_lock_write_lock(rw_lock *lock); 101 extern status_t rw_lock_write_unlock(rw_lock *lock); 102 103 #ifdef __cplusplus 104 } 105 #endif 106 107 #endif /* _KERNEL_LOCK_H */ 108