1f9a21cf8SJérôme Duval/*
2f9a21cf8SJérôme Duval * Copyright 2009, Colin G��nther, coling@gmx.de.
3f9a21cf8SJérôme Duval * Copyright 2007, Hugo Santos. All Rights Reserved.
4f9a21cf8SJérôme Duval * Distributed under the terms of the MIT License.
5f9a21cf8SJérôme Duval */
6f9a21cf8SJérôme Duval#ifndef _FBSD_COMPAT_SYS_MUTEX_H_
7f9a21cf8SJérôme Duval#define _FBSD_COMPAT_SYS_MUTEX_H_
8f9a21cf8SJérôme Duval
9f9a21cf8SJérôme Duval
10f9a21cf8SJérôme Duval#include <sys/haiku-module.h>
118267c193SAugustin Cavalier#include <kernel/int.h>
12f9a21cf8SJérôme Duval
13f9a21cf8SJérôme Duval#include <sys/queue.h>
14f9a21cf8SJérôme Duval#include <sys/_mutex.h>
15f9a21cf8SJérôme Duval#include <sys/pcpu.h>
16f9a21cf8SJérôme Duval#include <machine/atomic.h>
17f9a21cf8SJérôme Duval#include <machine/cpufunc.h>
18f9a21cf8SJérôme Duval
19f9a21cf8SJérôme Duval
20f9a21cf8SJérôme Duval#define MA_OWNED		0x1
21f9a21cf8SJérôme Duval#define MA_NOTOWNED		0x2
22f9a21cf8SJérôme Duval#define MA_RECURSED		0x4
23f9a21cf8SJérôme Duval#define MA_NOTRECURSED	0x8
24f9a21cf8SJérôme Duval
25f9a21cf8SJérôme Duval#define mtx_assert(mtx, what)
26f9a21cf8SJérôme Duval
278267c193SAugustin Cavalier#define	MTX_DEF			0x00000000
288267c193SAugustin Cavalier#define MTX_SPIN		0x00000001
298267c193SAugustin Cavalier#define MTX_RECURSE		0x00000004
308267c193SAugustin Cavalier#define MTX_QUIET		0x00040000
318267c193SAugustin Cavalier#define MTX_DUPOK		0x00400000
32f9a21cf8SJérôme Duval
33f9a21cf8SJérôme Duval
34f9a21cf8SJérôme Duval#define MTX_NETWORK_LOCK	"network driver"
35f9a21cf8SJérôme Duval
368267c193SAugustin Cavalier
378267c193SAugustin Cavalier/* on FreeBSD these are different functions */
388267c193SAugustin Cavalier#define	mtx_lock_spin(x) 	mtx_lock(x)
398267c193SAugustin Cavalier#define	mtx_unlock_spin(x)	mtx_unlock(x)
40f9a21cf8SJérôme Duval
41f9a21cf8SJérôme Duval
42f9a21cf8SJérôme Duvalextern struct mtx Giant;
43f9a21cf8SJérôme Duval
44f9a21cf8SJérôme Duval
45f9a21cf8SJérôme Duvalvoid mtx_init(struct mtx*, const char*, const char*, int);
46800e9d66SAugustin Cavaliervoid mtx_sysinit(void *arg);
47f9a21cf8SJérôme Duvalvoid mtx_destroy(struct mtx*);
48f9a21cf8SJérôme Duval
49f9a21cf8SJérôme Duval
50f9a21cf8SJérôme Duvalstatic inline void
51f9a21cf8SJérôme Duvalmtx_lock(struct mtx* mutex)
52f9a21cf8SJérôme Duval{
53f9a21cf8SJérôme Duval	if (mutex->type == MTX_DEF) {
54f9a21cf8SJérôme Duval		mutex_lock(&mutex->u.mutex.lock);
55f9a21cf8SJérôme Duval		mutex->u.mutex.owner = find_thread(NULL);
568267c193SAugustin Cavalier	} else if (mutex->type == MTX_RECURSE) {
57f9a21cf8SJérôme Duval		recursive_lock_lock(&mutex->u.recursive);
588267c193SAugustin Cavalier	} else if (mutex->type == MTX_SPIN) {
598267c193SAugustin Cavalier		cpu_status status = disable_interrupts();
608267c193SAugustin Cavalier		acquire_spinlock(&mutex->u.spinlock.lock);
618267c193SAugustin Cavalier		mutex->u.spinlock.state = status;
628267c193SAugustin Cavalier	}
63f9a21cf8SJérôme Duval}
64f9a21cf8SJérôme Duval
65f9a21cf8SJérôme Duval
6694064605SAugustin Cavalierstatic inline int
6794064605SAugustin Cavaliermtx_trylock(struct mtx* mutex)
6894064605SAugustin Cavalier{
6994064605SAugustin Cavalier	if (mutex->type == MTX_DEF) {
7094064605SAugustin Cavalier		if (mutex_trylock(&mutex->u.mutex.lock) != B_OK)
7194064605SAugustin Cavalier			return 0;
7294064605SAugustin Cavalier		mutex->u.mutex.owner = find_thread(NULL);
7394064605SAugustin Cavalier		return 1;
7494064605SAugustin Cavalier	} else if (mutex->type == MTX_RECURSE) {
7594064605SAugustin Cavalier		if (recursive_lock_trylock(&mutex->u.recursive) != B_OK)
7694064605SAugustin Cavalier			return 0;
7794064605SAugustin Cavalier		return 1;
788267c193SAugustin Cavalier	} else if (mutex->type == MTX_SPIN) {
798267c193SAugustin Cavalier		return 0;
8094064605SAugustin Cavalier	}
814e1ffc12SAugustin Cavalier	return 0;
8294064605SAugustin Cavalier}
8394064605SAugustin Cavalier
8494064605SAugustin Cavalier
85f9a21cf8SJérôme Duvalstatic inline void
86f9a21cf8SJérôme Duvalmtx_unlock(struct mtx* mutex)
87f9a21cf8SJérôme Duval{
88f9a21cf8SJérôme Duval	if (mutex->type == MTX_DEF) {
89f9a21cf8SJérôme Duval		mutex->u.mutex.owner = -1;
90f9a21cf8SJérôme Duval		mutex_unlock(&mutex->u.mutex.lock);
918267c193SAugustin Cavalier	} else if (mutex->type == MTX_RECURSE) {
92f9a21cf8SJérôme Duval		recursive_lock_unlock(&mutex->u.recursive);
938267c193SAugustin Cavalier	} else if (mutex->type == MTX_SPIN) {
948267c193SAugustin Cavalier		cpu_status status = mutex->u.spinlock.state;
958267c193SAugustin Cavalier		release_spinlock(&mutex->u.spinlock.lock);
968267c193SAugustin Cavalier		restore_interrupts(status);
978267c193SAugustin Cavalier	}
98f9a21cf8SJérôme Duval}
99f9a21cf8SJérôme Duval
100f9a21cf8SJérôme Duval
101f9a21cf8SJérôme Duvalstatic inline int
102f9a21cf8SJérôme Duvalmtx_initialized(struct mtx* mutex)
103f9a21cf8SJérôme Duval{
104f9a21cf8SJérôme Duval	/* TODO */
105f9a21cf8SJérôme Duval	return 1;
106f9a21cf8SJérôme Duval}
107f9a21cf8SJérôme Duval
108f9a21cf8SJérôme Duval
109f9a21cf8SJérôme Duvalstatic inline int
110f9a21cf8SJérôme Duvalmtx_owned(struct mtx* mutex)
111f9a21cf8SJérôme Duval{
112f9a21cf8SJérôme Duval	if (mutex->type == MTX_DEF)
113f9a21cf8SJérôme Duval		return mutex->u.mutex.owner == find_thread(NULL);
114f9a21cf8SJérôme Duval	if (mutex->type == MTX_RECURSE) {
115f9a21cf8SJérôme Duval#if KDEBUG
116f9a21cf8SJérôme Duval		return mutex->u.recursive.lock.holder == find_thread(NULL);
117f9a21cf8SJérôme Duval#else
118f9a21cf8SJérôme Duval		return mutex->u.recursive.holder == find_thread(NULL);
119f9a21cf8SJérôme Duval#endif
120f9a21cf8SJérôme Duval	}
121f9a21cf8SJérôme Duval
122f9a21cf8SJérôme Duval	return 0;
123f9a21cf8SJérôme Duval}
124f9a21cf8SJérôme Duval
125f9a21cf8SJérôme Duval
126800e9d66SAugustin Cavalierstruct mtx_args {
127800e9d66SAugustin Cavalier	void		*ma_mtx;
128800e9d66SAugustin Cavalier	const char 	*ma_desc;
129800e9d66SAugustin Cavalier	int		 ma_opts;
130800e9d66SAugustin Cavalier};
131800e9d66SAugustin Cavalier
1323d4f7f0fSAugustin Cavalier#define	MTX_SYSINIT(name, mtx, desc, opts) \
1333d4f7f0fSAugustin Cavalier	static struct mtx_args name##_args = {	\
1343d4f7f0fSAugustin Cavalier		(mtx), \
1353d4f7f0fSAugustin Cavalier		(desc), \
1363d4f7f0fSAugustin Cavalier		(opts), \
1373d4f7f0fSAugustin Cavalier	}; \
1383d4f7f0fSAugustin Cavalier	SYSINIT(name##_mtx, SI_SUB_LOCK, SI_ORDER_MIDDLE, \
1393d4f7f0fSAugustin Cavalier		mtx_sysinit, &name##_args); \
1403d4f7f0fSAugustin Cavalier	SYSUNINIT(name##_mtx, SI_SUB_LOCK, SI_ORDER_MIDDLE, \
1413d4f7f0fSAugustin Cavalier	    (system_init_func_t)mtx_destroy, (void*)mtx)
142800e9d66SAugustin Cavalier
143800e9d66SAugustin Cavalier
144f9a21cf8SJérôme Duval#endif	/* _FBSD_COMPAT_SYS_MUTEX_H_ */
145