aboutsummaryrefslogtreecommitdiff
path: root/sys/sys/lockmgr.h
blob: 4c3a272abdef9529ed5ed7104b4c9b1c3451ff14 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/*-
 * Copyright (c) 2008 Attilio Rao <attilio@FreeBSD.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice(s), this list of conditions and the following disclaimer as
 *    the first lines of this file unmodified other than the possible 
 *    addition of one or more copyright notices.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice(s), this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * $FreeBSD$
 */

#ifndef	_SYS_LOCKMGR_H_
#define	_SYS_LOCKMGR_H_

#include <sys/_lock.h>
#include <sys/_lockmgr.h>
#include <sys/_mutex.h>
#include <sys/_rwlock.h>

#define	LK_SHARE			0x01
#define	LK_SHARED_WAITERS		0x02
#define	LK_EXCLUSIVE_WAITERS		0x04
#define	LK_EXCLUSIVE_SPINNERS		0x08
#define	LK_ALL_WAITERS							\
	(LK_SHARED_WAITERS | LK_EXCLUSIVE_WAITERS)
#define	LK_FLAGMASK							\
	(LK_SHARE | LK_ALL_WAITERS | LK_EXCLUSIVE_SPINNERS)

#define	LK_HOLDER(x)			((x) & ~LK_FLAGMASK)
#define	LK_SHARERS_SHIFT		4
#define	LK_SHARERS(x)			(LK_HOLDER(x) >> LK_SHARERS_SHIFT)
#define	LK_SHARERS_LOCK(x)		((x) << LK_SHARERS_SHIFT | LK_SHARE)
#define	LK_ONE_SHARER			(1 << LK_SHARERS_SHIFT)
#define	LK_UNLOCKED			LK_SHARERS_LOCK(0)
#define	LK_KERNPROC			((uintptr_t)(-1) & ~LK_FLAGMASK)

#ifdef _KERNEL

#if !defined(LOCK_FILE) || !defined(LOCK_LINE)
#error	"LOCK_FILE and LOCK_LINE not defined, include <sys/lock.h> before"
#endif

struct thread;
#define	lk_recurse	lock_object.lo_data

/*
 * Function prototipes.  Routines that start with an underscore are not part
 * of the public interface and might be wrappered with a macro.
 */
int	 __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
	    const char *wmesg, int prio, int timo, const char *file, int line);
#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
void	 _lockmgr_assert(struct lock *lk, int what, const char *file, int line);
#endif
void	 _lockmgr_disown(struct lock *lk, const char *file, int line);

void	 lockallowrecurse(struct lock *lk);
void	 lockallowshare(struct lock *lk);
void	 lockdestroy(struct lock *lk);
void	 lockdisablerecurse(struct lock *lk);
void	 lockinit(struct lock *lk, int prio, const char *wmesg, int timo,
	    int flags);
#ifdef DDB
int	 lockmgr_chain(struct thread *td, struct thread **ownerp);
#endif
void	 lockmgr_printinfo(struct lock *lk);
int	 lockstatus(struct lock *lk);

/*
 * As far as the ilk can be a static NULL pointer these functions need a
 * strict prototype in order to safely use the lock_object member.
 */
static __inline int
_lockmgr_args(struct lock *lk, u_int flags, struct mtx *ilk, const char *wmesg,
    int prio, int timo, const char *file, int line)
{

	return (__lockmgr_args(lk, flags, (ilk != NULL) ? &ilk->lock_object :
	    NULL, wmesg, prio, timo, file, line));
}

static __inline int
_lockmgr_args_rw(struct lock *lk, u_int flags, struct rwlock *ilk,
    const char *wmesg, int prio, int timo, const char *file, int line)
{

	return (__lockmgr_args(lk, flags, (ilk != NULL) ? &ilk->lock_object :
	    NULL, wmesg, prio, timo, file, line));
}

/*
 * Define aliases in order to complete lockmgr KPI.
 */
#define	lockmgr(lk, flags, ilk)						\
	_lockmgr_args((lk), (flags), (ilk), LK_WMESG_DEFAULT,		\
	    LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, LOCK_FILE, LOCK_LINE)
#define	lockmgr_args(lk, flags, ilk, wmesg, prio, timo)			\
	_lockmgr_args((lk), (flags), (ilk), (wmesg), (prio), (timo),	\
	    LOCK_FILE, LOCK_LINE)
#define	lockmgr_args_rw(lk, flags, ilk, wmesg, prio, timo)		\
	_lockmgr_args_rw((lk), (flags), (ilk), (wmesg), (prio), (timo),	\
	    LOCK_FILE, LOCK_LINE)
#define	lockmgr_disown(lk)						\
	_lockmgr_disown((lk), LOCK_FILE, LOCK_LINE)
#define	lockmgr_recursed(lk)						\
	((lk)->lk_recurse != 0)
#define	lockmgr_rw(lk, flags, ilk)					\
	_lockmgr_args_rw((lk), (flags), (ilk), LK_WMESG_DEFAULT,	\
	    LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, LOCK_FILE, LOCK_LINE)
#define	lockmgr_waiters(lk)						\
	((lk)->lk_lock & LK_ALL_WAITERS)
#ifdef INVARIANTS
#define	lockmgr_assert(lk, what)					\
	_lockmgr_assert((lk), (what), LOCK_FILE, LOCK_LINE)
#else
#define	lockmgr_assert(lk, what)
#endif

/*
 * Flags for lockinit().
 */
#define	LK_INIT_MASK	0x0000FF
#define	LK_CANRECURSE	0x000001
#define	LK_NODUP	0x000002
#define	LK_NOPROFILE	0x000004
#define	LK_NOSHARE	0x000008
#define	LK_NOWITNESS	0x000010
#define	LK_QUIET	0x000020
#define	LK_ADAPTIVE	0x000040

/*
 * Additional attributes to be used in lockmgr().
 */
#define	LK_EATTR_MASK	0x00FF00
#define	LK_INTERLOCK	0x000100
#define	LK_NOWAIT	0x000200
#define	LK_RETRY	0x000400
#define	LK_SLEEPFAIL	0x000800
#define	LK_TIMELOCK	0x001000

/*
 * Operations for lockmgr().
 */
#define	LK_TYPE_MASK	0xFF0000
#define	LK_DOWNGRADE	0x010000
#define	LK_DRAIN	0x020000
#define	LK_EXCLOTHER	0x040000
#define	LK_EXCLUSIVE	0x080000
#define	LK_RELEASE	0x100000
#define	LK_SHARED	0x200000
#define	LK_UPGRADE	0x400000

#define	LK_TOTAL_MASK	(LK_INIT_MASK | LK_EATTR_MASK | LK_TYPE_MASK)

/*
 * Default values for lockmgr_args().
 */
#define	LK_WMESG_DEFAULT	(NULL)
#define	LK_PRIO_DEFAULT		(0)
#define	LK_TIMO_DEFAULT		(0)

/*
 * Assertion flags.
 */
#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
#define	KA_LOCKED	LA_LOCKED
#define	KA_SLOCKED	LA_SLOCKED
#define	KA_XLOCKED	LA_XLOCKED
#define	KA_UNLOCKED	LA_UNLOCKED
#define	KA_RECURSED	LA_RECURSED
#define	KA_NOTRECURSED	LA_NOTRECURSED
#endif

#endif /* _KERNEL */

#endif /* !_SYS_LOCKMGR_H_ */