1/*
2 * Copyright 2009, Colin G��nther, coling@gmx.de.
3 * Copyright 2007, Hugo Santos. All Rights Reserved.
4 * Distributed under the terms of the MIT License.
5 */
6#ifndef _FBSD_COMPAT_SYS_MUTEX_H_
7#define _FBSD_COMPAT_SYS_MUTEX_H_
8
9
10#include <sys/haiku-module.h>
11#include <kernel/int.h>
12
13#include <sys/queue.h>
14#include <sys/_mutex.h>
15#include <sys/pcpu.h>
16#include <machine/atomic.h>
17#include <machine/cpufunc.h>
18
19
20#define MA_OWNED		0x1
21#define MA_NOTOWNED		0x2
22#define MA_RECURSED		0x4
23#define MA_NOTRECURSED	0x8
24
25#define mtx_assert(mtx, what)
26
27#define	MTX_DEF			0x00000000
28#define MTX_SPIN		0x00000001
29#define MTX_RECURSE		0x00000004
30#define MTX_QUIET		0x00040000
31#define MTX_DUPOK		0x00400000
32
33
34#define MTX_NETWORK_LOCK	"network driver"
35
36
37/* on FreeBSD these are different functions */
38#define	mtx_lock_spin(x) 	mtx_lock(x)
39#define	mtx_unlock_spin(x)	mtx_unlock(x)
40
41
42extern struct mtx Giant;
43
44
45void mtx_init(struct mtx*, const char*, const char*, int);
46void mtx_sysinit(void *arg);
47void mtx_destroy(struct mtx*);
48
49
50static inline void
51mtx_lock(struct mtx* mutex)
52{
53	if (mutex->type == MTX_DEF) {
54		mutex_lock(&mutex->u.mutex.lock);
55		mutex->u.mutex.owner = find_thread(NULL);
56	} else if (mutex->type == MTX_RECURSE) {
57		recursive_lock_lock(&mutex->u.recursive);
58	} else if (mutex->type == MTX_SPIN) {
59		cpu_status status = disable_interrupts();
60		acquire_spinlock(&mutex->u.spinlock.lock);
61		mutex->u.spinlock.state = status;
62	}
63}
64
65
66static inline int
67mtx_trylock(struct mtx* mutex)
68{
69	if (mutex->type == MTX_DEF) {
70		if (mutex_trylock(&mutex->u.mutex.lock) != B_OK)
71			return 0;
72		mutex->u.mutex.owner = find_thread(NULL);
73		return 1;
74	} else if (mutex->type == MTX_RECURSE) {
75		if (recursive_lock_trylock(&mutex->u.recursive) != B_OK)
76			return 0;
77		return 1;
78	} else if (mutex->type == MTX_SPIN) {
79		return 0;
80	}
81	return 0;
82}
83
84
85static inline void
86mtx_unlock(struct mtx* mutex)
87{
88	if (mutex->type == MTX_DEF) {
89		mutex->u.mutex.owner = -1;
90		mutex_unlock(&mutex->u.mutex.lock);
91	} else if (mutex->type == MTX_RECURSE) {
92		recursive_lock_unlock(&mutex->u.recursive);
93	} else if (mutex->type == MTX_SPIN) {
94		cpu_status status = mutex->u.spinlock.state;
95		release_spinlock(&mutex->u.spinlock.lock);
96		restore_interrupts(status);
97	}
98}
99
100
101static inline int
102mtx_initialized(struct mtx* mutex)
103{
104	/* TODO */
105	return 1;
106}
107
108
109static inline int
110mtx_owned(struct mtx* mutex)
111{
112	if (mutex->type == MTX_DEF)
113		return mutex->u.mutex.owner == find_thread(NULL);
114	if (mutex->type == MTX_RECURSE) {
115#if KDEBUG
116		return mutex->u.recursive.lock.holder == find_thread(NULL);
117#else
118		return mutex->u.recursive.holder == find_thread(NULL);
119#endif
120	}
121
122	return 0;
123}
124
125
126struct mtx_args {
127	void		*ma_mtx;
128	const char 	*ma_desc;
129	int		 ma_opts;
130};
131
132#define	MTX_SYSINIT(name, mtx, desc, opts) \
133	static struct mtx_args name##_args = {	\
134		(mtx), \
135		(desc), \
136		(opts), \
137	}; \
138	SYSINIT(name##_mtx, SI_SUB_LOCK, SI_ORDER_MIDDLE, \
139		mtx_sysinit, &name##_args); \
140	SYSUNINIT(name##_mtx, SI_SUB_LOCK, SI_ORDER_MIDDLE, \
141	    (system_init_func_t)mtx_destroy, (void*)mtx)
142
143
144#endif	/* _FBSD_COMPAT_SYS_MUTEX_H_ */
145