2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
26 * Mach Operating System
27 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
28 * All Rights Reserved.
30 * Permission to use, copy, modify and distribute this software and its
31 * documentation is hereby granted, provided that both the copyright
32 * notice and this permission notice appear in all copies of the
33 * software, derivative works or modified versions, and any portions
34 * thereof, and that both notices appear in supporting documentation.
36 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
37 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
40 * Carnegie Mellon requests users of this software to return to
42 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
43 * School of Computer Science
44 * Carnegie Mellon University
45 * Pittsburgh PA 15213-3890
47 * any improvements or extensions that they make and grant Carnegie Mellon
48 * the rights to redistribute these changes.
52 * Author: Avadis Tevanian, Jr., Michael Wayne Young
55 * Locking primitives implementation
59 #include <mach_ldebug.h>
61 #include <kern/lock.h>
62 #include <kern/locks.h>
63 #include <kern/kalloc.h>
64 #include <kern/misc_protos.h>
65 #include <kern/thread.h>
66 #include <kern/processor.h>
67 #include <kern/cpu_data.h>
68 #include <kern/cpu_number.h>
69 #include <kern/sched_prim.h>
71 #include <kern/debug.h>
75 #include <ddb/db_command.h>
76 #include <ddb/db_output.h>
77 #include <ddb/db_sym.h>
78 #include <ddb/db_print.h>
82 #include <ppc/Firmware.h>
85 #include <sys/kdebug.h>
87 #define LCK_RW_LCK_EXCLUSIVE_CODE 0x100
88 #define LCK_RW_LCK_EXCLUSIVE1_CODE 0x101
89 #define LCK_RW_LCK_SHARED_CODE 0x102
90 #define LCK_RW_LCK_SH_TO_EX_CODE 0x103
91 #define LCK_RW_LCK_SH_TO_EX1_CODE 0x104
92 #define LCK_RW_LCK_EX_TO_SH_CODE 0x105
95 #define ANY_LOCK_DEBUG (USLOCK_DEBUG || LOCK_DEBUG || MUTEX_DEBUG)
97 unsigned int LcksOpts
=0;
98 unsigned int lock_wait_time
[2] = { (unsigned int)-1, 100 } ;
103 void db_print_simple_lock(
108 #endif /* MACH_KDB */
113 * Perform simple lock checks.
115 int uslock_check
= 1;
116 int max_lock_loops
= 100000000;
117 decl_simple_lock_data(extern , printf_lock
)
118 decl_simple_lock_data(extern , panic_lock
)
120 decl_simple_lock_data(extern , kdb_lock
)
121 #endif /* MACH_KDB */
122 #endif /* USLOCK_DEBUG */
126 * We often want to know the addresses of the callers
127 * of the various lock routines. However, this information
128 * is only used for debugging and statistics.
131 #define INVALID_PC ((void *) VM_MAX_KERNEL_ADDRESS)
132 #define INVALID_THREAD ((void *) VM_MAX_KERNEL_ADDRESS)
134 #define OBTAIN_PC(pc,l) ((pc) = (void *) GET_RETURN_PC(&(l)))
135 #define DECL_PC(pc) pc_t pc;
136 #else /* ANY_LOCK_DEBUG */
140 * Eliminate lint complaints about unused local pc variables.
142 #define OBTAIN_PC(pc,l) ++pc
144 #define OBTAIN_PC(pc,l)
146 #endif /* USLOCK_DEBUG */
150 * Portable lock package implementation of usimple_locks.
154 #define USLDBG(stmt) stmt
155 void usld_lock_init(usimple_lock_t
, unsigned short);
156 void usld_lock_pre(usimple_lock_t
, pc_t
);
157 void usld_lock_post(usimple_lock_t
, pc_t
);
158 void usld_unlock(usimple_lock_t
, pc_t
);
159 void usld_lock_try_pre(usimple_lock_t
, pc_t
);
160 void usld_lock_try_post(usimple_lock_t
, pc_t
);
161 int usld_lock_common_checks(usimple_lock_t
, char *);
162 #else /* USLOCK_DEBUG */
164 #endif /* USLOCK_DEBUG */
167 * Routine: lck_spin_alloc_init
176 if ((lck
= (lck_spin_t
*)kalloc(sizeof(lck_spin_t
))) != 0)
177 lck_spin_init(lck
, grp
, attr
);
183 * Routine: lck_spin_free
190 lck_spin_destroy(lck
, grp
);
191 kfree(lck
, sizeof(lck_spin_t
));
195 * Routine: lck_spin_init
201 __unused lck_attr_t
*attr
)
203 usimple_lock_init((usimple_lock_t
) lck
, 0);
204 lck_grp_reference(grp
);
205 lck_grp_lckcnt_incr(grp
, LCK_TYPE_SPIN
);
209 * Routine: lck_spin_destroy
216 if (lck
->lck_spin_data
[0] == LCK_SPIN_TAG_DESTROYED
)
218 lck
->lck_spin_data
[0] = LCK_SPIN_TAG_DESTROYED
;
219 lck_grp_lckcnt_decr(grp
, LCK_TYPE_SPIN
);
220 lck_grp_deallocate(grp
);
225 * Routine: lck_spin_lock
231 usimple_lock((usimple_lock_t
) lck
);
235 * Routine: lck_spin_unlock
241 usimple_unlock((usimple_lock_t
) lck
);
246 * Routine: lck_spin_try_lock
252 usimple_lock_try((usimple_lock_t
) lck
);
256 * Initialize a usimple_lock.
258 * No change in preemption state.
263 __unused
unsigned short tag
)
265 #ifndef MACHINE_SIMPLE_LOCK
266 USLDBG(usld_lock_init(l
, tag
));
267 hw_lock_init(&l
->interlock
);
269 simple_lock_init((simple_lock_t
)l
,tag
);
275 * Acquire a usimple_lock.
277 * Returns with preemption disabled. Note
278 * that the hw_lock routines are responsible for
279 * maintaining preemption state.
285 #ifndef MACHINE_SIMPLE_LOCK
289 USLDBG(usld_lock_pre(l
, pc
));
291 if(!hw_lock_to(&l
->interlock
, LockTimeOut
)) /* Try to get the lock with a timeout */
292 panic("simple lock deadlock detection - l=%08X, cpu=%d, ret=%08X", l
, cpu_number(), pc
);
294 USLDBG(usld_lock_post(l
, pc
));
296 simple_lock((simple_lock_t
)l
);
302 * Release a usimple_lock.
304 * Returns with preemption enabled. Note
305 * that the hw_lock routines are responsible for
306 * maintaining preemption state.
312 #ifndef MACHINE_SIMPLE_LOCK
316 USLDBG(usld_unlock(l
, pc
));
317 hw_lock_unlock(&l
->interlock
);
319 simple_unlock_rwmb((simple_lock_t
)l
);
325 * Conditionally acquire a usimple_lock.
327 * On success, returns with preemption disabled.
328 * On failure, returns with preemption in the same state
329 * as when first invoked. Note that the hw_lock routines
330 * are responsible for maintaining preemption state.
332 * XXX No stats are gathered on a miss; I preserved this
333 * behavior from the original assembly-language code, but
334 * doesn't it make sense to log misses? XXX
340 #ifndef MACHINE_SIMPLE_LOCK
342 unsigned int success
;
345 USLDBG(usld_lock_try_pre(l
, pc
));
346 if ((success
= hw_lock_try(&l
->interlock
))) {
347 USLDBG(usld_lock_try_post(l
, pc
));
351 return(simple_lock_try((simple_lock_t
)l
));
357 * States of a usimple_lock. The default when initializing
358 * a usimple_lock is setting it up for debug checking.
360 #define USLOCK_CHECKED 0x0001 /* lock is being checked */
361 #define USLOCK_TAKEN 0x0002 /* lock has been taken */
362 #define USLOCK_INIT 0xBAA0 /* lock has been initialized */
363 #define USLOCK_INITIALIZED (USLOCK_INIT|USLOCK_CHECKED)
364 #define USLOCK_CHECKING(l) (uslock_check && \
365 ((l)->debug.state & USLOCK_CHECKED))
368 * Trace activities of a particularly interesting lock.
370 void usl_trace(usimple_lock_t
, int, pc_t
, const char *);
374 * Initialize the debugging information contained
380 __unused
unsigned short tag
)
382 if (l
== USIMPLE_LOCK_NULL
)
383 panic("lock initialization: null lock pointer");
384 l
->lock_type
= USLOCK_TAG
;
385 l
->debug
.state
= uslock_check
? USLOCK_INITIALIZED
: 0;
386 l
->debug
.lock_cpu
= l
->debug
.unlock_cpu
= 0;
387 l
->debug
.lock_pc
= l
->debug
.unlock_pc
= INVALID_PC
;
388 l
->debug
.lock_thread
= l
->debug
.unlock_thread
= INVALID_THREAD
;
389 l
->debug
.duration
[0] = l
->debug
.duration
[1] = 0;
390 l
->debug
.unlock_cpu
= l
->debug
.unlock_cpu
= 0;
391 l
->debug
.unlock_pc
= l
->debug
.unlock_pc
= INVALID_PC
;
392 l
->debug
.unlock_thread
= l
->debug
.unlock_thread
= INVALID_THREAD
;
397 * These checks apply to all usimple_locks, not just
398 * those with USLOCK_CHECKED turned on.
401 usld_lock_common_checks(
405 if (l
== USIMPLE_LOCK_NULL
)
406 panic("%s: null lock pointer", caller
);
407 if (l
->lock_type
!= USLOCK_TAG
)
408 panic("%s: 0x%x is not a usimple lock", caller
, (integer_t
) l
);
409 if (!(l
->debug
.state
& USLOCK_INIT
))
410 panic("%s: 0x%x is not an initialized lock",
411 caller
, (integer_t
) l
);
412 return USLOCK_CHECKING(l
);
417 * Debug checks on a usimple_lock just before attempting
426 char caller
[] = "usimple_lock";
429 if (!usld_lock_common_checks(l
, caller
))
433 * Note that we have a weird case where we are getting a lock when we are]
434 * in the process of putting the system to sleep. We are running with no
435 * current threads, therefore we can't tell if we are trying to retake a lock
436 * we have or someone on the other processor has it. Therefore we just
437 * ignore this test if the locking thread is 0.
440 if ((l
->debug
.state
& USLOCK_TAKEN
) && l
->debug
.lock_thread
&&
441 l
->debug
.lock_thread
== (void *) current_thread()) {
442 printf("%s: lock 0x%x already locked (at 0x%x) by",
443 caller
, (integer_t
) l
, l
->debug
.lock_pc
);
444 printf(" current thread 0x%x (new attempt at pc 0x%x)\n",
445 l
->debug
.lock_thread
, pc
);
448 mp_disable_preemption();
449 usl_trace(l
, cpu_number(), pc
, caller
);
450 mp_enable_preemption();
455 * Debug checks on a usimple_lock just after acquiring it.
457 * Pre-emption has been disabled at this point,
458 * so we are safe in using cpu_number.
466 char caller
[] = "successful usimple_lock";
469 if (!usld_lock_common_checks(l
, caller
))
472 if (!((l
->debug
.state
& ~USLOCK_TAKEN
) == USLOCK_INITIALIZED
))
473 panic("%s: lock 0x%x became uninitialized",
474 caller
, (integer_t
) l
);
475 if ((l
->debug
.state
& USLOCK_TAKEN
))
476 panic("%s: lock 0x%x became TAKEN by someone else",
477 caller
, (integer_t
) l
);
479 mycpu
= cpu_number();
480 l
->debug
.lock_thread
= (void *)current_thread();
481 l
->debug
.state
|= USLOCK_TAKEN
;
482 l
->debug
.lock_pc
= pc
;
483 l
->debug
.lock_cpu
= mycpu
;
485 usl_trace(l
, mycpu
, pc
, caller
);
490 * Debug checks on a usimple_lock just before
491 * releasing it. Note that the caller has not
492 * yet released the hardware lock.
494 * Preemption is still disabled, so there's
495 * no problem using cpu_number.
503 char caller
[] = "usimple_unlock";
506 if (!usld_lock_common_checks(l
, caller
))
509 mycpu
= cpu_number();
511 if (!(l
->debug
.state
& USLOCK_TAKEN
))
512 panic("%s: lock 0x%x hasn't been taken",
513 caller
, (integer_t
) l
);
514 if (l
->debug
.lock_thread
!= (void *) current_thread())
515 panic("%s: unlocking lock 0x%x, owned by thread 0x%x",
516 caller
, (integer_t
) l
, l
->debug
.lock_thread
);
517 if (l
->debug
.lock_cpu
!= mycpu
) {
518 printf("%s: unlocking lock 0x%x on cpu 0x%x",
519 caller
, (integer_t
) l
, mycpu
);
520 printf(" (acquired on cpu 0x%x)\n", l
->debug
.lock_cpu
);
523 usl_trace(l
, mycpu
, pc
, caller
);
525 l
->debug
.unlock_thread
= l
->debug
.lock_thread
;
526 l
->debug
.lock_thread
= INVALID_PC
;
527 l
->debug
.state
&= ~USLOCK_TAKEN
;
528 l
->debug
.unlock_pc
= pc
;
529 l
->debug
.unlock_cpu
= mycpu
;
534 * Debug checks on a usimple_lock just before
535 * attempting to acquire it.
537 * Preemption isn't guaranteed to be disabled.
544 char caller
[] = "usimple_lock_try";
546 if (!usld_lock_common_checks(l
, caller
))
548 mp_disable_preemption();
549 usl_trace(l
, cpu_number(), pc
, caller
);
550 mp_enable_preemption();
555 * Debug checks on a usimple_lock just after
556 * successfully attempting to acquire it.
558 * Preemption has been disabled by the
559 * lock acquisition attempt, so it's safe
568 char caller
[] = "successful usimple_lock_try";
570 if (!usld_lock_common_checks(l
, caller
))
573 if (!((l
->debug
.state
& ~USLOCK_TAKEN
) == USLOCK_INITIALIZED
))
574 panic("%s: lock 0x%x became uninitialized",
575 caller
, (integer_t
) l
);
576 if ((l
->debug
.state
& USLOCK_TAKEN
))
577 panic("%s: lock 0x%x became TAKEN by someone else",
578 caller
, (integer_t
) l
);
580 mycpu
= cpu_number();
581 l
->debug
.lock_thread
= (void *) current_thread();
582 l
->debug
.state
|= USLOCK_TAKEN
;
583 l
->debug
.lock_pc
= pc
;
584 l
->debug
.lock_cpu
= mycpu
;
586 usl_trace(l
, mycpu
, pc
, caller
);
591 * For very special cases, set traced_lock to point to a
592 * specific lock of interest. The result is a series of
593 * XPRs showing lock operations on that lock. The lock_seq
594 * value is used to show the order of those operations.
596 usimple_lock_t traced_lock
;
597 unsigned int lock_seq
;
604 const char * op_name
)
606 if (traced_lock
== l
) {
608 "seq %d, cpu %d, %s @ %x\n",
609 (integer_t
) lock_seq
, (integer_t
) mycpu
,
610 (integer_t
) op_name
, (integer_t
) pc
, 0);
616 #endif /* USLOCK_DEBUG */
619 * Routine: lock_alloc
621 * Allocate a lock for external users who cannot
622 * hard-code the structure definition into their
624 * For now just use kalloc, but a zone is probably
635 if ((l
= (lock_t
*)kalloc(sizeof(lock_t
))) != 0)
636 lock_init(l
, can_sleep
, tag
, tag1
);
643 * Free a lock allocated for external users.
644 * For now just use kfree, but a zone is probably
651 kfree(l
, sizeof(lock_t
));
658 * Initialize a lock; required before use.
659 * Note that clients declare the "struct lock"
660 * variables and then initialize them, rather
661 * than getting a new one from this module.
667 __unused
unsigned short tag
,
670 (void) memset((void *) l
, 0, sizeof(lock_t
));
672 simple_lock_init(&l
->interlock
, tag1
);
673 l
->want_write
= FALSE
;
674 l
->want_upgrade
= FALSE
;
676 l
->can_sleep
= can_sleep
;
681 * Sleep locks. These use the same data structure and algorithm
682 * as the spin locks, but the process sleeps while it is waiting
683 * for the lock. These work on uniprocessor systems.
686 #define DECREMENTER_TIMEOUT 1000000
693 boolean_t lock_miss
= FALSE
;
696 #endif /* MACH_LDEBUG */
698 simple_lock(&l
->interlock
);
701 decrementer
= DECREMENTER_TIMEOUT
;
702 #endif /* MACH_LDEBUG */
705 * Try to acquire the want_write bit.
707 while (l
->want_write
) {
712 i
= lock_wait_time
[l
->can_sleep
? 1 : 0];
714 simple_unlock(&l
->interlock
);
717 Debugger("timeout - want_write");
718 #endif /* MACH_LDEBUG */
719 while (--i
!= 0 && l
->want_write
)
721 simple_lock(&l
->interlock
);
724 if (l
->can_sleep
&& l
->want_write
) {
726 thread_sleep_simple_lock((event_t
) l
,
727 simple_lock_addr(l
->interlock
),
729 /* interlock relocked */
732 l
->want_write
= TRUE
;
734 /* Wait for readers (and upgrades) to finish */
737 decrementer
= DECREMENTER_TIMEOUT
;
738 #endif /* MACH_LDEBUG */
739 while ((l
->read_count
!= 0) || l
->want_upgrade
) {
744 i
= lock_wait_time
[l
->can_sleep
? 1 : 0];
746 simple_unlock(&l
->interlock
);
749 Debugger("timeout - wait for readers");
750 #endif /* MACH_LDEBUG */
751 while (--i
!= 0 && (l
->read_count
!= 0 ||
754 simple_lock(&l
->interlock
);
757 if (l
->can_sleep
&& (l
->read_count
!= 0 || l
->want_upgrade
)) {
759 thread_sleep_simple_lock((event_t
) l
,
760 simple_lock_addr(l
->interlock
),
762 /* interlock relocked */
766 simple_unlock(&l
->interlock
);
773 boolean_t do_wakeup
= FALSE
;
776 simple_lock(&l
->interlock
);
778 if (l
->read_count
!= 0) {
782 if (l
->want_upgrade
) {
783 l
->want_upgrade
= FALSE
;
786 l
->want_write
= FALSE
;
790 * There is no reason to wakeup a waiting thread
791 * if the read-count is non-zero. Consider:
792 * we must be dropping a read lock
793 * threads are waiting only if one wants a write lock
794 * if there are still readers, they can't proceed
797 if (l
->waiting
&& (l
->read_count
== 0)) {
802 simple_unlock(&l
->interlock
);
805 thread_wakeup((event_t
) l
);
815 #endif /* MACH_LDEBUG */
817 simple_lock(&l
->interlock
);
820 decrementer
= DECREMENTER_TIMEOUT
;
821 #endif /* MACH_LDEBUG */
822 while (l
->want_write
|| l
->want_upgrade
) {
823 i
= lock_wait_time
[l
->can_sleep
? 1 : 0];
826 simple_unlock(&l
->interlock
);
829 Debugger("timeout - wait no writers");
830 #endif /* MACH_LDEBUG */
831 while (--i
!= 0 && (l
->want_write
|| l
->want_upgrade
))
833 simple_lock(&l
->interlock
);
836 if (l
->can_sleep
&& (l
->want_write
|| l
->want_upgrade
)) {
838 thread_sleep_simple_lock((event_t
) l
,
839 simple_lock_addr(l
->interlock
),
841 /* interlock relocked */
847 simple_unlock(&l
->interlock
);
852 * Routine: lock_read_to_write
854 * Improves a read-only lock to one with
855 * write permission. If another reader has
856 * already requested an upgrade to a write lock,
857 * no lock is held upon return.
859 * Returns TRUE if the upgrade *failed*.
867 boolean_t do_wakeup
= FALSE
;
870 #endif /* MACH_LDEBUG */
872 simple_lock(&l
->interlock
);
876 if (l
->want_upgrade
) {
878 * Someone else has requested upgrade.
879 * Since we've released a read lock, wake
882 if (l
->waiting
&& (l
->read_count
== 0)) {
887 simple_unlock(&l
->interlock
);
890 thread_wakeup((event_t
) l
);
894 l
->want_upgrade
= TRUE
;
897 decrementer
= DECREMENTER_TIMEOUT
;
898 #endif /* MACH_LDEBUG */
899 while (l
->read_count
!= 0) {
900 i
= lock_wait_time
[l
->can_sleep
? 1 : 0];
903 simple_unlock(&l
->interlock
);
906 Debugger("timeout - read_count");
907 #endif /* MACH_LDEBUG */
908 while (--i
!= 0 && l
->read_count
!= 0)
910 simple_lock(&l
->interlock
);
913 if (l
->can_sleep
&& l
->read_count
!= 0) {
915 thread_sleep_simple_lock((event_t
) l
,
916 simple_lock_addr(l
->interlock
),
918 /* interlock relocked */
922 simple_unlock(&l
->interlock
);
931 boolean_t do_wakeup
= FALSE
;
933 simple_lock(&l
->interlock
);
937 l
->want_upgrade
= FALSE
;
939 l
->want_write
= FALSE
;
946 simple_unlock(&l
->interlock
);
949 thread_wakeup((event_t
) l
);
955 * Routine: lock_try_write
957 * Tries to get a write lock.
959 * Returns FALSE if the lock is not held on return.
968 simple_lock(&l
->interlock
);
970 if (l
->want_write
|| l
->want_upgrade
|| l
->read_count
) {
974 simple_unlock(&l
->interlock
);
982 l
->want_write
= TRUE
;
984 simple_unlock(&l
->interlock
);
990 * Routine: lock_try_read
992 * Tries to get a read lock.
994 * Returns FALSE if the lock is not held on return.
1003 simple_lock(&l
->interlock
);
1005 if (l
->want_write
|| l
->want_upgrade
) {
1006 simple_unlock(&l
->interlock
);
1012 simple_unlock(&l
->interlock
);
1020 * Routine: lck_rw_alloc_init
1028 if ((lck
= (lck_rw_t
*)kalloc(sizeof(lck_rw_t
))) != 0)
1029 lck_rw_init(lck
, grp
, attr
);
1035 * Routine: lck_rw_free
1041 lck_rw_destroy(lck
, grp
);
1042 kfree(lck
, sizeof(lck_rw_t
));
1046 * Routine: lck_rw_init
1052 __unused lck_attr_t
*attr
) {
1054 hw_lock_init(&lck
->interlock
);
1055 lck
->want_write
= FALSE
;
1056 lck
->want_upgrade
= FALSE
;
1057 lck
->read_count
= 0;
1058 lck
->can_sleep
= TRUE
;
1059 lck
->lck_rw_tag
= 0;
1061 lck_grp_reference(grp
);
1062 lck_grp_lckcnt_incr(grp
, LCK_TYPE_RW
);
1066 * Routine: lck_rw_destroy
1072 if (lck
->lck_rw_tag
== LCK_RW_TAG_DESTROYED
)
1074 lck
->lck_rw_tag
= LCK_RW_TAG_DESTROYED
;
1075 lck_grp_lckcnt_decr(grp
, LCK_TYPE_RW
);
1076 lck_grp_deallocate(grp
);
1081 * Sleep locks. These use the same data structure and algorithm
1082 * as the spin locks, but the process sleeps while it is waiting
1083 * for the lock. These work on uniprocessor systems.
1086 #define DECREMENTER_TIMEOUT 1000000
1090 * We need to disable interrupts while holding the mutex interlock
1091 * to prevent an IPI intervening.
1092 * Hence, local helper functions lck_interlock_lock()/lck_interlock_unlock().
1095 lck_interlock_lock(lck_rw_t
*lck
)
1099 istate
= ml_set_interrupts_enabled(FALSE
);
1100 hw_lock_lock(&lck
->interlock
);
1106 lck_interlock_unlock(lck_rw_t
*lck
, boolean_t istate
)
1108 hw_lock_unlock(&lck
->interlock
);
1109 ml_set_interrupts_enabled(istate
);
1113 * Routine: lck_rw_lock_exclusive
1116 lck_rw_lock_exclusive(
1120 boolean_t lock_miss
= FALSE
;
1124 #endif /* MACH_LDEBUG */
1127 istate
= lck_interlock_lock(lck
);
1130 decrementer
= DECREMENTER_TIMEOUT
;
1131 #endif /* MACH_LDEBUG */
1134 * Try to acquire the want_write bit.
1136 while (lck
->want_write
) {
1137 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EXCLUSIVE_CODE
) | DBG_FUNC_START
, (int)lck
, 0, 0, 0, 0);
1143 i
= lock_wait_time
[lck
->can_sleep
? 1 : 0];
1145 lck_interlock_unlock(lck
, istate
);
1148 Debugger("timeout - want_write");
1149 #endif /* MACH_LDEBUG */
1150 while (--i
!= 0 && lck
->want_write
)
1152 istate
= lck_interlock_lock(lck
);
1155 if (lck
->can_sleep
&& lck
->want_write
) {
1156 lck
->waiting
= TRUE
;
1157 res
= assert_wait((event_t
) lck
, THREAD_UNINT
);
1158 if (res
== THREAD_WAITING
) {
1159 lck_interlock_unlock(lck
, istate
);
1160 res
= thread_block(THREAD_CONTINUE_NULL
);
1161 istate
= lck_interlock_lock(lck
);
1164 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EXCLUSIVE_CODE
) | DBG_FUNC_END
, (int)lck
, res
, 0, 0, 0);
1166 lck
->want_write
= TRUE
;
1168 /* Wait for readers (and upgrades) to finish */
1171 decrementer
= DECREMENTER_TIMEOUT
;
1172 #endif /* MACH_LDEBUG */
1173 while ((lck
->read_count
!= 0) || lck
->want_upgrade
) {
1178 i
= lock_wait_time
[lck
->can_sleep
? 1 : 0];
1180 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EXCLUSIVE1_CODE
) | DBG_FUNC_START
,
1181 (int)lck
, lck
->read_count
, lck
->want_upgrade
, i
, 0);
1184 lck_interlock_unlock(lck
, istate
);
1187 Debugger("timeout - wait for readers");
1188 #endif /* MACH_LDEBUG */
1189 while (--i
!= 0 && (lck
->read_count
!= 0 ||
1192 istate
= lck_interlock_lock(lck
);
1195 if (lck
->can_sleep
&& (lck
->read_count
!= 0 || lck
->want_upgrade
)) {
1196 lck
->waiting
= TRUE
;
1197 res
= assert_wait((event_t
) lck
, THREAD_UNINT
);
1198 if (res
== THREAD_WAITING
) {
1199 lck_interlock_unlock(lck
, istate
);
1200 res
= thread_block(THREAD_CONTINUE_NULL
);
1201 istate
= lck_interlock_lock(lck
);
1204 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EXCLUSIVE1_CODE
) | DBG_FUNC_END
,
1205 (int)lck
, lck
->read_count
, lck
->want_upgrade
, res
, 0);
1208 lck_interlock_unlock(lck
, istate
);
1213 * Routine: lck_rw_done
1219 boolean_t do_wakeup
= FALSE
;
1220 lck_rw_type_t lck_rw_type
;
1224 istate
= lck_interlock_lock(lck
);
1226 if (lck
->read_count
!= 0) {
1227 lck_rw_type
= LCK_RW_TYPE_SHARED
;
1231 lck_rw_type
= LCK_RW_TYPE_EXCLUSIVE
;
1232 if (lck
->want_upgrade
)
1233 lck
->want_upgrade
= FALSE
;
1235 lck
->want_write
= FALSE
;
1239 * There is no reason to wakeup a waiting thread
1240 * if the read-count is non-zero. Consider:
1241 * we must be dropping a read lock
1242 * threads are waiting only if one wants a write lock
1243 * if there are still readers, they can't proceed
1246 if (lck
->waiting
&& (lck
->read_count
== 0)) {
1247 lck
->waiting
= FALSE
;
1251 lck_interlock_unlock(lck
, istate
);
1254 thread_wakeup((event_t
) lck
);
1255 return(lck_rw_type
);
1262 * Routine: lck_rw_unlock
1267 lck_rw_type_t lck_rw_type
)
1269 if (lck_rw_type
== LCK_RW_TYPE_SHARED
)
1270 lck_rw_unlock_shared(lck
);
1271 else if (lck_rw_type
== LCK_RW_TYPE_EXCLUSIVE
)
1272 lck_rw_unlock_exclusive(lck
);
1274 panic("lck_rw_unlock(): Invalid RW lock type: %d\n", lck_rw_type
);
1279 * Routine: lck_rw_unlock_shared
1282 lck_rw_unlock_shared(
1287 ret
= lck_rw_done(lck
);
1289 if (ret
!= LCK_RW_TYPE_SHARED
)
1290 panic("lck_rw_unlock(): lock held in mode: %d\n", ret
);
1295 * Routine: lck_rw_unlock_exclusive
1298 lck_rw_unlock_exclusive(
1303 ret
= lck_rw_done(lck
);
1305 if (ret
!= LCK_RW_TYPE_EXCLUSIVE
)
1306 panic("lck_rw_unlock_exclusive(): lock held in mode: %d\n", ret
);
1311 * Routine: lck_rw_lock
1316 lck_rw_type_t lck_rw_type
)
1318 if (lck_rw_type
== LCK_RW_TYPE_SHARED
)
1319 lck_rw_lock_shared(lck
);
1320 else if (lck_rw_type
== LCK_RW_TYPE_EXCLUSIVE
)
1321 lck_rw_lock_exclusive(lck
);
1323 panic("lck_rw_lock(): Invalid RW lock type: %x\n", lck_rw_type
);
1328 * Routine: lck_rw_lock_shared
1338 #endif /* MACH_LDEBUG */
1341 istate
= lck_interlock_lock(lck
);
1344 decrementer
= DECREMENTER_TIMEOUT
;
1345 #endif /* MACH_LDEBUG */
1346 while (lck
->want_write
|| lck
->want_upgrade
) {
1347 i
= lock_wait_time
[lck
->can_sleep
? 1 : 0];
1349 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SHARED_CODE
) | DBG_FUNC_START
,
1350 (int)lck
, lck
->want_write
, lck
->want_upgrade
, i
, 0);
1353 lck_interlock_unlock(lck
, istate
);
1356 Debugger("timeout - wait no writers");
1357 #endif /* MACH_LDEBUG */
1358 while (--i
!= 0 && (lck
->want_write
|| lck
->want_upgrade
))
1360 istate
= lck_interlock_lock(lck
);
1363 if (lck
->can_sleep
&& (lck
->want_write
|| lck
->want_upgrade
)) {
1364 lck
->waiting
= TRUE
;
1365 res
= assert_wait((event_t
) lck
, THREAD_UNINT
);
1366 if (res
== THREAD_WAITING
) {
1367 lck_interlock_unlock(lck
, istate
);
1368 res
= thread_block(THREAD_CONTINUE_NULL
);
1369 istate
= lck_interlock_lock(lck
);
1372 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SHARED_CODE
) | DBG_FUNC_END
,
1373 (int)lck
, lck
->want_write
, lck
->want_upgrade
, res
, 0);
1378 lck_interlock_unlock(lck
, istate
);
1383 * Routine: lck_rw_lock_shared_to_exclusive
1385 * Improves a read-only lock to one with
1386 * write permission. If another reader has
1387 * already requested an upgrade to a write lock,
1388 * no lock is held upon return.
1390 * Returns TRUE if the upgrade *failed*.
1394 lck_rw_lock_shared_to_exclusive(
1398 boolean_t do_wakeup
= FALSE
;
1402 #endif /* MACH_LDEBUG */
1405 istate
= lck_interlock_lock(lck
);
1409 if (lck
->want_upgrade
) {
1410 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SH_TO_EX_CODE
) | DBG_FUNC_START
,
1411 (int)lck
, lck
->read_count
, lck
->want_upgrade
, 0, 0);
1414 * Someone else has requested upgrade.
1415 * Since we've released a read lock, wake
1418 if (lck
->waiting
&& (lck
->read_count
== 0)) {
1419 lck
->waiting
= FALSE
;
1423 lck_interlock_unlock(lck
, istate
);
1426 thread_wakeup((event_t
) lck
);
1428 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SH_TO_EX_CODE
) | DBG_FUNC_END
,
1429 (int)lck
, lck
->read_count
, lck
->want_upgrade
, 0, 0);
1434 lck
->want_upgrade
= TRUE
;
1437 decrementer
= DECREMENTER_TIMEOUT
;
1438 #endif /* MACH_LDEBUG */
1439 while (lck
->read_count
!= 0) {
1440 i
= lock_wait_time
[lck
->can_sleep
? 1 : 0];
1442 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SH_TO_EX1_CODE
) | DBG_FUNC_START
,
1443 (int)lck
, lck
->read_count
, i
, 0, 0);
1446 lck_interlock_unlock(lck
, istate
);
1449 Debugger("timeout - read_count");
1450 #endif /* MACH_LDEBUG */
1451 while (--i
!= 0 && lck
->read_count
!= 0)
1453 istate
= lck_interlock_lock(lck
);
1456 if (lck
->can_sleep
&& lck
->read_count
!= 0) {
1457 lck
->waiting
= TRUE
;
1458 res
= assert_wait((event_t
) lck
, THREAD_UNINT
);
1459 if (res
== THREAD_WAITING
) {
1460 lck_interlock_unlock(lck
, istate
);
1461 res
= thread_block(THREAD_CONTINUE_NULL
);
1462 istate
= lck_interlock_lock(lck
);
1465 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SH_TO_EX1_CODE
) | DBG_FUNC_END
,
1466 (int)lck
, lck
->read_count
, 0, 0, 0);
1469 lck_interlock_unlock(lck
, istate
);
1475 * Routine: lck_rw_lock_exclusive_to_shared
1478 lck_rw_lock_exclusive_to_shared(
1481 boolean_t do_wakeup
= FALSE
;
1484 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EX_TO_SH_CODE
) | DBG_FUNC_START
,
1485 (int)lck
, lck
->want_write
, lck
->want_upgrade
, 0, 0);
1487 istate
= lck_interlock_lock(lck
);
1490 if (lck
->want_upgrade
)
1491 lck
->want_upgrade
= FALSE
;
1493 lck
->want_write
= FALSE
;
1496 lck
->waiting
= FALSE
;
1500 lck_interlock_unlock(lck
, istate
);
1503 thread_wakeup((event_t
) lck
);
1505 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EX_TO_SH_CODE
) | DBG_FUNC_END
,
1506 (int)lck
, lck
->want_write
, lck
->want_upgrade
, lck
->read_count
, 0);
1512 * Routine: lck_rw_try_lock
1517 lck_rw_type_t lck_rw_type
)
1519 if (lck_rw_type
== LCK_RW_TYPE_SHARED
)
1520 return(lck_rw_try_lock_shared(lck
));
1521 else if (lck_rw_type
== LCK_RW_TYPE_EXCLUSIVE
)
1522 return(lck_rw_try_lock_exclusive(lck
));
1524 panic("lck_rw_try_lock(): Invalid rw lock type: %x\n", lck_rw_type
);
1529 * Routine: lck_rw_try_lock_exclusive
1531 * Tries to get a write lock.
1533 * Returns FALSE if the lock is not held on return.
1537 lck_rw_try_lock_exclusive(
1542 istate
= lck_interlock_lock(lck
);
1544 if (lck
->want_write
|| lck
->want_upgrade
|| lck
->read_count
) {
1548 lck_interlock_unlock(lck
, istate
);
1556 lck
->want_write
= TRUE
;
1558 lck_interlock_unlock(lck
, istate
);
1564 * Routine: lck_rw_try_lock_shared
1566 * Tries to get a read lock.
1568 * Returns FALSE if the lock is not held on return.
1572 lck_rw_try_lock_shared(
1577 istate
= lck_interlock_lock(lck
);
1579 if (lck
->want_write
|| lck
->want_upgrade
) {
1580 lck_interlock_unlock(lck
, istate
);
1586 lck_interlock_unlock(lck
, istate
);
1592 * Routine: lck_mtx_alloc_init
1601 if ((lck
= (lck_mtx_t
*)kalloc(sizeof(lck_mtx_t
))) != 0)
1602 lck_mtx_init(lck
, grp
, attr
);
1608 * Routine: lck_mtx_free
1615 lck_mtx_destroy(lck
, grp
);
1616 kfree(lck
, sizeof(lck_mtx_t
));
1620 * Routine: lck_mtx_ext_init
1628 lck
->lck_mtx
.lck_mtx_ilk
= 0;
1629 lck
->lck_mtx
.lck_mtx_locked
= 0;
1630 lck
->lck_mtx
.lck_mtx_waiters
= 0;
1631 lck
->lck_mtx
.lck_mtx_pri
= 0;
1632 lck
->lck_mtx_attr
= 0;
1634 if ((attr
->lck_attr_val
) & LCK_ATTR_DEBUG
) {
1635 lck
->lck_mtx_deb
.pc
= 0;
1636 lck
->lck_mtx_deb
.thread
= 0;
1637 lck
->lck_mtx_deb
.type
= MUTEX_TAG
;
1638 lck
->lck_mtx_attr
|= LCK_MTX_ATTR_DEBUG
;
1641 lck
->lck_mtx_grp
= grp
;
1645 * Routine: lck_mtx_init
1653 lck_mtx_ext_t
*lck_ext
;
1655 if ((attr
!= LCK_ATTR_NULL
) && ((attr
->lck_attr_val
) & LCK_ATTR_DEBUG
)) {
1656 if ((lck_ext
= (lck_mtx_ext_t
*)kalloc(sizeof(lck_mtx_ext_t
))) != 0) {
1657 lck_mtx_ext_init(lck_ext
, grp
, attr
);
1658 lck
->lck_mtx_tag
= LCK_MTX_TAG_INDIRECT
;
1659 lck
->lck_mtx_ptr
= lck_ext
;
1662 lck
->lck_mtx_ilk
= 0;
1663 lck
->lck_mtx_locked
= 0;
1664 lck
->lck_mtx_waiters
= 0;
1665 lck
->lck_mtx_pri
= 0;
1667 lck_grp_reference(grp
);
1668 lck_grp_lckcnt_incr(grp
, LCK_TYPE_MTX
);
1672 * Routine: lck_mtx_destroy
1679 boolean_t lck_is_indirect
;
1681 if (lck
->lck_mtx_tag
== LCK_MTX_TAG_DESTROYED
)
1683 lck_is_indirect
= (lck
->lck_mtx_tag
== LCK_MTX_TAG_INDIRECT
);
1684 lck
->lck_mtx_tag
= LCK_MTX_TAG_DESTROYED
;
1685 if (lck_is_indirect
)
1686 kfree(lck
->lck_mtx_ptr
, sizeof(lck_mtx_ext_t
));
1687 lck_grp_lckcnt_decr(grp
, LCK_TYPE_MTX
);
1688 lck_grp_deallocate(grp
);
1693 * Routine: lck_mtx_assert
1697 __unused lck_mtx_t
*lck
,
1698 __unused
unsigned int type
)
1704 void db_show_one_lock(lock_t
*);
1710 db_printf("Read_count = 0x%x, %swant_upgrade, %swant_write, ",
1712 lock
->want_upgrade
? "" : "!",
1713 lock
->want_write
? "" : "!");
1714 db_printf("%swaiting, %scan_sleep\n",
1715 lock
->waiting
? "" : "!", lock
->can_sleep
? "" : "!");
1716 db_printf("Interlock:\n");
1717 db_show_one_simple_lock((db_expr_t
)simple_lock_addr(lock
->interlock
),
1718 TRUE
, (db_expr_t
)0, (char *)0);
1721 #endif /* MACH_KDB */
1724 * The C portion of the mutex package. These routines are only invoked
1725 * if the optimized assembler routines can't do the work.
1729 * Routine: lock_alloc
1731 * Allocate a mutex for external users who cannot
1732 * hard-code the structure definition into their
1734 * For now just use kalloc, but a zone is probably
1743 if ((m
= (mutex_t
*)kalloc(sizeof(mutex_t
))) != 0)
1749 * Routine: mutex_free
1751 * Free a mutex allocated for external users.
1752 * For now just use kfree, but a zone is probably
1759 kfree(m
, sizeof(mutex_t
));
1763 * Routine: _mutex_assert
1771 thread_t thread
= current_thread();
1774 if (panicstr
!= NULL
)
1777 holder
= (thread_t
) mutex
->lck_mtx
.lck_mtx_locked
;
1781 if (thread
!= holder
)
1782 panic("mutex %x not owned\n", mutex
);
1786 if (thread
== holder
)
1787 panic("mutex %x owned\n", mutex
);
1795 * Routines to print out simple_locks and mutexes in a nicely-formatted
1799 char *simple_lock_labels
= "ENTRY ILK THREAD DURATION CALLER";
1800 char *mutex_labels
= "ENTRY LOCKED WAITERS THREAD CALLER";
1803 db_show_one_simple_lock (
1805 boolean_t have_addr
,
1809 simple_lock_t saddr
= (simple_lock_t
)addr
;
1811 if (saddr
== (simple_lock_t
)0 || !have_addr
) {
1812 db_error ("No simple_lock\n");
1815 else if (saddr
->lock_type
!= USLOCK_TAG
)
1816 db_error ("Not a simple_lock\n");
1817 #endif /* USLOCK_DEBUG */
1819 db_printf ("%s\n", simple_lock_labels
);
1820 db_print_simple_lock (saddr
);
1824 db_print_simple_lock (
1828 db_printf ("%08x %3d", addr
, *hw_lock_addr(addr
->interlock
));
1830 db_printf (" %08x", addr
->debug
.lock_thread
);
1831 db_printf (" %08x ", addr
->debug
.duration
[1]);
1832 db_printsym ((int)addr
->debug
.lock_pc
, DB_STGY_ANY
);
1833 #endif /* USLOCK_DEBUG */
1840 boolean_t have_addr
,
1844 mutex_t
* maddr
= (mutex_t
*)addr
;
1846 if (maddr
== (mutex_t
*)0 || !have_addr
)
1847 db_error ("No mutex\n");
1849 else if (maddr
->type
!= MUTEX_TAG
)
1850 db_error ("Not a mutex\n");
1851 #endif /* MACH_LDEBUG */
1853 db_printf ("%s\n", mutex_labels
);
1854 db_print_mutex (maddr
);
1861 db_printf ("%08x %6d %7d",
1862 addr
, *addr
, addr
->lck_mtx
.lck_mtx_waiters
);
1864 db_printf (" %08x ", addr
->thread
);
1865 db_printsym (addr
->pc
, DB_STGY_ANY
);
1866 #endif /* MACH_LDEBUG */
1870 #endif /* MACH_KDB */