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