mutex.h revision 227758
118334Speter/*- 218334Speter * Copyright (c) 1997 Berkeley Software Design, Inc. All rights reserved. 372562Sobrien * 4169689Skan * Redistribution and use in source and binary forms, with or without 5169689Skan * modification, are permitted provided that the following conditions 618334Speter * are met: 790075Sobrien * 1. Redistributions of source code must retain the above copyright 818334Speter * notice, this list of conditions and the following disclaimer. 990075Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1090075Sobrien * notice, this list of conditions and the following disclaimer in the 1190075Sobrien * documentation and/or other materials provided with the distribution. 1290075Sobrien * 3. Berkeley Software Design Inc's name may not be used to endorse or 1318334Speter * promote products derived from this software without specific prior 1490075Sobrien * written permission. 1590075Sobrien * 1690075Sobrien * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND 1790075Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1818334Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1918334Speter * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE 2090075Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21169689Skan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22169689Skan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2318334Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2418334Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2518334Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2650397Sobrien * SUCH DAMAGE. 27132718Skan * 28132718Skan * from BSDI $Id: mutex.h,v 2.7.2.35 2000/04/27 03:10:26 cp Exp $ 2952284Sobrien * $FreeBSD: head/sys/sys/mutex.h 227758 2011-11-20 16:33:09Z attilio $ 3018334Speter */ 3118334Speter 3290075Sobrien#ifndef _SYS_MUTEX_H_ 3318334Speter#define _SYS_MUTEX_H_ 3418334Speter 3518334Speter#include <sys/queue.h> 3690075Sobrien#include <sys/_lock.h> 3718334Speter#include <sys/_mutex.h> 3818334Speter 39117395Skan#ifdef _KERNEL 4018334Speter#include <sys/pcpu.h> 41132718Skan#include <sys/lock_profile.h> 42132718Skan#include <sys/lockstat.h> 43132718Skan#include <machine/atomic.h> 44132718Skan#include <machine/cpufunc.h> 45132718Skan 46132718Skan/* 47132718Skan * Mutex types and options passed to mtx_init(). MTX_QUIET and MTX_DUPOK 48132718Skan * can also be passed in. 49132718Skan */ 50132718Skan#define MTX_DEF 0x00000000 /* DEFAULT (sleep) lock */ 51132718Skan#define MTX_SPIN 0x00000001 /* Spin lock (disables interrupts) */ 52132718Skan#define MTX_RECURSE 0x00000004 /* Option: lock allowed to recurse */ 53132718Skan#define MTX_NOWITNESS 0x00000008 /* Don't do any witness checking. */ 54132718Skan#define MTX_NOPROFILE 0x00000020 /* Don't profile this lock */ 55169689Skan 56169689Skan/* 5718334Speter * Option flags passed to certain lock/unlock routines, through the use 58169689Skan * of corresponding mtx_{lock,unlock}_flags() interface macros. 59169689Skan */ 60169689Skan#define MTX_QUIET LOP_QUIET /* Don't log a mutex event */ 61117395Skan#define MTX_DUPOK LOP_DUPOK /* Don't log a duplicate acquire */ 6296263Sobrien 6318334Speter/* 6418334Speter * State bits kept in mutex->mtx_lock, for the DEFAULT lock type. None of this, 6518334Speter * with the exception of MTX_UNOWNED, applies to spin locks. 66169689Skan */ 67169689Skan#define MTX_RECURSED 0x00000001 /* lock recursed (for MTX_DEF only) */ 6818334Speter#define MTX_CONTESTED 0x00000002 /* lock contested (for MTX_DEF only) */ 6918334Speter#define MTX_UNOWNED 0x00000004 /* Cookie for free mutex */ 7090075Sobrien#define MTX_FLAGMASK (MTX_RECURSED | MTX_CONTESTED | MTX_UNOWNED) 7118334Speter 7218334Speter/* 7318334Speter * Value stored in mutex->mtx_lock to denote a destroyed mutex. 7418334Speter */ 7518334Speter#define MTX_DESTROYED (MTX_CONTESTED | MTX_UNOWNED) 7618334Speter 7718334Speter/* 7818334Speter * Prototypes 7918334Speter * 8018334Speter * NOTE: Functions prepended with `_' (underscore) are exported to other parts 8190075Sobrien * of the kernel via macros, thus allowing us to use the cpp LOCK_FILE 8290075Sobrien * and LOCK_LINE. These functions should not be called directly by any 8390075Sobrien * code using the API. Their macros cover their functionality. 8490075Sobrien * Functions with a `_' suffix are the entrypoint for the common 8590075Sobrien * KPI covering both compat shims and fast path case. These can be 8690075Sobrien * used by consumers willing to pass options, file and line 8790075Sobrien * informations, in an option-independent way. 8890075Sobrien * 8990075Sobrien * [See below for descriptions] 9090075Sobrien * 9190075Sobrien */ 9290075Sobrienvoid mtx_init(struct mtx *m, const char *name, const char *type, int opts); 9390075Sobrienvoid mtx_destroy(struct mtx *m); 9490075Sobrienvoid mtx_sysinit(void *arg); 9590075Sobrienint mtx_trylock_flags_(struct mtx *m, int opts, const char *file, 9690075Sobrien int line); 9790075Sobrienvoid mutex_init(void); 9890075Sobrienvoid _mtx_lock_sleep(struct mtx *m, uintptr_t tid, int opts, 9990075Sobrien const char *file, int line); 100169689Skanvoid _mtx_unlock_sleep(struct mtx *m, int opts, const char *file, int line); 101169689Skan#ifdef SMP 102169689Skanvoid _mtx_lock_spin(struct mtx *m, uintptr_t tid, int opts, 103169689Skan const char *file, int line); 104169689Skan#endif 105169689Skanvoid _mtx_unlock_spin(struct mtx *m, int opts, const char *file, int line); 10618334Spetervoid _mtx_lock_flags(struct mtx *m, int opts, const char *file, int line); 107169689Skanvoid _mtx_unlock_flags(struct mtx *m, int opts, const char *file, int line); 108169689Skanvoid _mtx_lock_spin_flags(struct mtx *m, int opts, const char *file, 10918334Speter int line); 11018334Spetervoid _mtx_unlock_spin_flags(struct mtx *m, int opts, const char *file, 11118334Speter int line); 11218334Speter#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT) 113132718Skanvoid _mtx_assert(const struct mtx *m, int what, const char *file, int line); 11418334Speter#endif 115169689Skanvoid thread_lock_flags_(struct thread *, int, const char *, int); 116169689Skan 117169689Skan#define thread_lock(tdp) \ 118169689Skan thread_lock_flags_((tdp), 0, __FILE__, __LINE__) 119169689Skan#define thread_lock_flags(tdp, opt) \ 120169689Skan thread_lock_flags_((tdp), (opt), __FILE__, __LINE__) 121169689Skan#define thread_unlock(tdp) \ 122169689Skan mtx_unlock_spin((tdp)->td_lock) 123169689Skan 124169689Skan#define mtx_recurse lock_object.lo_data 125169689Skan 126169689Skan/* Very simple operations on mtx_lock. */ 127169689Skan 128169689Skan/* Try to obtain mtx_lock once. */ 129169689Skan#define _mtx_obtain_lock(mp, tid) \ 130169689Skan atomic_cmpset_acq_ptr(&(mp)->mtx_lock, MTX_UNOWNED, (tid)) 131169689Skan 132169689Skan/* Try to release mtx_lock if it is unrecursed and uncontested. */ 133169689Skan#define _mtx_release_lock(mp, tid) \ 134169689Skan atomic_cmpset_rel_ptr(&(mp)->mtx_lock, (tid), MTX_UNOWNED) 135169689Skan 136169689Skan/* Release mtx_lock quickly, assuming we own it. */ 137169689Skan#define _mtx_release_lock_quick(mp) \ 13818334Speter atomic_store_rel_ptr(&(mp)->mtx_lock, MTX_UNOWNED) 13918334Speter 140169689Skan/* 14118334Speter * Full lock operations that are suitable to be inlined in non-debug 142169689Skan * kernels. If the lock cannot be acquired or released trivially then 143169689Skan * the work is deferred to another function. 144169689Skan */ 145169689Skan 146169689Skan/* Lock a normal mutex. */ 14718334Speter#define __mtx_lock(mp, tid, opts, file, line) do { \ 148169689Skan uintptr_t _tid = (uintptr_t)(tid); \ 14918334Speter \ 150169689Skan if (!_mtx_obtain_lock((mp), _tid)) \ 151169689Skan _mtx_lock_sleep((mp), _tid, (opts), (file), (line)); \ 152169689Skan else \ 15318334Speter LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_MTX_LOCK_ACQUIRE, \ 154169689Skan mp, 0, 0, (file), (line)); \ 155169689Skan} while (0) 156169689Skan 15718334Speter/* 158169689Skan * Lock a spin mutex. For spinlocks, we handle recursion inline (it 159169689Skan * turns out that function calls can be significantly expensive on 16018334Speter * some architectures). Since spin locks are not _too_ common, 161169689Skan * inlining this code is not too big a deal. 162169689Skan */ 163169689Skan#ifdef SMP 16418334Speter#define __mtx_lock_spin(mp, tid, opts, file, line) do { \ 165169689Skan uintptr_t _tid = (uintptr_t)(tid); \ 166169689Skan \ 167169689Skan spinlock_enter(); \ 16818334Speter if (!_mtx_obtain_lock((mp), _tid)) { \ 169169689Skan if ((mp)->mtx_lock == _tid) \ 170169689Skan (mp)->mtx_recurse++; \ 171169689Skan else \ 17218334Speter _mtx_lock_spin((mp), _tid, (opts), (file), (line)); \ 173169689Skan } else \ 174169689Skan LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_MTX_SPIN_LOCK_ACQUIRE, \ 175169689Skan mp, 0, 0, (file), (line)); \ 17618334Speter} while (0) 177169689Skan#else /* SMP */ 178169689Skan#define __mtx_lock_spin(mp, tid, opts, file, line) do { \ 179169689Skan uintptr_t _tid = (uintptr_t)(tid); \ 18018334Speter \ 181169689Skan spinlock_enter(); \ 182169689Skan if ((mp)->mtx_lock == _tid) \ 18318334Speter (mp)->mtx_recurse++; \ 184169689Skan else { \ 185169689Skan KASSERT((mp)->mtx_lock == MTX_UNOWNED, ("corrupt spinlock")); \ 186169689Skan (mp)->mtx_lock = _tid; \ 18718334Speter } \ 188169689Skan} while (0) 189169689Skan#endif /* SMP */ 19018334Speter 191169689Skan/* Unlock a normal mutex. */ 192169689Skan#define __mtx_unlock(mp, tid, opts, file, line) do { \ 193169689Skan uintptr_t _tid = (uintptr_t)(tid); \ 194169689Skan \ 195169689Skan if (!_mtx_release_lock((mp), _tid)) \ 196169689Skan _mtx_unlock_sleep((mp), (opts), (file), (line)); \ 197169689Skan} while (0) 198169689Skan 199169689Skan/* 200169689Skan * Unlock a spin mutex. For spinlocks, we can handle everything 201169689Skan * inline, as it's pretty simple and a function call would be too 202169689Skan * expensive (at least on some architectures). Since spin locks are 203169689Skan * not _too_ common, inlining this code is not too big a deal. 204169689Skan * 205169689Skan * Since we always perform a spinlock_enter() when attempting to acquire a 206169689Skan * spin lock, we need to always perform a matching spinlock_exit() when 207169689Skan * releasing a spin lock. This includes the recursion cases. 20818334Speter */ 20918334Speter#ifdef SMP 21018334Speter#define __mtx_unlock_spin(mp) do { \ 21118334Speter if (mtx_recursed((mp))) \ 212169689Skan (mp)->mtx_recurse--; \ 213169689Skan else { \ 214169689Skan LOCKSTAT_PROFILE_RELEASE_LOCK(LS_MTX_SPIN_UNLOCK_RELEASE, \ 215169689Skan mp); \ 216169689Skan _mtx_release_lock_quick((mp)); \ 217169689Skan } \ 218169689Skan spinlock_exit(); \ 219169689Skan} while (0) 220169689Skan#else /* SMP */ 221169689Skan#define __mtx_unlock_spin(mp) do { \ 222169689Skan if (mtx_recursed((mp))) \ 223169689Skan (mp)->mtx_recurse--; \ 224169689Skan else { \ 225169689Skan LOCKSTAT_PROFILE_RELEASE_LOCK(LS_MTX_SPIN_UNLOCK_RELEASE, \ 226169689Skan mp); \ 227169689Skan (mp)->mtx_lock = MTX_UNOWNED; \ 228169689Skan } \ 229169689Skan spinlock_exit(); \ 230169689Skan} while (0) 231169689Skan#endif /* SMP */ 232169689Skan 233169689Skan/* 234169689Skan * Exported lock manipulation interface. 235169689Skan * 236169689Skan * mtx_lock(m) locks MTX_DEF mutex `m' 23718334Speter * 23818334Speter * mtx_lock_spin(m) locks MTX_SPIN mutex `m' 23918334Speter * 240169689Skan * mtx_unlock(m) unlocks MTX_DEF mutex `m' 241169689Skan * 242169689Skan * mtx_unlock_spin(m) unlocks MTX_SPIN mutex `m' 243169689Skan * 244169689Skan * mtx_lock_spin_flags(m, opts) and mtx_lock_flags(m, opts) locks mutex `m' 245169689Skan * and passes option flags `opts' to the "hard" function, if required. 246169689Skan * With these routines, it is possible to pass flags such as MTX_QUIET 24718334Speter * to the appropriate lock manipulation routines. 248169689Skan * 249169689Skan * mtx_trylock(m) attempts to acquire MTX_DEF mutex `m' but doesn't sleep if 250169689Skan * it cannot. Rather, it returns 0 on failure and non-zero on success. 251169689Skan * It does NOT handle recursion as we assume that if a caller is properly 252169689Skan * using this part of the interface, he will know that the lock in question 253169689Skan * is _not_ recursed. 254169689Skan * 255169689Skan * mtx_trylock_flags(m, opts) is used the same way as mtx_trylock() but accepts 256169689Skan * relevant option flags `opts.' 257169689Skan * 258169689Skan * mtx_initialized(m) returns non-zero if the lock `m' has been initialized. 259169689Skan * 260169689Skan * mtx_owned(m) returns non-zero if the current thread owns the lock `m' 261169689Skan * 26218334Speter * mtx_recursed(m) returns non-zero if the lock `m' is presently recursed. 26318334Speter */ 26418334Speter#define mtx_lock(m) mtx_lock_flags((m), 0) 26518334Speter#define mtx_lock_spin(m) mtx_lock_spin_flags((m), 0) 26618334Speter#define mtx_trylock(m) mtx_trylock_flags((m), 0) 26718334Speter#define mtx_unlock(m) mtx_unlock_flags((m), 0) 26818334Speter#define mtx_unlock_spin(m) mtx_unlock_spin_flags((m), 0) 26918334Speter 270132718Skanstruct mtx_pool; 27118334Speter 27250397Sobrienstruct mtx_pool *mtx_pool_create(const char *mtx_name, int pool_size, int opts); 27350397Sobrienvoid mtx_pool_destroy(struct mtx_pool **poolp); 27450397Sobrienstruct mtx *mtx_pool_find(struct mtx_pool *pool, void *ptr); 27550397Sobrienstruct mtx *mtx_pool_alloc(struct mtx_pool *pool); 27650397Sobrien#define mtx_pool_lock(pool, ptr) \ 27750397Sobrien mtx_lock(mtx_pool_find((pool), (ptr))) 27818334Speter#define mtx_pool_lock_spin(pool, ptr) \ 27990075Sobrien mtx_lock_spin(mtx_pool_find((pool), (ptr))) 28090075Sobrien#define mtx_pool_unlock(pool, ptr) \ 28190075Sobrien mtx_unlock(mtx_pool_find((pool), (ptr))) 28290075Sobrien#define mtx_pool_unlock_spin(pool, ptr) \ 28390075Sobrien mtx_unlock_spin(mtx_pool_find((pool), (ptr))) 28490075Sobrien 285132718Skan/* 28690075Sobrien * mtxpool_lockbuilder is a pool of sleep locks that is not witness 28790075Sobrien * checked and should only be used for building higher level locks. 28890075Sobrien * 28990075Sobrien * mtxpool_sleep is a general purpose pool of sleep mutexes. 29090075Sobrien */ 29190075Sobrienextern struct mtx_pool *mtxpool_lockbuilder; 29290075Sobrienextern struct mtx_pool *mtxpool_sleep; 29390075Sobrien 29490075Sobrien#ifndef LOCK_DEBUG 29590075Sobrien#error LOCK_DEBUG not defined, include <sys/lock.h> before <sys/mutex.h> 29690075Sobrien#endif 29790075Sobrien#if LOCK_DEBUG > 0 || defined(MUTEX_NOINLINE) 29890075Sobrien#define mtx_lock_flags_(m, opts, file, line) \ 29990075Sobrien _mtx_lock_flags((m), (opts), (file), (line)) 30090075Sobrien#define mtx_unlock_flags_(m, opts, file, line) \ 30190075Sobrien _mtx_unlock_flags((m), (opts), (file), (line)) 30290075Sobrien#define mtx_lock_spin_flags_(m, opts, file, line) \ 30390075Sobrien _mtx_lock_spin_flags((m), (opts), (file), (line)) 30490075Sobrien#define mtx_unlock_spin_flags_(m, opts, file, line) \ 30590075Sobrien _mtx_unlock_spin_flags((m), (opts), (file), (line)) 30690075Sobrien#else /* LOCK_DEBUG == 0 && !MUTEX_NOINLINE */ 30790075Sobrien#define mtx_lock_flags_(m, opts, file, line) \ 30890075Sobrien __mtx_lock((m), curthread, (opts), (file), (line)) 30990075Sobrien#define mtx_unlock_flags_(m, opts, file, line) \ 31090075Sobrien __mtx_unlock((m), curthread, (opts), (file), (line)) 31190075Sobrien#define mtx_lock_spin_flags_(m, opts, file, line) \ 31290075Sobrien __mtx_lock_spin((m), curthread, (opts), (file), (line)) 31390075Sobrien#define mtx_unlock_spin_flags_(m, opts, file, line) \ 31490075Sobrien __mtx_unlock_spin((m)) 31590075Sobrien#endif /* LOCK_DEBUG > 0 || MUTEX_NOINLINE */ 316169689Skan 31790075Sobrien#ifdef INVARIANTS 31890075Sobrien#define mtx_assert_(m, what, file, line) \ 31990075Sobrien _mtx_assert((m), (what), (file), (line)) 32090075Sobrien 32190075Sobrien#define GIANT_REQUIRED mtx_assert_(&Giant, MA_OWNED, __FILE__, __LINE__) 32290075Sobrien 32390075Sobrien#else /* INVARIANTS */ 32490075Sobrien#define mtx_assert_(m, what, file, line) (void)0 32590075Sobrien#define GIANT_REQUIRED 32690075Sobrien#endif /* INVARIANTS */ 32790075Sobrien 32890075Sobrien#define mtx_lock_flags(m, opts) \ 32918334Speter mtx_lock_flags_((m), (opts), LOCK_FILE, LOCK_LINE) 33018334Speter#define mtx_unlock_flags(m, opts) \ 33118334Speter mtx_unlock_flags_((m), (opts), LOCK_FILE, LOCK_LINE) 33218334Speter#define mtx_lock_spin_flags(m, opts) \ 33318334Speter mtx_lock_spin_flags_((m), (opts), LOCK_FILE, LOCK_LINE) 33490075Sobrien#define mtx_unlock_spin_flags(m, opts) \ 33518334Speter mtx_unlock_spin_flags_((m), (opts), LOCK_FILE, LOCK_LINE) 33618334Speter#define mtx_trylock_flags(m, opts) \ 33718334Speter mtx_trylock_flags_((m), (opts), LOCK_FILE, LOCK_LINE) 33818334Speter#define mtx_assert(m, what) \ 33918334Speter mtx_assert_((m), (what), __FILE__, __LINE__) 34052284Sobrien 34118334Speter#define mtx_sleep(chan, mtx, pri, wmesg, timo) \ 34252284Sobrien _sleep((chan), &(mtx)->lock_object, (pri), (wmesg), (timo)) 34352284Sobrien 34452284Sobrien#define mtx_initialized(m) lock_initalized(&(m)->lock_object) 34518334Speter 346132718Skan#define mtx_owned(m) (((m)->mtx_lock & ~MTX_FLAGMASK) == (uintptr_t)curthread) 347132718Skan 348169689Skan#define mtx_recursed(m) ((m)->mtx_recurse != 0) 34918334Speter 35090075Sobrien#define mtx_name(m) ((m)->lock_object.lo_name) 351169689Skan 352169689Skan/* 35390075Sobrien * Global locks. 35496263Sobrien */ 355146895Skanextern struct mtx Giant; 35618334Speterextern struct mtx blocked_lock; 35790075Sobrien 35852284Sobrien/* 35918334Speter * Giant lock manipulation and clean exit macros. 36018334Speter * Used to replace return with an exit Giant and return. 36118334Speter * 36218334Speter * Note that DROP_GIANT*() needs to be paired with PICKUP_GIANT() 36318334Speter * The #ifndef is to allow lint-like tools to redefine DROP_GIANT. 36418334Speter */ 36518334Speter#ifndef DROP_GIANT 366169689Skan#define DROP_GIANT() \ 367169689Skando { \ 368169689Skan int _giantcnt = 0; \ 369169689Skan WITNESS_SAVE_DECL(Giant); \ 370169689Skan \ 371169689Skan if (mtx_owned(&Giant)) { \ 372169689Skan WITNESS_SAVE(&Giant.lock_object, Giant); \ 373169689Skan for (_giantcnt = 0; mtx_owned(&Giant); _giantcnt++) \ 374169689Skan mtx_unlock(&Giant); \ 375169689Skan } 376169689Skan 377169689Skan#define PICKUP_GIANT() \ 378169689Skan PARTIAL_PICKUP_GIANT(); \ 379169689Skan} while (0) 380169689Skan 381169689Skan#define PARTIAL_PICKUP_GIANT() \ 382169689Skan mtx_assert(&Giant, MA_NOTOWNED); \ 383169689Skan if (_giantcnt > 0) { \ 384169689Skan while (_giantcnt--) \ 38518334Speter mtx_lock(&Giant); \ 38618334Speter WITNESS_RESTORE(&Giant.lock_object, Giant); \ 38718334Speter } 388169689Skan#endif 389169689Skan 390169689Skan#define UGAR(rval) do { \ 391169689Skan int _val = (rval); \ 392169689Skan mtx_unlock(&Giant); \ 39318334Speter return (_val); \ 394169689Skan} while (0) 395132718Skan 396132718Skanstruct mtx_args { 397169689Skan struct mtx *ma_mtx; 398169689Skan const char *ma_desc; 399132718Skan int ma_opts; 400132718Skan}; 401132718Skan 402132718Skan#define MTX_SYSINIT(name, mtx, desc, opts) \ 403132718Skan static struct mtx_args name##_args = { \ 404132718Skan (mtx), \ 405132718Skan (desc), \ 406169689Skan (opts) \ 407132718Skan }; \ 408132718Skan SYSINIT(name##_mtx_sysinit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \ 409132718Skan mtx_sysinit, &name##_args); \ 410132718Skan SYSUNINIT(name##_mtx_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \ 411132718Skan mtx_destroy, (mtx)) 412132718Skan 413132718Skan/* 414132718Skan * The INVARIANTS-enabled mtx_assert() functionality. 415132718Skan * 416132718Skan * The constants need to be defined for INVARIANT_SUPPORT infrastructure 417132718Skan * support as _mtx_assert() itself uses them and the latter implies that 418132718Skan * _mtx_assert() must build. 419132718Skan */ 420132718Skan#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT) 421132718Skan#define MA_OWNED LA_XLOCKED 422132718Skan#define MA_NOTOWNED LA_UNLOCKED 423132718Skan#define MA_RECURSED LA_RECURSED 424132718Skan#define MA_NOTRECURSED LA_NOTRECURSED 425132718Skan#endif 426169689Skan 427169689Skan/* 428169689Skan * Common lock type names. 429132718Skan */ 430132718Skan#define MTX_NETWORK_LOCK "network driver" 431132718Skan 432132718Skan#endif /* _KERNEL */ 433132718Skan#endif /* _SYS_MUTEX_H_ */ 434132718Skan