kern_sx.c (227309) | kern_sx.c (227588) |
---|---|
1/*- 2 * Copyright (c) 2007 Attilio Rao <attilio@freebsd.org> 3 * Copyright (c) 2001 Jason Evans <jasone@freebsd.org> 4 * 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: --- 27 unchanged lines hidden (view full) --- 36 * so should not be relied upon in combination with sx locks. 37 */ 38 39#include "opt_ddb.h" 40#include "opt_kdtrace.h" 41#include "opt_no_adaptive_sx.h" 42 43#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2007 Attilio Rao <attilio@freebsd.org> 3 * Copyright (c) 2001 Jason Evans <jasone@freebsd.org> 4 * 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: --- 27 unchanged lines hidden (view full) --- 36 * so should not be relied upon in combination with sx locks. 37 */ 38 39#include "opt_ddb.h" 40#include "opt_kdtrace.h" 41#include "opt_no_adaptive_sx.h" 42 43#include <sys/cdefs.h> |
44__FBSDID("$FreeBSD: head/sys/kern/kern_sx.c 227309 2011-11-07 15:43:11Z ed $"); | 44__FBSDID("$FreeBSD: head/sys/kern/kern_sx.c 227588 2011-11-16 21:51:17Z pjd $"); |
45 46#include <sys/param.h> 47#include <sys/ktr.h> 48#include <sys/lock.h> 49#include <sys/mutex.h> 50#include <sys/proc.h> 51#include <sys/sleepqueue.h> 52#include <sys/sx.h> --- 47 unchanged lines hidden (view full) --- 100 101/* 102 * Returns true if an exclusive lock is recursed. It assumes 103 * curthread currently has an exclusive lock. 104 */ 105#define sx_recurse lock_object.lo_data 106#define sx_recursed(sx) ((sx)->sx_recurse != 0) 107 | 45 46#include <sys/param.h> 47#include <sys/ktr.h> 48#include <sys/lock.h> 49#include <sys/mutex.h> 50#include <sys/proc.h> 51#include <sys/sleepqueue.h> 52#include <sys/sx.h> --- 47 unchanged lines hidden (view full) --- 100 101/* 102 * Returns true if an exclusive lock is recursed. It assumes 103 * curthread currently has an exclusive lock. 104 */ 105#define sx_recurse lock_object.lo_data 106#define sx_recursed(sx) ((sx)->sx_recurse != 0) 107 |
108static void assert_sx(struct lock_object *lock, int what); | 108static void assert_sx(const struct lock_object *lock, int what); |
109#ifdef DDB | 109#ifdef DDB |
110static void db_show_sx(struct lock_object *lock); | 110static void db_show_sx(const struct lock_object *lock); |
111#endif 112static void lock_sx(struct lock_object *lock, int how); 113#ifdef KDTRACE_HOOKS | 111#endif 112static void lock_sx(struct lock_object *lock, int how); 113#ifdef KDTRACE_HOOKS |
114static int owner_sx(struct lock_object *lock, struct thread **owner); | 114static int owner_sx(const struct lock_object *lock, struct thread **owner); |
115#endif 116static int unlock_sx(struct lock_object *lock); 117 118struct lock_class lock_class_sx = { 119 .lc_name = "sx", 120 .lc_flags = LC_SLEEPLOCK | LC_SLEEPABLE | LC_RECURSABLE | LC_UPGRADABLE, 121 .lc_assert = assert_sx, 122#ifdef DDB --- 14 unchanged lines hidden (view full) --- 137static u_int asx_retries = 10; 138static u_int asx_loops = 10000; 139static SYSCTL_NODE(_debug, OID_AUTO, sx, CTLFLAG_RD, NULL, "sxlock debugging"); 140SYSCTL_UINT(_debug_sx, OID_AUTO, retries, CTLFLAG_RW, &asx_retries, 0, ""); 141SYSCTL_UINT(_debug_sx, OID_AUTO, loops, CTLFLAG_RW, &asx_loops, 0, ""); 142#endif 143 144void | 115#endif 116static int unlock_sx(struct lock_object *lock); 117 118struct lock_class lock_class_sx = { 119 .lc_name = "sx", 120 .lc_flags = LC_SLEEPLOCK | LC_SLEEPABLE | LC_RECURSABLE | LC_UPGRADABLE, 121 .lc_assert = assert_sx, 122#ifdef DDB --- 14 unchanged lines hidden (view full) --- 137static u_int asx_retries = 10; 138static u_int asx_loops = 10000; 139static SYSCTL_NODE(_debug, OID_AUTO, sx, CTLFLAG_RD, NULL, "sxlock debugging"); 140SYSCTL_UINT(_debug_sx, OID_AUTO, retries, CTLFLAG_RW, &asx_retries, 0, ""); 141SYSCTL_UINT(_debug_sx, OID_AUTO, loops, CTLFLAG_RW, &asx_loops, 0, ""); 142#endif 143 144void |
145assert_sx(struct lock_object *lock, int what) | 145assert_sx(const struct lock_object *lock, int what) |
146{ 147 | 146{ 147 |
148 sx_assert((struct sx *)lock, what); | 148 sx_assert((const struct sx *)lock, what); |
149} 150 151void 152lock_sx(struct lock_object *lock, int how) 153{ 154 struct sx *sx; 155 156 sx = (struct sx *)lock; --- 16 unchanged lines hidden (view full) --- 173 } else { 174 sx_sunlock(sx); 175 return (0); 176 } 177} 178 179#ifdef KDTRACE_HOOKS 180int | 149} 150 151void 152lock_sx(struct lock_object *lock, int how) 153{ 154 struct sx *sx; 155 156 sx = (struct sx *)lock; --- 16 unchanged lines hidden (view full) --- 173 } else { 174 sx_sunlock(sx); 175 return (0); 176 } 177} 178 179#ifdef KDTRACE_HOOKS 180int |
181owner_sx(struct lock_object *lock, struct thread **owner) | 181owner_sx(const struct lock_object *lock, struct thread **owner) |
182{ | 182{ |
183 struct sx *sx = (struct sx *)lock; | 183 const struct sx *sx = (const struct sx *)lock; |
184 uintptr_t x = sx->sx_lock; 185 186 *owner = (struct thread *)SX_OWNER(x); 187 return ((x & SX_LOCK_SHARED) != 0 ? (SX_SHARERS(x) != 0) : 188 (*owner != NULL)); 189} 190#endif 191 --- 808 unchanged lines hidden (view full) --- 1000#endif 1001 1002/* 1003 * In the non-WITNESS case, sx_assert() can only detect that at least 1004 * *some* thread owns an slock, but it cannot guarantee that *this* 1005 * thread owns an slock. 1006 */ 1007void | 184 uintptr_t x = sx->sx_lock; 185 186 *owner = (struct thread *)SX_OWNER(x); 187 return ((x & SX_LOCK_SHARED) != 0 ? (SX_SHARERS(x) != 0) : 188 (*owner != NULL)); 189} 190#endif 191 --- 808 unchanged lines hidden (view full) --- 1000#endif 1001 1002/* 1003 * In the non-WITNESS case, sx_assert() can only detect that at least 1004 * *some* thread owns an slock, but it cannot guarantee that *this* 1005 * thread owns an slock. 1006 */ 1007void |
1008_sx_assert(struct sx *sx, int what, const char *file, int line) | 1008_sx_assert(const struct sx *sx, int what, const char *file, int line) |
1009{ 1010#ifndef WITNESS 1011 int slocked = 0; 1012#endif 1013 1014 if (panicstr != NULL) 1015 return; 1016 switch (what) { --- 66 unchanged lines hidden (view full) --- 1083 panic("Unknown sx lock assertion: %d @ %s:%d", what, file, 1084 line); 1085 } 1086} 1087#endif /* INVARIANT_SUPPORT */ 1088 1089#ifdef DDB 1090static void | 1009{ 1010#ifndef WITNESS 1011 int slocked = 0; 1012#endif 1013 1014 if (panicstr != NULL) 1015 return; 1016 switch (what) { --- 66 unchanged lines hidden (view full) --- 1083 panic("Unknown sx lock assertion: %d @ %s:%d", what, file, 1084 line); 1085 } 1086} 1087#endif /* INVARIANT_SUPPORT */ 1088 1089#ifdef DDB 1090static void |
1091db_show_sx(struct lock_object *lock) | 1091db_show_sx(const struct lock_object *lock) |
1092{ 1093 struct thread *td; | 1092{ 1093 struct thread *td; |
1094 struct sx *sx; | 1094 const struct sx *sx; |
1095 | 1095 |
1096 sx = (struct sx *)lock; | 1096 sx = (const struct sx *)lock; |
1097 1098 db_printf(" state: "); 1099 if (sx->sx_lock == SX_LOCK_UNLOCKED) 1100 db_printf("UNLOCKED\n"); 1101 else if (sx->sx_lock == SX_LOCK_DESTROYED) { 1102 db_printf("DESTROYED\n"); 1103 return; 1104 } else if (sx->sx_lock & SX_LOCK_SHARED) --- 57 unchanged lines hidden --- | 1097 1098 db_printf(" state: "); 1099 if (sx->sx_lock == SX_LOCK_UNLOCKED) 1100 db_printf("UNLOCKED\n"); 1101 else if (sx->sx_lock == SX_LOCK_DESTROYED) { 1102 db_printf("DESTROYED\n"); 1103 return; 1104 } else if (sx->sx_lock & SX_LOCK_SHARED) --- 57 unchanged lines hidden --- |