1 /* $OpenBSD: witness.h,v 1.1 2017/04/20 12:59:36 visa Exp $ */ 2 3 /*- 4 * Copyright (c) 1997 Berkeley Software Design, Inc. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Berkeley Software Design Inc's name may not be used to endorse or 15 * promote products derived from this software without specific prior 16 * written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * from BSDI Id: mutex.h,v 2.7.2.35 2000/04/27 03:10:26 cp 31 * $FreeBSD: head/sys/sys/lock.h 313908 2017-02-18 01:52:10Z mjg $ 32 */ 33 34 #ifndef _SYS_WITNESS_H_ 35 #define _SYS_WITNESS_H_ 36 37 #include <sys/_lock.h> 38 39 /* 40 * Lock classes are statically assigned an index into the global lock_classes 41 * array. Debugging code looks up the lock class for a given lock object 42 * by indexing the array. 43 */ 44 #define LO_CLASSINDEX(lock) \ 45 ((((lock)->lo_flags) & LO_CLASSMASK) >> LO_CLASSSHIFT) 46 #define LOCK_CLASS(lock) \ 47 (lock_classes[LO_CLASSINDEX((lock))]) 48 #define LOCK_CLASS_MAX \ 49 (LO_CLASSMASK >> LO_CLASSSHIFT) 50 51 /* 52 * Option flags passed to lock operations that witness also needs to know 53 * about or that are generic across all locks. 54 */ 55 #define LOP_NEWORDER 0x00000001 /* Define a new lock order. */ 56 #define LOP_QUIET 0x00000002 /* Don't log locking operations. */ 57 #define LOP_TRYLOCK 0x00000004 /* Don't check lock order. */ 58 #define LOP_EXCLUSIVE 0x00000008 /* Exclusive lock. */ 59 #define LOP_DUPOK 0x00000010 /* Don't check for duplicate acquires */ 60 61 /* Flags passed to witness_assert. */ 62 #define LA_MASKASSERT 0x000000ff /* Mask for witness defined asserts. */ 63 #define LA_UNLOCKED 0x00000000 /* Lock is unlocked. */ 64 #define LA_LOCKED 0x00000001 /* Lock is at least share locked. */ 65 #define LA_SLOCKED 0x00000002 /* Lock is exactly share locked. */ 66 #define LA_XLOCKED 0x00000004 /* Lock is exclusively locked. */ 67 #define LA_RECURSED 0x00000008 /* Lock is recursed. */ 68 #define LA_NOTRECURSED 0x00000010 /* Lock is not recursed. */ 69 70 #ifdef _KERNEL 71 72 void witness_initialize(void); 73 void witness_init(struct lock_object *, struct lock_type *); 74 int witness_defineorder(struct lock_object *, struct lock_object *); 75 void witness_checkorder(struct lock_object *, int, const char *, int, 76 struct lock_object *); 77 void witness_lock(struct lock_object *, int, const char *, int); 78 void witness_upgrade(struct lock_object *, int, const char *, int); 79 void witness_downgrade(struct lock_object *, int, const char *, int); 80 void witness_unlock(struct lock_object *, int, const char *, int); 81 void witness_save(struct lock_object *, const char **, int *); 82 void witness_restore(struct lock_object *, const char *, int); 83 int witness_warn(int, struct lock_object *, const char *, ...); 84 void witness_assert(const struct lock_object *, int, const char *, int); 85 void witness_display_spinlock(struct lock_object *, struct proc *, 86 int (*)(const char *, ...)); 87 int witness_line(struct lock_object *); 88 void witness_norelease(struct lock_object *); 89 void witness_releaseok(struct lock_object *); 90 const char *witness_file(struct lock_object *); 91 void witness_thread_exit(struct proc *); 92 93 #ifdef WITNESS 94 95 /* Flags for witness_warn(). */ 96 #define WARN_KERNELOK 0x01 /* Kernel lock is exempt from this check. */ 97 #define WARN_PANIC 0x02 /* Panic if check fails. */ 98 #define WARN_SLEEPOK 0x04 /* Sleepable locks are exempt from check. */ 99 100 #define WITNESS_INITIALIZE() \ 101 witness_initialize() 102 103 #define WITNESS_INIT(lock, type) \ 104 witness_init((lock), (type)) 105 106 #define WITNESS_CHECKORDER(lock, flags, file, line, interlock) \ 107 witness_checkorder((lock), (flags), (file), (line), (interlock)) 108 109 #define WITNESS_DEFINEORDER(lock1, lock2) \ 110 witness_defineorder((struct lock_object *)(lock1), \ 111 (struct lock_object *)(lock2)) 112 113 #define WITNESS_LOCK(lock, flags, file, line) \ 114 witness_lock((lock), (flags), (file), (line)) 115 116 #define WITNESS_UPGRADE(lock, flags, file, line) \ 117 witness_upgrade((lock), (flags), (file), (line)) 118 119 #define WITNESS_DOWNGRADE(lock, flags, file, line) \ 120 witness_downgrade((lock), (flags), (file), (line)) 121 122 #define WITNESS_UNLOCK(lock, flags, file, line) \ 123 witness_unlock((lock), (flags), (file), (line)) 124 125 #define WITNESS_CHECK(flags, lock, fmt, ...) \ 126 witness_warn((flags), (lock), (fmt), ## __VA_ARGS__) 127 128 #define WITNESS_WARN(flags, lock, fmt, ...) \ 129 witness_warn((flags), (lock), (fmt), ## __VA_ARGS__) 130 131 #define WITNESS_SAVE_DECL(n) \ 132 const char * __CONCAT(n, __wf); \ 133 int __CONCAT(n, __wl) 134 135 #define WITNESS_SAVE(lock, n) \ 136 witness_save((lock), &__CONCAT(n, __wf), &__CONCAT(n, __wl)) 137 138 #define WITNESS_RESTORE(lock, n) \ 139 witness_restore((lock), __CONCAT(n, __wf), __CONCAT(n, __wl)) 140 141 #define WITNESS_NORELEASE(lock) \ 142 witness_norelease(&(lock)->lock_object) 143 144 #define WITNESS_RELEASEOK(lock) \ 145 witness_releaseok(&(lock)->lock_object) 146 147 #define WITNESS_FILE(lock) \ 148 witness_file(lock) 149 150 #define WITNESS_LINE(lock) \ 151 witness_line(lock) 152 153 #define WITNESS_THREAD_EXIT(p) \ 154 witness_thread_exit((p)) 155 156 #else /* WITNESS */ 157 #define WITNESS_INITIALIZE() (void)0 158 #define WITNESS_INIT(lock, type) (void)0 159 #define WITNESS_DEFINEORDER(lock1, lock2) 0 160 #define WITNESS_CHECKORDER(lock, flags, file, line, interlock) (void)0 161 #define WITNESS_LOCK(lock, flags, file, line) (void)0 162 #define WITNESS_UPGRADE(lock, flags, file, line) (void)0 163 #define WITNESS_DOWNGRADE(lock, flags, file, line) (void)0 164 #define WITNESS_UNLOCK(lock, flags, file, line) (void)0 165 #define WITNESS_CHECK(flags, lock, fmt, ...) 0 166 #define WITNESS_WARN(flags, lock, fmt, ...) (void)0 167 #define WITNESS_SAVE_DECL(n) (void)0 168 #define WITNESS_SAVE(lock, n) (void)0 169 #define WITNESS_RESTORE(lock, n) (void)0 170 #define WITNESS_NORELEASE(lock) (void)0 171 #define WITNESS_RELEASEOK(lock) (void)0 172 #define WITNESS_THREAD_EXIT(p) (void)0 173 #define WITNESS_FILE(lock) ("?") 174 #define WITNESS_LINE(lock) (0) 175 #endif /* WITNESS */ 176 177 #endif /* _KERNEL */ 178 #endif /* _SYS_WITNESS_H_ */ 179