Deleted Added
full compact
kern_mutex.c (154482) kern_mutex.c (154484)
1/*-
2 * Copyright (c) 1998 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.

--- 20 unchanged lines hidden (view full) ---

29 * and BSDI $Id: synch_machdep.c,v 2.3.2.39 2000/04/27 03:10:25 cp Exp $
30 */
31
32/*
33 * Machine independent bits of mutex implementation.
34 */
35
36#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1998 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.

--- 20 unchanged lines hidden (view full) ---

29 * and BSDI $Id: synch_machdep.c,v 2.3.2.39 2000/04/27 03:10:25 cp Exp $
30 */
31
32/*
33 * Machine independent bits of mutex implementation.
34 */
35
36#include <sys/cdefs.h>
37__FBSDID("$FreeBSD: head/sys/kern/kern_mutex.c 154482 2006-01-17 16:47:42Z jhb $");
37__FBSDID("$FreeBSD: head/sys/kern/kern_mutex.c 154484 2006-01-17 16:55:17Z jhb $");
38
39#include "opt_adaptive_mutexes.h"
40#include "opt_ddb.h"
41#include "opt_mprof.h"
42#include "opt_mutex_wake_all.h"
43#include "opt_sched.h"
44
45#include <sys/param.h>

--- 227 unchanged lines hidden (view full) ---

