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
7
8#include "device.h"
9
10#include <compat/sys/mutex.h>
11
12
13struct mtx Giant;
14struct rw_lock ifnet_rwlock;
15struct mtx gIdStoreLock;
16
17
18void
19mtx_init(struct mtx *mutex, const char *name, const char *type,
20	int options)
21{
22	if ((options & MTX_RECURSE) != 0) {
23		recursive_lock_init_etc(&mutex->u.recursive, name,
24			MUTEX_FLAG_CLONE_NAME);
25		mutex->type = MTX_RECURSE;
26	} else if ((options & MTX_SPIN) != 0) {
27		B_INITIALIZE_SPINLOCK(&mutex->u.spinlock_.lock);
28		mutex->type = MTX_SPIN;
29	} else {
30		mutex_init_etc(&mutex->u.mutex_.lock, name, MUTEX_FLAG_CLONE_NAME);
31		mutex->u.mutex_.owner = -1;
32		mutex->type = MTX_DEF;
33	}
34}
35
36
37void
38mtx_sysinit(void *arg)
39{
40	struct mtx_args *margs = arg;
41
42	mtx_init((struct mtx *)margs->ma_mtx, margs->ma_desc, NULL,
43	    margs->ma_opts);
44}
45
46
47void
48mtx_destroy(struct mtx *mutex)
49{
50	if ((mutex->type & MTX_RECURSE) != 0) {
51		recursive_lock_destroy(&mutex->u.recursive);
52	} else if ((mutex->type & MTX_SPIN) != 0) {
53		KASSERT(!B_SPINLOCK_IS_LOCKED(&mutex->u.spinlock_.lock), ("spin mutex is locked"));
54	} else {
55		mutex_destroy(&mutex->u.mutex_.lock);
56	}
57}
58
59
60void
61mtx_lock_spin(struct mtx* mutex)
62{
63	KASSERT(mutex->type == MTX_SPIN, ("not a spin mutex"));
64
65	cpu_status status = disable_interrupts();
66	acquire_spinlock(&mutex->u.spinlock_.lock);
67	mutex->u.spinlock_.state = status;
68}
69
70
71void
72mtx_unlock_spin(struct mtx* mutex)
73{
74	KASSERT(mutex->type == MTX_SPIN, ("not a spin mutex"));
75
76	cpu_status status = mutex->u.spinlock_.state;
77	release_spinlock(&mutex->u.spinlock_.lock);
78	restore_interrupts(status);
79}
80
81
82void
83_mtx_assert(struct mtx *m, int what, const char *file, int line)
84{
85	switch (what) {
86	case MA_OWNED:
87	case MA_OWNED | MA_RECURSED:
88	case MA_OWNED | MA_NOTRECURSED:
89		if (!mtx_owned(m))
90			panic("mutex %p not owned at %s:%d",
91				m, file, line);
92		if (mtx_recursed(m)) {
93			if ((what & MA_NOTRECURSED) != 0)
94				panic("mutex %p recursed at %s:%d",
95					m, file, line);
96		} else if ((what & MA_RECURSED) != 0) {
97			panic("mutex %p unrecursed at %s:%d",
98				m, file, line);
99		}
100		break;
101	case MA_NOTOWNED:
102		if (mtx_owned(m))
103			panic("mutex %p owned at %s:%d",
104				m, file, line);
105		break;
106	default:
107		panic("unknown mtx_assert at %s:%d", file, line);
108	}
109}
110
111
112status_t
113init_mutexes()
114{
115	mtx_init(&Giant, "Banana Giant", NULL, MTX_DEF);
116	rw_lock_init(&ifnet_rwlock, "gDevices");
117	mtx_init(&gIdStoreLock, "Identity Store", NULL, MTX_DEF);
118
119	return B_OK;
120}
121
122
123void
124uninit_mutexes()
125{
126	mtx_destroy(&Giant);
127	rw_lock_destroy(&ifnet_rwlock);
128	mtx_destroy(&gIdStoreLock);
129}
130