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