273 * Function versions of the inlined __mtx_* macros. These are used by
274 * modules and can also be called from assembly language if needed.
275 */
276void
277_mtx_lock_flags(struct mtx *m, int opts, const char *file, int line)
278{
279
280 MPASS(curthread != NULL);
38
39#include "opt_adaptive_mutexes.h"
40#include "opt_ddb.h"
41#include "opt_mprof.h"
42#include "opt_mutex_wake_all.h"
43#include "opt_sched.h"
44
45#include <sys/param.h>

--- 227 unchanged lines hidden (view full) ---

273 * Function versions of the inlined __mtx_* macros. These are used by
274 * modules and can also be called from assembly language if needed.
275 */
276void
277_mtx_lock_flags(struct mtx *m, int opts, const char *file, int line)
278{
279
280 MPASS(curthread != NULL);
281 KASSERT(LO_CLASSINDEX(&m->mtx_object) == LOCK_CLASS_SLEEP_MUTEX,
281 KASSERT(LOCK_CLASS(&m->mtx_object) == &lock_class_mtx_sleep,
282 ("mtx_lock() of spin mutex %s @ %s:%d", m->mtx_object.lo_name,
283 file, line));
284 WITNESS_CHECKORDER(&m->mtx_object, opts | LOP_NEWORDER | LOP_EXCLUSIVE,
285 file, line);
286 _get_sleep_lock(m, curthread, opts, file, line);
287 LOCK_LOG_LOCK("LOCK", &m->mtx_object, opts, m->mtx_recurse, file,
288 line);
289 WITNESS_LOCK(&m->mtx_object, opts | LOP_EXCLUSIVE, file, line);

--- 8 unchanged lines hidden (view full) ---

298#endif
299}
300
301void
302_mtx_unlock_flags(struct mtx *m, int opts, const char *file, int line)
303{
304
305 MPASS(curthread != NULL);
282 ("mtx_lock() of spin mutex %s @ %s:%d", m->mtx_object.lo_name,
283 file, line));
284 WITNESS_CHECKORDER(&m->mtx_object, opts | LOP_NEWORDER | LOP_EXCLUSIVE,
285 file, line);
286 _get_sleep_lock(m, curthread, opts, file, line);
287 LOCK_LOG_LOCK("LOCK", &m->mtx_object, opts, m->mtx_recurse, file,
288 line);
289 WITNESS_LOCK(&m->mtx_object, opts | LOP_EXCLUSIVE, file, line);

--- 8 unchanged lines hidden (view full) ---

298#endif
299}
300
301void
302_mtx_unlock_flags(struct mtx *m, int opts, const char *file, int line)
303{
304
305 MPASS(curthread != NULL);
306 KASSERT(LO_CLASSINDEX(&m->mtx_object) == LOCK_CLASS_SLEEP_MUTEX,
306 KASSERT(LOCK_CLASS(&m->mtx_object) == &lock_class_mtx_sleep,
307 ("mtx_unlock() of spin mutex %s @ %s:%d", m->mtx_object.lo_name,
308 file, line));
309 WITNESS_UNLOCK(&m->mtx_object, opts | LOP_EXCLUSIVE, file, line);
310 LOCK_LOG_LOCK("UNLOCK", &m->mtx_object, opts, m->mtx_recurse, file,
311 line);
312 mtx_assert(m, MA_OWNED);
313#ifdef MUTEX_PROFILING
314 if (m->mtx_acqtime != 0) {

--- 62 unchanged lines hidden (view full) ---

377 _rel_sleep_lock(m, curthread, opts, file, line);
378}
379
380void
381_mtx_lock_spin_flags(struct mtx *m, int opts, const char *file, int line)
382{
383
384 MPASS(curthread != NULL);
307 ("mtx_unlock() of spin mutex %s @ %s:%d", m->mtx_object.lo_name,
308 file, line));
309 WITNESS_UNLOCK(&m->mtx_object, opts | LOP_EXCLUSIVE, file, line);
310 LOCK_LOG_LOCK("UNLOCK", &m->mtx_object, opts, m->mtx_recurse, file,
311 line);
312 mtx_assert(m, MA_OWNED);
313#ifdef MUTEX_PROFILING
314 if (m->mtx_acqtime != 0) {

--- 62 unchanged lines hidden (view full) ---

377 _rel_sleep_lock(m, curthread, opts, file, line);
378}
379
380void
381_mtx_lock_spin_flags(struct mtx *m, int opts, const char *file, int line)
382{
383
384 MPASS(curthread != NULL);
385 KASSERT(LO_CLASSINDEX(&m->mtx_object) == LOCK_CLASS_SPIN_MUTEX,
385 KASSERT(LOCK_CLASS(&m->mtx_object) == &lock_class_mtx_spin,
386 ("mtx_lock_spin() of sleep mutex %s @ %s:%d",
387 m->mtx_object.lo_name, file, line));
388 WITNESS_CHECKORDER(&m->mtx_object, opts | LOP_NEWORDER | LOP_EXCLUSIVE,
389 file, line);
390 _get_spin_lock(m, curthread, opts, file, line);
391 LOCK_LOG_LOCK("LOCK", &m->mtx_object, opts, m->mtx_recurse, file,
392 line);
393 WITNESS_LOCK(&m->mtx_object, opts | LOP_EXCLUSIVE, file, line);
394}
395
396void
397_mtx_unlock_spin_flags(struct mtx *m, int opts, const char *file, int line)
398{
399
400 MPASS(curthread != NULL);
386 ("mtx_lock_spin() of sleep mutex %s @ %s:%d",
387 m->mtx_object.lo_name, file, line));
388 WITNESS_CHECKORDER(&m->mtx_object, opts | LOP_NEWORDER | LOP_EXCLUSIVE,
389 file, line);
390 _get_spin_lock(m, curthread, opts, file, line);
391 LOCK_LOG_LOCK("LOCK", &m->mtx_object, opts, m->mtx_recurse, file,
392 line);
393 WITNESS_LOCK(&m->mtx_object, opts | LOP_EXCLUSIVE, file, line);
394}
395
396void
397_mtx_unlock_spin_flags(struct mtx *m, int opts, const char *file, int line)
398{
399
400 MPASS(curthread != NULL);
401 KASSERT(LO_CLASSINDEX(&m->mtx_object) == LOCK_CLASS_SPIN_MUTEX,
401 KASSERT(LOCK_CLASS(&m->mtx_object) == &lock_class_mtx_spin,
402 ("mtx_unlock_spin() of sleep mutex %s @ %s:%d",
403 m->mtx_object.lo_name, file, line));
404 WITNESS_UNLOCK(&m->mtx_object, opts | LOP_EXCLUSIVE, file, line);
405 LOCK_LOG_LOCK("UNLOCK", &m->mtx_object, opts, m->mtx_recurse, file,
406 line);
407 mtx_assert(m, MA_OWNED);
408 _rel_spin_lock(m);
409}

--- 4 unchanged lines hidden (view full) ---

414 * is already owned, it will recursively acquire the lock.
415 */
416int
417_mtx_trylock(struct mtx *m, int opts, const char *file, int line)
418{
419 int rval;
420
421 MPASS(curthread != NULL);
402 ("mtx_unlock_spin() of sleep mutex %s @ %s:%d",
403 m->mtx_object.lo_name, file, line));
404 WITNESS_UNLOCK(&m->mtx_object, opts | LOP_EXCLUSIVE, file, line);
405 LOCK_LOG_LOCK("UNLOCK", &m->mtx_object, opts, m->mtx_recurse, file,
406 line);
407 mtx_assert(m, MA_OWNED);
408 _rel_spin_lock(m);
409}

--- 4 unchanged lines hidden (view full) ---

414 * is already owned, it will recursively acquire the lock.
415 */
416int
417_mtx_trylock(struct mtx *m, int opts, const char *file, int line)
418{
419 int rval;
420
421 MPASS(curthread != NULL);
422 KASSERT(LO_CLASSINDEX(&m->mtx_object) == LOCK_CLASS_SLEEP_MUTEX,
422 KASSERT(LOCK_CLASS(&m->mtx_object) == &lock_class_mtx_sleep,
423 ("mtx_trylock() of spin mutex %s @ %s:%d", m->mtx_object.lo_name,
424 file, line));
425
426 if (mtx_owned(m) && (m->mtx_object.lo_flags & LO_RECURSABLE) != 0) {
427 m->mtx_recurse++;
428 atomic_set_ptr(&m->mtx_lock, MTX_RECURSED);
429 rval = 1;
430 } else

--- 394 unchanged lines hidden (view full) ---

825 * Mutex initialization routine; initialize lock `m' of type contained in
826 * `opts' with options contained in `opts' and name `name.' The optional
827 * lock type `type' is used as a general lock category name for use with
828 * witness.
829 */
830void
831mtx_init(struct mtx *m, const char *name, const char *type, int opts)
832{
423 ("mtx_trylock() of spin mutex %s @ %s:%d", m->mtx_object.lo_name,
424 file, line));
425
426 if (mtx_owned(m) && (m->mtx_object.lo_flags & LO_RECURSABLE) != 0) {
427 m->mtx_recurse++;
428 atomic_set_ptr(&m->mtx_lock, MTX_RECURSED);
429 rval = 1;
430 } else

--- 394 unchanged lines hidden (view full) ---

825 * Mutex initialization routine; initialize lock `m' of type contained in
826 * `opts' with options contained in `opts' and name `name.' The optional
827 * lock type `type' is used as a general lock category name for use with
828 * witness.
829 */
830void
831mtx_init(struct mtx *m, const char *name, const char *type, int opts)
832{
833 struct lock_object *lock;
833 struct lock_class *class;
834 int flags;
834
835 MPASS((opts & ~(MTX_SPIN | MTX_QUIET | MTX_RECURSE |
836 MTX_NOWITNESS | MTX_DUPOK)) == 0);
837
838#ifdef MUTEX_DEBUG
839 /* Diagnostic and error correction */
840 mtx_validate(m);
841#endif
842
835
836 MPASS((opts & ~(MTX_SPIN | MTX_QUIET | MTX_RECURSE |
837 MTX_NOWITNESS | MTX_DUPOK)) == 0);
838
839#ifdef MUTEX_DEBUG
840 /* Diagnostic and error correction */
841 mtx_validate(m);
842#endif
843
843 lock = &m->mtx_object;
844 KASSERT((lock->lo_flags & LO_INITIALIZED) == 0,
845 ("mutex \"%s\" %p already initialized", name, m));
846 bzero(m, sizeof(*m));
844 /* Determine lock class and lock flags. */
847 if (opts & MTX_SPIN)
845 if (opts & MTX_SPIN)
848 lock->lo_flags = LOCK_CLASS_SPIN_MUTEX << LO_CLASSSHIFT;
846 class = &lock_class_mtx_spin;
849 else
847 else
850 lock->lo_flags = LOCK_CLASS_SLEEP_MUTEX << LO_CLASSSHIFT;
851 lock->lo_name = name;
852 lock->lo_type = type != NULL ? type : name;
848 class = &lock_class_mtx_sleep;
849 flags = 0;
853 if (opts & MTX_QUIET)
850 if (opts & MTX_QUIET)
854 lock->lo_flags |= LO_QUIET;
851 flags |= LO_QUIET;
855 if (opts & MTX_RECURSE)
852 if (opts & MTX_RECURSE)
856 lock->lo_flags |= LO_RECURSABLE;
853 flags |= LO_RECURSABLE;
857 if ((opts & MTX_NOWITNESS) == 0)
854 if ((opts & MTX_NOWITNESS) == 0)
858 lock->lo_flags |= LO_WITNESS;
855 flags |= LO_WITNESS;
859 if (opts & MTX_DUPOK)
856 if (opts & MTX_DUPOK)
860 lock->lo_flags |= LO_DUPOK;
857 flags |= LO_DUPOK;
861
858
859 /* Initialize mutex. */
862 m->mtx_lock = MTX_UNOWNED;
860 m->mtx_lock = MTX_UNOWNED;
861 m->mtx_recurse = 0;
862#ifdef MUTEX_PROFILING
863 m->mtx_acqtime = 0;
864 m->mtx_filename = NULL;
865 m->mtx_lineno = 0;
866 m->mtx_contest_holding = 0;
867 m->mtx_contest_locking = 0;
868#endif
863
869
864 LOCK_LOG_INIT(lock, opts);
865
866 WITNESS_INIT(lock);
870 lock_init(&m->mtx_object, class, name, type, flags);
867}
868
869/*
870 * Remove lock `m' from all_mtx queue. We don't allow MTX_QUIET to be
871 * passed in as a flag here because if the corresponding mtx_init() was
872 * called with MTX_QUIET set, then it will already be set in the mutex's
873 * flags.
874 */
875void
876mtx_destroy(struct mtx *m)
877{
878
871}
872
873/*
874 * Remove lock `m' from all_mtx queue. We don't allow MTX_QUIET to be
875 * passed in as a flag here because if the corresponding mtx_init() was
876 * called with MTX_QUIET set, then it will already be set in the mutex's
877 * flags.
878 */
879void
880mtx_destroy(struct mtx *m)
881{
882
879 LOCK_LOG_DESTROY(&m->mtx_object, 0);
880
881 if (!mtx_owned(m))
882 MPASS(mtx_unowned(m));
883 else {
884 MPASS((m->mtx_lock & (MTX_RECURSED|MTX_CONTESTED)) == 0);
885
886 /* Perform the non-mtx related part of mtx_unlock_spin(). */
883 if (!mtx_owned(m))
884 MPASS(mtx_unowned(m));
885 else {
886 MPASS((m->mtx_lock & (MTX_RECURSED|MTX_CONTESTED)) == 0);
887
888 /* Perform the non-mtx related part of mtx_unlock_spin(). */
887 if (LO_CLASSINDEX(&m->mtx_object) == LOCK_CLASS_SPIN_MUTEX)
889 if (LOCK_CLASS(&m->mtx_object) == &lock_class_mtx_spin)
888 spinlock_exit();
889
890 /* Tell witness this isn't locked to make it happy. */
891 WITNESS_UNLOCK(&m->mtx_object, LOP_EXCLUSIVE, __FILE__,
892 __LINE__);
893 }
894
890 spinlock_exit();
891
892 /* Tell witness this isn't locked to make it happy. */
893 WITNESS_UNLOCK(&m->mtx_object, LOP_EXCLUSIVE, __FILE__,
894 __LINE__);
895 }
896
895 WITNESS_DESTROY(&m->mtx_object);
897 lock_destroy(&m->mtx_object);
896}
897
898/*
899 * Intialize the mutex code and system mutexes. This is called from the MD
900 * startup code prior to mi_startup(). The per-CPU data space needs to be
901 * setup before this is called.
902 */
903void

--- 8 unchanged lines hidden (view full) ---

912 */
913 mtx_init(&Giant, "Giant", NULL, MTX_DEF | MTX_RECURSE);
914 mtx_init(&sched_lock, "sched lock", NULL, MTX_SPIN | MTX_RECURSE);
915 mtx_init(&proc0.p_mtx, "process lock", NULL, MTX_DEF | MTX_DUPOK);
916 mtx_init(&devmtx, "cdev", NULL, MTX_DEF);
917 mtx_lock(&Giant);
918}
919
898}
899
900/*
901 * Intialize the mutex code and system mutexes. This is called from the MD
902 * startup code prior to mi_startup(). The per-CPU data space needs to be
903 * setup before this is called.
904 */
905void

--- 8 unchanged lines hidden (view full) ---

914 */
915 mtx_init(&Giant, "Giant", NULL, MTX_DEF | MTX_RECURSE);
916 mtx_init(&sched_lock, "sched lock", NULL, MTX_SPIN | MTX_RECURSE);
917 mtx_init(&proc0.p_mtx, "process lock", NULL, MTX_DEF | MTX_DUPOK);
918 mtx_init(&devmtx, "cdev", NULL, MTX_DEF);
919 mtx_lock(&Giant);
920}
921
920#if LOCK_DEBUG > 0 || defined(DDB)
921/* XXX: This is not mutex-specific. */
922struct lock_class *lock_classes[LOCK_CLASS_MAX + 1] = {
923 &lock_class_mtx_spin,
924 &lock_class_mtx_sleep,
925 &lock_class_sx,
926};
927#endif
928
929#ifdef DDB
922#ifdef DDB
930/* XXX: This function is not mutex-specific. */
931DB_SHOW_COMMAND(lock, db_show_lock)
932{
933 struct lock_object *lock;
934 struct lock_class *class;
935
936 if (!have_addr)
937 return;
938 lock = (struct lock_object *)addr;
939 if (LO_CLASSINDEX(lock) > LOCK_CLASS_MAX) {
940 db_printf("Unknown lock class: %d\n", LO_CLASSINDEX(lock));
941 return;
942 }
943 class = LOCK_CLASS(lock);
944 db_printf(" class: %s\n", class->lc_name);
945 db_printf(" name: %s\n", lock->lo_name);
946 if (lock->lo_type && lock->lo_type != lock->lo_name)
947 db_printf(" type: %s\n", lock->lo_type);
948 class->lc_ddb_show(lock);
949}
950
951void
952db_show_mtx(struct lock_object *lock)
953{
954 struct thread *td;
955 struct mtx *m;
956
957 m = (struct mtx *)lock;
958
959 db_printf(" flags: {");
923void
924db_show_mtx(struct lock_object *lock)
925{
926 struct thread *td;
927 struct mtx *m;
928
929 m = (struct mtx *)lock;
930
931 db_printf(" flags: {");
960 if (LO_CLASSINDEX(lock) == LOCK_CLASS_SPIN_MUTEX)
932 if (LOCK_CLASS(lock) == &lock_class_mtx_spin)
961 db_printf("SPIN");
962 else
963 db_printf("DEF");
964 if (m->mtx_object.lo_flags & LO_RECURSABLE)
965 db_printf(", RECURSE");
966 if (m->mtx_object.lo_flags & LO_DUPOK)
967 db_printf(", DUPOK");
968 db_printf("}\n");

--- 20 unchanged lines hidden ---
933 db_printf("SPIN");
934 else
935 db_printf("DEF");
936 if (m->mtx_object.lo_flags & LO_RECURSABLE)
937 db_printf(", RECURSE");
938 if (m->mtx_object.lo_flags & LO_DUPOK)
939 db_printf(", DUPOK");
940 db_printf("}\n");

--- 20 unchanged lines hidden ---