xref: /haiku/src/libs/compat/freebsd_network/mutex.c (revision e1c4049fed1047bdb957b0529e1921e97ef94770)
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
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
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
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
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
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
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
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
124 uninit_mutexes()
125 {
126 	mtx_destroy(&Giant);
127 	rw_lock_destroy(&ifnet_rwlock);
128 	mtx_destroy(&gIdStoreLock);
129 }
130