1/*
2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de.
4 * Distributed under the terms of the MIT License.
5 *
6 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
7 * Distributed under the terms of the NewOS License.
8 */
9#ifndef _FSSH_KERNEL_LOCK_H
10#define _FSSH_KERNEL_LOCK_H
11
12
13#include <fssh_auto_locker.h>
14#include <fssh_errors.h>
15#include <fssh_os.h>
16
17
18typedef struct fssh_mutex {
19	fssh_sem_id		sem;
20	fssh_thread_id	holder;
21} fssh_mutex;
22
23#define FSSH_MUTEX_FLAG_CLONE_NAME	0x1
24
25
26typedef struct fssh_recursive_lock {
27	fssh_sem_id		sem;
28	fssh_thread_id	holder;
29	int				recursion;
30} fssh_recursive_lock;
31
32
33typedef struct fssh_rw_lock {
34	fssh_sem_id		sem;
35	fssh_thread_id	holder;
36	int32_t			count;
37} fssh_rw_lock;
38
39#define FSSH_RW_LOCK_FLAG_CLONE_NAME	0x1
40
41#define FSSH_ASSERT_LOCKED_RECURSIVE(r)
42#define FSSH_ASSERT_LOCKED_MUTEX(m)
43#define FSSH_ASSERT_WRITE_LOCKED_RW_LOCK(l)
44#define FSSH_ASSERT_READ_LOCKED_RW_LOCK(l)
45
46// static initializers
47#define FSSH_MUTEX_INITIALIZER(name)			{ name, NULL, 0, 0 }
48#define FSSH_RECURSIVE_LOCK_INITIALIZER(name)	{ FSSH_MUTEX_INITIALIZER(name), -1, 0 }
49#define FSSH_RW_LOCK_INITIALIZER(name)			{ name, NULL, -1, 0, 0, 0 }
50
51#ifdef __cplusplus
52extern "C" {
53#endif
54
55extern void	fssh_recursive_lock_init(fssh_recursive_lock *lock, const char *name);
56	// name is *not* cloned nor freed in recursive_lock_destroy()
57extern void fssh_recursive_lock_init_etc(fssh_recursive_lock *lock, const char *name,
58	uint32_t flags);
59extern void fssh_recursive_lock_destroy(fssh_recursive_lock *lock);
60extern fssh_status_t fssh_recursive_lock_lock(fssh_recursive_lock *lock);
61extern fssh_status_t fssh_recursive_lock_trylock(fssh_recursive_lock *lock);
62extern void fssh_recursive_lock_unlock(fssh_recursive_lock *lock);
63extern int32_t fssh_recursive_lock_get_recursion(fssh_recursive_lock *lock);
64extern void fssh_recursive_lock_transfer_lock(fssh_recursive_lock *lock, fssh_thread_id thread);
65
66extern void fssh_rw_lock_init(fssh_rw_lock* lock, const char* name);
67	// name is *not* cloned nor freed in rw_lock_destroy()
68extern void fssh_rw_lock_init_etc(fssh_rw_lock* lock, const char* name, uint32_t flags);
69extern void fssh_rw_lock_destroy(fssh_rw_lock* lock);
70extern fssh_status_t fssh_rw_lock_read_lock(fssh_rw_lock* lock);
71extern fssh_status_t fssh_rw_lock_read_unlock(fssh_rw_lock* lock);
72extern fssh_status_t fssh_rw_lock_write_lock(fssh_rw_lock* lock);
73extern fssh_status_t fssh_rw_lock_write_unlock(fssh_rw_lock* lock);
74
75extern void fssh_mutex_init(fssh_mutex* lock, const char* name);
76	// name is *not* cloned nor freed in mutex_destroy()
77extern void fssh_mutex_init_etc(fssh_mutex* lock, const char* name, uint32_t flags);
78extern void fssh_mutex_destroy(fssh_mutex* lock);
79extern fssh_status_t fssh_mutex_lock(fssh_mutex* lock);
80extern fssh_status_t fssh_mutex_trylock(fssh_mutex* lock);
81extern void fssh_mutex_unlock(fssh_mutex* lock);
82extern void fssh_mutex_transfer_lock(fssh_mutex* lock, fssh_thread_id thread);
83
84#ifdef __cplusplus
85}
86
87namespace FSShell {
88
89// MutexLocking
90class MutexLocking {
91public:
92	inline bool Lock(fssh_mutex *lockable)
93	{
94		return fssh_mutex_lock(lockable) == FSSH_B_OK;
95	}
96
97	inline void Unlock(fssh_mutex *lockable)
98	{
99		fssh_mutex_unlock(lockable);
100	}
101};
102
103// MutexLocker
104typedef AutoLocker<fssh_mutex, MutexLocking> MutexLocker;
105
106// RecursiveLockLocking
107class RecursiveLockLocking {
108public:
109	inline bool Lock(fssh_recursive_lock *lockable)
110	{
111		return fssh_recursive_lock_lock(lockable) == FSSH_B_OK;
112	}
113
114	inline void Unlock(fssh_recursive_lock *lockable)
115	{
116		fssh_recursive_lock_unlock(lockable);
117	}
118};
119
120// RecursiveLocker
121typedef AutoLocker<fssh_recursive_lock, RecursiveLockLocking> RecursiveLocker;
122
123class ReadWriteLockReadLocking {
124public:
125	inline bool Lock(fssh_rw_lock *lockable)
126	{
127		return fssh_rw_lock_read_lock(lockable) == FSSH_B_OK;
128	}
129
130	inline void Unlock(fssh_rw_lock *lockable)
131	{
132		fssh_rw_lock_read_unlock(lockable);
133	}
134};
135
136class ReadWriteLockWriteLocking {
137public:
138	inline bool Lock(fssh_rw_lock *lockable)
139	{
140		return fssh_rw_lock_write_lock(lockable) == FSSH_B_OK;
141	}
142
143	inline void Unlock(fssh_rw_lock *lockable)
144	{
145		fssh_rw_lock_write_unlock(lockable);
146	}
147};
148
149typedef AutoLocker<fssh_rw_lock, ReadWriteLockReadLocking> ReadLocker;
150typedef AutoLocker<fssh_rw_lock, ReadWriteLockWriteLocking> WriteLocker;
151
152}	// namespace FSShell
153
154using FSShell::AutoLocker;
155using FSShell::MutexLocker;
156using FSShell::RecursiveLocker;
157using FSShell::ReadLocker;
158using FSShell::WriteLocker;
159
160#endif	// __cplusplus
161
162#endif	/* _FSSH_KERNEL_LOCK_H */
163