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