lock.h revision 74912
1/*- 2 * Copyright (c) 1997 Berkeley Software Design, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Berkeley Software Design Inc's name may not be used to endorse or 13 * promote products derived from this software without specific prior 14 * written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * from BSDI $Id: mutex.h,v 2.7.2.35 2000/04/27 03:10:26 cp Exp $ 29 * $FreeBSD: head/sys/sys/lock.h 74912 2001-03-28 09:03:24Z jhb $ 30 */ 31 32#ifndef _SYS_LOCK_H_ 33#define _SYS_LOCK_H_ 34 35/* 36 * XXX - compatability until lockmgr() goes away or all the #includes are 37 * updated. 38 */ 39#include <sys/lockmgr.h> 40 41#include <sys/queue.h> 42 43/* 44 * Lock classes. Each lock has a class which describes characteristics 45 * common to all types of locks of a given class. 46 * 47 * Spin locks in general must always protect against preemption, as it is 48 * an error to perform any type of context switch while holding a spin lock. 49 * Also, for an individual lock to be recursable, its class must allow 50 * recursion and the lock itself must explicitly allow recursion. 51 */ 52 53struct lock_class { 54 const char *lc_name; 55 u_int lc_flags; 56}; 57 58#define LC_SLEEPLOCK 0x00000001 /* Sleep lock. */ 59#define LC_SPINLOCK 0x00000002 /* Spin lock. */ 60#define LC_SLEEPABLE 0x00000004 /* Sleeping allowed with this lock. */ 61#define LC_RECURSABLE 0x00000008 /* Locks of this type may recurse. */ 62 63struct witness; 64 65struct lock_object { 66 struct lock_class *lo_class; 67 const char *lo_name; 68 const char *lo_file; /* File and line of last acquire. */ 69 int lo_line; 70 u_int lo_flags; 71 STAILQ_ENTRY(lock_object) lo_list; /* List of all locks in system. */ 72 struct witness *lo_witness; 73}; 74 75#define LO_CLASSFLAGS 0x0000ffff /* Class specific flags. */ 76#define LO_INITIALIZED 0x00010000 /* Lock has been initialized. */ 77#define LO_WITNESS 0x00020000 /* Should witness monitor this lock. */ 78#define LO_QUIET 0x00040000 /* Don't log locking operations. */ 79#define LO_RECURSABLE 0x00080000 /* Lock may recurse. */ 80#define LO_SLEEPABLE 0x00100000 /* Lock may be held while sleeping. */ 81#define LO_LOCKED 0x01000000 /* Someone holds this lock. */ 82#define LO_RECURSED 0x02000000 /* Someone has recursed on this lock. */ 83 84/* 85 * Option flags passed to lock operations that witness also needs to know 86 * about or that are generic across all locks. 87 */ 88#define LOP_NOSWITCH 0x00000001 /* Lock doesn't switch on release. */ 89#define LOP_QUIET 0x00000002 /* Don't log locking operations. */ 90#define LOP_TRYLOCK 0x00000004 /* Don't check lock order. */ 91 92#ifdef _KERNEL 93/* 94 * A simple list type used to build the list of locks held by a process 95 * or CPU. We can't simply embed the list in struct lock_object since a 96 * lock may be held by more than one process if it is a shared lock. Locks 97 * are added to the head of the list, so we fill up each list entry from 98 * "the back" logically. To ease some of the arithmetic, we actually fill 99 * in each list entry the normal way (childer[0] then children[1], etc.) but 100 * when we traverse the list we read children[count-1] as the first entry 101 * down to children[0] as the final entry. 102 */ 103#define LOCK_NCHILDREN 6 104 105struct lock_list_entry { 106 struct lock_list_entry *ll_next; 107 struct lock_object *ll_children[LOCK_NCHILDREN]; 108 u_int ll_count; 109}; 110 111/* 112 * Macros for KTR_LOCK tracing. 113 * 114 * opname - name of this operation (LOCK/UNLOCK/SLOCK, etc.) 115 * lo - struct lock_object * for this lock 116 * flags - flags passed to the lock operation 117 * recurse - this locks recursion level (or 0 if class is not recursable) 118 * result - result of a try lock operation 119 * file - file name 120 * line - line number 121 */ 122#define LOCK_LOG_TEST(lo, flags) \ 123 (((flags) & LOP_QUIET) == 0 && ((lo)->lo_flags & LO_QUIET) == 0) 124 125#define LOCK_LOG_LOCK(opname, lo, flags, recurse, file, line) do { \ 126 if (LOCK_LOG_TEST((lo), (flags))) \ 127 CTR5(KTR_LOCK, opname " (%s) %s r = %d at %s:%d", \ 128 (lo)->lo_class->lc_name, (lo)->lo_name, \ 129 (u_int)(recurse), (file), (line)); \ 130} while (0) 131 132#define LOCK_LOG_TRY(opname, lo, flags, result, file, line) do { \ 133 if (LOCK_LOG_TEST((lo), (flags))) \ 134 CTR5(KTR_LOCK, "TRY_" opname " (%s) %s result=%d at %s:%d",\ 135 (lo)->lo_class->lc_name, (lo)->lo_name, \ 136 (u_int)(result), (file), (line)); \ 137} while (0) 138 139#define LOCK_LOG_INIT(lo, flags) do { \ 140 if (LOCK_LOG_TEST((lo), (flags))) \ 141 CTR3(KTR_LOCK, __func__ ": %p (%s) %s", (lo), \ 142 (lo)->lo_class->lc_name, (lo)->lo_name); \ 143} while (0) 144 145#define LOCK_LOG_DESTROY(lo, flags) LOCK_LOG_INIT(lo, flags) 146 147/* 148 * Helpful macros for quickly coming up with assertions with informative 149 * panic messages. 150 */ 151#define MPASS(ex) MPASS4(ex, #ex, __FILE__, __LINE__) 152#define MPASS2(ex, what) MPASS4(ex, what, __FILE__, __LINE__) 153#define MPASS3(ex, file, line) MPASS4(ex, #ex, file, line) 154#define MPASS4(ex, what, file, line) \ 155 KASSERT((ex), ("Assertion %s failed at %s:%d", what, file, line)) 156 157extern struct lock_class lock_class_mtx_sleep; 158extern struct lock_class lock_class_mtx_spin; 159extern struct lock_class lock_class_sx; 160 161void witness_init(struct lock_object *); 162void witness_destroy(struct lock_object *); 163void witness_lock(struct lock_object *, int, const char *, int); 164void witness_unlock(struct lock_object *, int, const char *, int); 165void witness_save(struct lock_object *, const char **, int *); 166void witness_restore(struct lock_object *, const char *, int); 167int witness_list(struct proc *); 168int witness_sleep(int, struct lock_object *, const char *, int); 169 170#ifdef WITNESS 171#define WITNESS_INIT(lock) \ 172 witness_init((lock)) 173 174#define WITNESS_DESTROY(lock) \ 175 witness_destroy(lock) 176 177#define WITNESS_LOCK(lock, flags, file, line) \ 178 witness_lock((lock), (flags), (file), (line)) 179 180#define WITNESS_UNLOCK(lock, flags, file, line) \ 181 witness_unlock((lock), (flags), (file), (line)) 182 183#define WITNESS_SLEEP(check, lock) \ 184 witness_sleep((check), (lock), __FILE__, __LINE__) 185 186#define WITNESS_SAVE_DECL(n) \ 187 const char * __CONCAT(n, __wf); \ 188 int __CONCAT(n, __wl) 189 190#define WITNESS_SAVE(lock, n) \ 191 witness_save((lock), &__CONCAT(n, __wf), &__CONCAT(n, __wl)) 192 193#define WITNESS_RESTORE(lock, n) \ 194 witness_restore((lock), __CONCAT(n, __wf), __CONCAT(n, __wl)) 195 196#else /* WITNESS */ 197#define WITNESS_INIT(lock) (lock)->lo_flags |= LO_INITIALIZED 198#define WITNESS_DESTROY(lock) (lock)->lo_flags &= ~LO_INITIALIZED 199#define WITNESS_LOCK(lock, flags, file, line) 200#define WITNESS_UNLOCK(lock, flags, file, line) 201#define WITNESS_SLEEP(check, lock) 202#define WITNESS_SAVE_DECL(n) 203#define WITNESS_SAVE(lock, n) 204#define WITNESS_RESTORE(lock, n) 205#endif /* WITNESS */ 206 207#endif /* _KERNEL */ 208#endif /* _SYS_LOCK_H_ */ 209