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