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