Deleted Added
full compact
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 ---