xref: /haiku/headers/private/kernel/lock.h (revision 89755088d790ff4fe36f8aa77dacb2bd15507108)
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