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#ifndef _FBSD_COMPAT_SYS_MUTEX_H_ 7#define _FBSD_COMPAT_SYS_MUTEX_H_ 8 9 10#include <sys/_mutex.h> 11#include <sys/systm.h> 12#include <sys/pcpu.h> 13 14 15#define MA_OWNED 0x1 16#define MA_NOTOWNED 0x2 17#define MA_RECURSED 0x4 18#define MA_NOTRECURSED 0x8 19 20#define MTX_DEF 0x00000000 21#define MTX_SPIN 0x00000001 22#define MTX_RECURSE 0x00000004 23#define MTX_QUIET 0x00040000 24#define MTX_DUPOK 0x00400000 25 26 27#define MTX_NETWORK_LOCK "network driver" 28 29 30extern struct mtx Giant; 31 32 33void mtx_init(struct mtx*, const char*, const char*, int); 34void mtx_sysinit(void *arg); 35void mtx_destroy(struct mtx*); 36void mtx_lock_spin(struct mtx* mutex); 37void mtx_unlock_spin(struct mtx* mutex); 38void _mtx_assert(struct mtx *m, int what, const char *file, int line); 39 40 41#ifdef INVARIANTS 42# define mtx_assert(m, what) \ 43 _mtx_assert((m), (what), __FILE__, __LINE__) 44#else 45# define mtx_assert(m, what) 46#endif 47 48 49static inline void 50mtx_lock(struct mtx* mutex) 51{ 52 if (mutex->type == MTX_DEF) { 53 mutex_lock(&mutex->u.mutex_.lock); 54 mutex->u.mutex_.owner = find_thread(NULL); 55 } else if (mutex->type == MTX_RECURSE) { 56 recursive_lock_lock(&mutex->u.recursive); 57 } else if (mutex->type == MTX_SPIN) { 58 mtx_lock_spin(mutex); 59 } 60} 61 62 63static inline int 64mtx_trylock(struct mtx* mutex) 65{ 66 if (mutex->type == MTX_DEF) { 67 if (mutex_trylock(&mutex->u.mutex_.lock) != B_OK) 68 return 0; 69 mutex->u.mutex_.owner = find_thread(NULL); 70 return 1; 71 } else if (mutex->type == MTX_RECURSE) { 72 if (recursive_lock_trylock(&mutex->u.recursive) != B_OK) 73 return 0; 74 return 1; 75 } else if (mutex->type == MTX_SPIN) { 76 return 0; 77 } 78 return 0; 79} 80 81 82static inline void 83mtx_unlock(struct mtx* mutex) 84{ 85 if (mutex->type == MTX_DEF) { 86 mutex->u.mutex_.owner = -1; 87 mutex_unlock(&mutex->u.mutex_.lock); 88 } else if (mutex->type == MTX_RECURSE) { 89 recursive_lock_unlock(&mutex->u.recursive); 90 } else if (mutex->type == MTX_SPIN) { 91 mtx_unlock_spin(mutex); 92 } 93} 94 95 96static inline int 97mtx_initialized(struct mtx* mutex) 98{ 99 /* TODO */ 100 return 1; 101} 102 103 104static inline int 105mtx_owned(struct mtx* mutex) 106{ 107 if (mutex->type == MTX_DEF) 108 return mutex->u.mutex_.owner == find_thread(NULL); 109 if (mutex->type == MTX_RECURSE) { 110#if KDEBUG 111 return mutex->u.recursive.lock.holder == find_thread(NULL); 112#else 113 return mutex->u.recursive.holder == find_thread(NULL); 114#endif 115 } 116 if (mutex->type == MTX_SPIN) 117 return mutex->u.spinlock_.lock.lock != 0; 118 119 return 0; 120} 121 122 123static inline int 124mtx_recursed(struct mtx* mutex) 125{ 126 if (mutex->type == MTX_RECURSE) 127 return mutex->u.recursive.recursion != 0; 128 return 0; 129} 130 131 132struct mtx_args { 133 void *ma_mtx; 134 const char *ma_desc; 135 int ma_opts; 136}; 137 138#define MTX_SYSINIT(name, mtx, desc, opts) \ 139 static struct mtx_args name##_args = { \ 140 (mtx), \ 141 (desc), \ 142 (opts), \ 143 }; \ 144 SYSINIT(name##_mtx, SI_SUB_LOCK, SI_ORDER_MIDDLE, \ 145 mtx_sysinit, &name##_args); \ 146 SYSUNINIT(name##_mtx, SI_SUB_LOCK, SI_ORDER_MIDDLE, \ 147 (system_init_func_t)mtx_destroy, (void*)mtx) 148 149 150#endif /* _FBSD_COMPAT_SYS_MUTEX_H_ */ 151