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
13 struct mtx Giant;
14 struct rw_lock ifnet_rwlock;
15 struct mtx gIdStoreLock;
16
17
18 void
mtx_init(struct mtx * mutex,const char * name,const char * type,int options)19 mtx_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
37 void
mtx_sysinit(void * arg)38 mtx_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
47 void
mtx_destroy(struct mtx * mutex)48 mtx_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
60 void
mtx_lock_spin(struct mtx * mutex)61 mtx_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
71 void
mtx_unlock_spin(struct mtx * mutex)72 mtx_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
82 void
_mtx_assert(struct mtx * m,int what,const char * file,int line)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
112 status_t
init_mutexes()113 init_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
123 void
uninit_mutexes()124 uninit_mutexes()
125 {
126 mtx_destroy(&Giant);
127 rw_lock_destroy(&ifnet_rwlock);
128 mtx_destroy(&gIdStoreLock);
129 }
130