kern_sx.c (169776) | kern_sx.c (169780) |
---|---|
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: --- 26 unchanged lines hidden (view full) --- 35 * Priority propagation will not generally raise the priority of lock holders, 36 * so should not be relied upon in combination with sx locks. 37 */ 38 39#include "opt_adaptive_sx.h" 40#include "opt_ddb.h" 41 42#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: --- 26 unchanged lines hidden (view full) --- 35 * Priority propagation will not generally raise the priority of lock holders, 36 * so should not be relied upon in combination with sx locks. 37 */ 38 39#include "opt_adaptive_sx.h" 40#include "opt_ddb.h" 41 42#include <sys/cdefs.h> |
43__FBSDID("$FreeBSD: head/sys/kern/kern_sx.c 169776 2007-05-19 20:18:12Z jhb $"); | 43__FBSDID("$FreeBSD: head/sys/kern/kern_sx.c 169780 2007-05-19 21:26:05Z jhb $"); |
44 45#include <sys/param.h> 46#include <sys/ktr.h> 47#include <sys/lock.h> 48#include <sys/lock_profile.h> 49#include <sys/mutex.h> 50#include <sys/proc.h> 51#include <sys/sleepqueue.h> --- 82 unchanged lines hidden (view full) --- 134} 135 136int 137unlock_sx(struct lock_object *lock) 138{ 139 struct sx *sx; 140 141 sx = (struct sx *)lock; | 44 45#include <sys/param.h> 46#include <sys/ktr.h> 47#include <sys/lock.h> 48#include <sys/lock_profile.h> 49#include <sys/mutex.h> 50#include <sys/proc.h> 51#include <sys/sleepqueue.h> --- 82 unchanged lines hidden (view full) --- 134} 135 136int 137unlock_sx(struct lock_object *lock) 138{ 139 struct sx *sx; 140 141 sx = (struct sx *)lock; |
142 sx_assert(sx, SX_LOCKED | SX_NOTRECURSED); | 142 sx_assert(sx, SA_LOCKED | SA_NOTRECURSED); |
143 if (sx_xlocked(sx)) { 144 sx_xunlock(sx); 145 return (1); 146 } else { 147 sx_sunlock(sx); 148 return (0); 149 } 150} --- 117 unchanged lines hidden (view full) --- 268 269void 270_sx_sunlock(struct sx *sx, const char *file, int line) 271{ 272 273 MPASS(curthread != NULL); 274 KASSERT(sx->sx_lock != SX_LOCK_DESTROYED, 275 ("sx_sunlock() of destroyed sx @ %s:%d", file, line)); | 143 if (sx_xlocked(sx)) { 144 sx_xunlock(sx); 145 return (1); 146 } else { 147 sx_sunlock(sx); 148 return (0); 149 } 150} --- 117 unchanged lines hidden (view full) --- 268 269void 270_sx_sunlock(struct sx *sx, const char *file, int line) 271{ 272 273 MPASS(curthread != NULL); 274 KASSERT(sx->sx_lock != SX_LOCK_DESTROYED, 275 ("sx_sunlock() of destroyed sx @ %s:%d", file, line)); |
276 _sx_assert(sx, SX_SLOCKED, file, line); | 276 _sx_assert(sx, SA_SLOCKED, file, line); |
277 curthread->td_locks--; 278 WITNESS_UNLOCK(&sx->lock_object, 0, file, line); 279 LOCK_LOG_LOCK("SUNLOCK", &sx->lock_object, 0, 0, file, line); 280 if (SX_SHARERS(sx->sx_lock) == 0) 281 lock_profile_release_lock(&sx->lock_object); 282 __sx_sunlock(sx, file, line); 283} 284 285void 286_sx_xunlock(struct sx *sx, const char *file, int line) 287{ 288 289 MPASS(curthread != NULL); 290 KASSERT(sx->sx_lock != SX_LOCK_DESTROYED, 291 ("sx_xunlock() of destroyed sx @ %s:%d", file, line)); | 277 curthread->td_locks--; 278 WITNESS_UNLOCK(&sx->lock_object, 0, file, line); 279 LOCK_LOG_LOCK("SUNLOCK", &sx->lock_object, 0, 0, file, line); 280 if (SX_SHARERS(sx->sx_lock) == 0) 281 lock_profile_release_lock(&sx->lock_object); 282 __sx_sunlock(sx, file, line); 283} 284 285void 286_sx_xunlock(struct sx *sx, const char *file, int line) 287{ 288 289 MPASS(curthread != NULL); 290 KASSERT(sx->sx_lock != SX_LOCK_DESTROYED, 291 ("sx_xunlock() of destroyed sx @ %s:%d", file, line)); |
292 _sx_assert(sx, SX_XLOCKED, file, line); | 292 _sx_assert(sx, SA_XLOCKED, file, line); |
293 curthread->td_locks--; 294 WITNESS_UNLOCK(&sx->lock_object, LOP_EXCLUSIVE, file, line); 295 LOCK_LOG_LOCK("XUNLOCK", &sx->lock_object, 0, sx->sx_recurse, file, 296 line); 297 if (!sx_recursed(sx)) 298 lock_profile_release_lock(&sx->lock_object); 299 __sx_xunlock(sx, curthread, file, line); 300} --- 6 unchanged lines hidden (view full) --- 307int 308_sx_try_upgrade(struct sx *sx, const char *file, int line) 309{ 310 uintptr_t x; 311 int success; 312 313 KASSERT(sx->sx_lock != SX_LOCK_DESTROYED, 314 ("sx_try_upgrade() of destroyed sx @ %s:%d", file, line)); | 293 curthread->td_locks--; 294 WITNESS_UNLOCK(&sx->lock_object, LOP_EXCLUSIVE, file, line); 295 LOCK_LOG_LOCK("XUNLOCK", &sx->lock_object, 0, sx->sx_recurse, file, 296 line); 297 if (!sx_recursed(sx)) 298 lock_profile_release_lock(&sx->lock_object); 299 __sx_xunlock(sx, curthread, file, line); 300} --- 6 unchanged lines hidden (view full) --- 307int 308_sx_try_upgrade(struct sx *sx, const char *file, int line) 309{ 310 uintptr_t x; 311 int success; 312 313 KASSERT(sx->sx_lock != SX_LOCK_DESTROYED, 314 ("sx_try_upgrade() of destroyed sx @ %s:%d", file, line)); |
315 _sx_assert(sx, SX_SLOCKED, file, line); | 315 _sx_assert(sx, SA_SLOCKED, file, line); |
316 317 /* 318 * Try to switch from one shared lock to an exclusive lock. We need 319 * to maintain the SX_LOCK_EXCLUSIVE_WAITERS flag if set so that 320 * we will wake up the exclusive waiters when we drop the lock. 321 */ 322 x = sx->sx_lock & SX_LOCK_EXCLUSIVE_WAITERS; 323 success = atomic_cmpset_ptr(&sx->sx_lock, SX_SHARERS_LOCK(1) | x, --- 10 unchanged lines hidden (view full) --- 334 */ 335void 336_sx_downgrade(struct sx *sx, const char *file, int line) 337{ 338 uintptr_t x; 339 340 KASSERT(sx->sx_lock != SX_LOCK_DESTROYED, 341 ("sx_downgrade() of destroyed sx @ %s:%d", file, line)); | 316 317 /* 318 * Try to switch from one shared lock to an exclusive lock. We need 319 * to maintain the SX_LOCK_EXCLUSIVE_WAITERS flag if set so that 320 * we will wake up the exclusive waiters when we drop the lock. 321 */ 322 x = sx->sx_lock & SX_LOCK_EXCLUSIVE_WAITERS; 323 success = atomic_cmpset_ptr(&sx->sx_lock, SX_SHARERS_LOCK(1) | x, --- 10 unchanged lines hidden (view full) --- 334 */ 335void 336_sx_downgrade(struct sx *sx, const char *file, int line) 337{ 338 uintptr_t x; 339 340 KASSERT(sx->sx_lock != SX_LOCK_DESTROYED, 341 ("sx_downgrade() of destroyed sx @ %s:%d", file, line)); |
342 _sx_assert(sx, SX_XLOCKED | SX_NOTRECURSED, file, line); | 342 _sx_assert(sx, SA_XLOCKED | SA_NOTRECURSED, file, line); |
343#ifndef INVARIANTS 344 if (sx_recursed(sx)) 345 panic("downgrade of a recursed lock"); 346#endif 347 348 WITNESS_DOWNGRADE(&sx->lock_object, 0, file, line); 349 350 /* --- 489 unchanged lines hidden (view full) --- 840{ 841#ifndef WITNESS 842 int slocked = 0; 843#endif 844 845 if (panicstr != NULL) 846 return; 847 switch (what) { | 343#ifndef INVARIANTS 344 if (sx_recursed(sx)) 345 panic("downgrade of a recursed lock"); 346#endif 347 348 WITNESS_DOWNGRADE(&sx->lock_object, 0, file, line); 349 350 /* --- 489 unchanged lines hidden (view full) --- 840{ 841#ifndef WITNESS 842 int slocked = 0; 843#endif 844 845 if (panicstr != NULL) 846 return; 847 switch (what) { |
848 case SX_SLOCKED: 849 case SX_SLOCKED | SX_NOTRECURSED: 850 case SX_SLOCKED | SX_RECURSED: | 848 case SA_SLOCKED: 849 case SA_SLOCKED | SA_NOTRECURSED: 850 case SA_SLOCKED | SA_RECURSED: |
851#ifndef WITNESS 852 slocked = 1; 853 /* FALLTHROUGH */ 854#endif | 851#ifndef WITNESS 852 slocked = 1; 853 /* FALLTHROUGH */ 854#endif |
855 case SX_LOCKED: 856 case SX_LOCKED | SX_NOTRECURSED: 857 case SX_LOCKED | SX_RECURSED: | 855 case SA_LOCKED: 856 case SA_LOCKED | SA_NOTRECURSED: 857 case SA_LOCKED | SA_RECURSED: |
858#ifdef WITNESS 859 witness_assert(&sx->lock_object, what, file, line); 860#else 861 /* 862 * If some other thread has an exclusive lock or we 863 * have one and are asserting a shared lock, fail. 864 * Also, if no one has a lock at all, fail. 865 */ 866 if (sx->sx_lock == SX_LOCK_UNLOCKED || 867 (!(sx->sx_lock & SX_LOCK_SHARED) && (slocked || 868 sx_xholder(sx) != curthread))) 869 panic("Lock %s not %slocked @ %s:%d\n", 870 sx->lock_object.lo_name, slocked ? "share " : "", 871 file, line); 872 873 if (!(sx->sx_lock & SX_LOCK_SHARED)) { 874 if (sx_recursed(sx)) { | 858#ifdef WITNESS 859 witness_assert(&sx->lock_object, what, file, line); 860#else 861 /* 862 * If some other thread has an exclusive lock or we 863 * have one and are asserting a shared lock, fail. 864 * Also, if no one has a lock at all, fail. 865 */ 866 if (sx->sx_lock == SX_LOCK_UNLOCKED || 867 (!(sx->sx_lock & SX_LOCK_SHARED) && (slocked || 868 sx_xholder(sx) != curthread))) 869 panic("Lock %s not %slocked @ %s:%d\n", 870 sx->lock_object.lo_name, slocked ? "share " : "", 871 file, line); 872 873 if (!(sx->sx_lock & SX_LOCK_SHARED)) { 874 if (sx_recursed(sx)) { |
875 if (what & SX_NOTRECURSED) | 875 if (what & SA_NOTRECURSED) |
876 panic("Lock %s recursed @ %s:%d\n", 877 sx->lock_object.lo_name, file, 878 line); | 876 panic("Lock %s recursed @ %s:%d\n", 877 sx->lock_object.lo_name, file, 878 line); |
879 } else if (what & SX_RECURSED) | 879 } else if (what & SA_RECURSED) |
880 panic("Lock %s not recursed @ %s:%d\n", 881 sx->lock_object.lo_name, file, line); 882 } 883#endif 884 break; | 880 panic("Lock %s not recursed @ %s:%d\n", 881 sx->lock_object.lo_name, file, line); 882 } 883#endif 884 break; |
885 case SX_XLOCKED: 886 case SX_XLOCKED | SX_NOTRECURSED: 887 case SX_XLOCKED | SX_RECURSED: | 885 case SA_XLOCKED: 886 case SA_XLOCKED | SA_NOTRECURSED: 887 case SA_XLOCKED | SA_RECURSED: |
888 if (sx_xholder(sx) != curthread) 889 panic("Lock %s not exclusively locked @ %s:%d\n", 890 sx->lock_object.lo_name, file, line); 891 if (sx_recursed(sx)) { | 888 if (sx_xholder(sx) != curthread) 889 panic("Lock %s not exclusively locked @ %s:%d\n", 890 sx->lock_object.lo_name, file, line); 891 if (sx_recursed(sx)) { |
892 if (what & SX_NOTRECURSED) | 892 if (what & SA_NOTRECURSED) |
893 panic("Lock %s recursed @ %s:%d\n", 894 sx->lock_object.lo_name, file, line); | 893 panic("Lock %s recursed @ %s:%d\n", 894 sx->lock_object.lo_name, file, line); |
895 } else if (what & SX_RECURSED) | 895 } else if (what & SA_RECURSED) |
896 panic("Lock %s not recursed @ %s:%d\n", 897 sx->lock_object.lo_name, file, line); 898 break; | 896 panic("Lock %s not recursed @ %s:%d\n", 897 sx->lock_object.lo_name, file, line); 898 break; |
899 case SX_UNLOCKED: | 899 case SA_UNLOCKED: |
900#ifdef WITNESS 901 witness_assert(&sx->lock_object, what, file, line); 902#else 903 /* 904 * If we hold an exclusve lock fail. We can't 905 * reliably check to see if we hold a shared lock or 906 * not. 907 */ --- 85 unchanged lines hidden --- | 900#ifdef WITNESS 901 witness_assert(&sx->lock_object, what, file, line); 902#else 903 /* 904 * If we hold an exclusve lock fail. We can't 905 * reliably check to see if we hold a shared lock or 906 * not. 907 */ --- 85 unchanged lines hidden --- |