#define GIANT_PROC 1 #define GIANT_FILE 2 extern int kern_giant_file; extern int kern_giant_proc; extern int _mtx_lock_giant(int); extern void _mtx_unlock_giant(int); #if defined(GIANT_PROC_ALWAYS) || defined(GIANT_ALL_ALWAYS) #define _mtx_lock_proc(s) \ if (!s) mtx_lock(&Giant); (s) |= GIANT_PROC #define _mtx_unlock_proc(s) \ if (s & GIANT_PROC) mtx_unlock(&Giant); (s) = 0 #elif defined(GIANT_PROC_NEVER) || defined(GIANT_ALL_NEVER) #define _mtx_lock_proc(s) \ do {} while (0) #define _mtx_unlock_proc(s) \ do {} while (0); (s) = 0 #else #define _mtx_lock_proc(s) \ (s) |= _mtx_lock_giant(kern_giant_proc) #define _mtx_unlock_proc(s) \ if (s) _mtx_unlock_giant(s); (s) = 0 #endif /* and so on for the other flags for other bits */ #if defined(GIANT_FILE_ALWAYS) || defined(GIANT_ALL_ALWAYS) #define _mtx_lock_file(s) \ if (!s) mtx_lock(&Giant); (s) |= GIANT_FILE #define _mtx_unlock_file(s) \ if (s & GIANT_FILE) mtx_unlock(&Giant); (s) = 0 #elif defined(GIANT_FILE_NEVER) || defined(GIANT_ALL_NEVER) #define _mtx_lock_file(s) \ do {} while (0) #define _mtx_unlock_file(s) \ do {} while (0); (s) = 0 #else #define _mtx_lock_file(s) \ (s) |= _mtx_lock_giant(kern_giant_file) #define _mtx_unlock_file(s) \ if (s) _mtx_unlock_giant(s); (s) = 0 #endif #define mtx_lock_giant(mask) \ ({ \ int ret = 0; \ if (mask & GIANT_PROC) { \ _mtx_lock_proc(ret); \ } else if (mask & GIANT_FILE) { \ _mtx_lock_file(ret); \ } else \ panic("unknown flag"); \ ret; \ }) #if 0 /* bah, gcc isn't smart enough for this yet */ #define mtx_unlock_giant(mask) \ { \ if (mask & GIANT_PROC) { \ _mtx_unlock_proc(mask); \ } else if (mask & GIANT_FILE) { \ _mtx_unlock_file(mask); \ } \ } #else #define mtx_unlock_giant(mask) \ { \ if (mask) \ _mtx_unlock_giant(mask); \ } #endif /* hackery to get basic stuff to compile */ int Giant; extern void bar(void); extern void mtx_lock(int *); extern void mtx_unlock(int *); void foo(void) { int q; q = mtx_lock_giant(GIANT_PROC); bar(); if (q) mtx_unlock_giant(q); }