2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
27 * Mach Operating System
28 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
29 * All Rights Reserved.
31 * Permission to use, copy, modify and distribute this software and its
32 * documentation is hereby granted, provided that both the copyright
33 * notice and this permission notice appear in all copies of the
34 * software, derivative works or modified versions, and any portions
35 * thereof, and that both notices appear in supporting documentation.
37 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
38 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
39 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
41 * Carnegie Mellon requests users of this software to return to
43 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
44 * School of Computer Science
45 * Carnegie Mellon University
46 * Pittsburgh PA 15213-3890
48 * any improvements or extensions that they make and grant Carnegie Mellon
49 * the rights to redistribute these changes.
53 * Author: Avadis Tevanian, Jr., Michael Wayne Young
56 * Locking primitives implementation
60 #include <mach_ldebug.h>
62 #include <kern/lock.h>
63 #include <kern/locks.h>
64 #include <kern/kalloc.h>
65 #include <kern/misc_protos.h>
66 #include <kern/thread.h>
67 #include <kern/processor.h>
68 #include <kern/cpu_data.h>
69 #include <kern/cpu_number.h>
70 #include <kern/sched_prim.h>
72 #include <kern/debug.h>
76 #include <ddb/db_command.h>
77 #include <ddb/db_output.h>
78 #include <ddb/db_sym.h>
79 #include <ddb/db_print.h>
83 #include <ppc/Firmware.h>
86 #include <sys/kdebug.h>
88 #define LCK_RW_LCK_EXCLUSIVE_CODE 0x100
89 #define LCK_RW_LCK_EXCLUSIVE1_CODE 0x101
90 #define LCK_RW_LCK_SHARED_CODE 0x102
91 #define LCK_RW_LCK_SH_TO_EX_CODE 0x103
92 #define LCK_RW_LCK_SH_TO_EX1_CODE 0x104
93 #define LCK_RW_LCK_EX_TO_SH_CODE 0x105
96 #define ANY_LOCK_DEBUG (USLOCK_DEBUG || LOCK_DEBUG || MUTEX_DEBUG)
98 unsigned int LcksOpts
=0;
99 unsigned int lock_wait_time
[2] = { (unsigned int)-1, 100 } ;
104 void db_print_simple_lock(
109 #endif /* MACH_KDB */
114 * Perform simple lock checks.
116 int uslock_check
= 1;
117 int max_lock_loops
= 100000000;
118 decl_simple_lock_data(extern , printf_lock
)
119 decl_simple_lock_data(extern , panic_lock
)
121 decl_simple_lock_data(extern , kdb_lock
)
122 #endif /* MACH_KDB */
123 #endif /* USLOCK_DEBUG */
127 * We often want to know the addresses of the callers
128 * of the various lock routines. However, this information
129 * is only used for debugging and statistics.
132 #define INVALID_PC ((void *) VM_MAX_KERNEL_ADDRESS)
133 #define INVALID_THREAD ((void *) VM_MAX_KERNEL_ADDRESS)
135 #define OBTAIN_PC(pc,l) ((pc) = (void *) GET_RETURN_PC(&(l)))
136 #define DECL_PC(pc) pc_t pc;
137 #else /* ANY_LOCK_DEBUG */
141 * Eliminate lint complaints about unused local pc variables.
143 #define OBTAIN_PC(pc,l) ++pc
145 #define OBTAIN_PC(pc,l)
147 #endif /* USLOCK_DEBUG */
151 * Portable lock package implementation of usimple_locks.
155 #define USLDBG(stmt) stmt
156 void usld_lock_init(usimple_lock_t
, unsigned short);
157 void usld_lock_pre(usimple_lock_t
, pc_t
);
158 void usld_lock_post(usimple_lock_t
, pc_t
);
159 void usld_unlock(usimple_lock_t
, pc_t
);
160 void usld_lock_try_pre(usimple_lock_t
, pc_t
);
161 void usld_lock_try_post(usimple_lock_t
, pc_t
);
162 int usld_lock_common_checks(usimple_lock_t
, char *);
163 #else /* USLOCK_DEBUG */
165 #endif /* USLOCK_DEBUG */
168 * Routine: lck_spin_alloc_init
177 if ((lck
= (lck_spin_t
*)kalloc(sizeof(lck_spin_t
))) != 0)
178 lck_spin_init(lck
, grp
, attr
);
184 * Routine: lck_spin_free
191 lck_spin_destroy(lck
, grp
);
192 kfree(lck
, sizeof(lck_spin_t
));
196 * Routine: lck_spin_init
202 __unused lck_attr_t
*attr
)
204 usimple_lock_init((usimple_lock_t
) lck
, 0);
205 lck_grp_reference(grp
);
206 lck_grp_lckcnt_incr(grp
, LCK_TYPE_SPIN
);
210 * Routine: lck_spin_destroy
217 if (lck
->lck_spin_data
[0] == LCK_SPIN_TAG_DESTROYED
)
219 lck
->lck_spin_data
[0] = LCK_SPIN_TAG_DESTROYED
;
220 lck_grp_lckcnt_decr(grp
, LCK_TYPE_SPIN
);
221 lck_grp_deallocate(grp
);
226 * Routine: lck_spin_lock
232 usimple_lock((usimple_lock_t
) lck
);
236 * Routine: lck_spin_unlock
242 usimple_unlock((usimple_lock_t
) lck
);
247 * Routine: lck_spin_try_lock
253 usimple_lock_try((usimple_lock_t
) lck
);
257 * Initialize a usimple_lock.
259 * No change in preemption state.
264 __unused
unsigned short tag
)
266 #ifndef MACHINE_SIMPLE_LOCK
267 USLDBG(usld_lock_init(l
, tag
));
268 hw_lock_init(&l
->interlock
);
270 simple_lock_init((simple_lock_t
)l
,tag
);
276 * Acquire a usimple_lock.
278 * Returns with preemption disabled. Note
279 * that the hw_lock routines are responsible for
280 * maintaining preemption state.
286 #ifndef MACHINE_SIMPLE_LOCK
290 USLDBG(usld_lock_pre(l
, pc
));
292 if(!hw_lock_to(&l
->interlock
, LockTimeOut
)) /* Try to get the lock with a timeout */
293 panic("simple lock deadlock detection - l=%08X, cpu=%d, ret=%08X", l
, cpu_number(), pc
);
295 USLDBG(usld_lock_post(l
, pc
));
297 simple_lock((simple_lock_t
)l
);
303 * Release a usimple_lock.
305 * Returns with preemption enabled. Note
306 * that the hw_lock routines are responsible for
307 * maintaining preemption state.
313 #ifndef MACHINE_SIMPLE_LOCK
317 USLDBG(usld_unlock(l
, pc
));
318 hw_lock_unlock(&l
->interlock
);
320 simple_unlock_rwmb((simple_lock_t
)l
);
326 * Conditionally acquire a usimple_lock.
328 * On success, returns with preemption disabled.
329 * On failure, returns with preemption in the same state
330 * as when first invoked. Note that the hw_lock routines
331 * are responsible for maintaining preemption state.
333 * XXX No stats are gathered on a miss; I preserved this
334 * behavior from the original assembly-language code, but
335 * doesn't it make sense to log misses? XXX
341 #ifndef MACHINE_SIMPLE_LOCK
343 unsigned int success
;
346 USLDBG(usld_lock_try_pre(l
, pc
));
347 if ((success
= hw_lock_try(&l
->interlock
))) {
348 USLDBG(usld_lock_try_post(l
, pc
));
352 return(simple_lock_try((simple_lock_t
)l
));
358 * States of a usimple_lock. The default when initializing
359 * a usimple_lock is setting it up for debug checking.
361 #define USLOCK_CHECKED 0x0001 /* lock is being checked */
362 #define USLOCK_TAKEN 0x0002 /* lock has been taken */
363 #define USLOCK_INIT 0xBAA0 /* lock has been initialized */
364 #define USLOCK_INITIALIZED (USLOCK_INIT|USLOCK_CHECKED)
365 #define USLOCK_CHECKING(l) (uslock_check && \
366 ((l)->debug.state & USLOCK_CHECKED))
369 * Trace activities of a particularly interesting lock.
371 void usl_trace(usimple_lock_t
, int, pc_t
, const char *);
375 * Initialize the debugging information contained
381 __unused
unsigned short tag
)
383 if (l
== USIMPLE_LOCK_NULL
)
384 panic("lock initialization: null lock pointer");
385 l
->lock_type
= USLOCK_TAG
;
386 l
->debug
.state
= uslock_check
? USLOCK_INITIALIZED
: 0;
387 l
->debug
.lock_cpu
= l
->debug
.unlock_cpu
= 0;
388 l
->debug
.lock_pc
= l
->debug
.unlock_pc
= INVALID_PC
;
389 l
->debug
.lock_thread
= l
->debug
.unlock_thread
= INVALID_THREAD
;
390 l
->debug
.duration
[0] = l
->debug
.duration
[1] = 0;
391 l
->debug
.unlock_cpu
= l
->debug
.unlock_cpu
= 0;
392 l
->debug
.unlock_pc
= l
->debug
.unlock_pc
= INVALID_PC
;
393 l
->debug
.unlock_thread
= l
->debug
.unlock_thread
= INVALID_THREAD
;
398 * These checks apply to all usimple_locks, not just
399 * those with USLOCK_CHECKED turned on.
402 usld_lock_common_checks(
406 if (l
== USIMPLE_LOCK_NULL
)
407 panic("%s: null lock pointer", caller
);
408 if (l
->lock_type
!= USLOCK_TAG
)
409 panic("%s: 0x%x is not a usimple lock", caller
, (integer_t
) l
);
410 if (!(l
->debug
.state
& USLOCK_INIT
))
411 panic("%s: 0x%x is not an initialized lock",
412 caller
, (integer_t
) l
);
413 return USLOCK_CHECKING(l
);
418 * Debug checks on a usimple_lock just before attempting
427 char caller
[] = "usimple_lock";
430 if (!usld_lock_common_checks(l
, caller
))
434 * Note that we have a weird case where we are getting a lock when we are]
435 * in the process of putting the system to sleep. We are running with no
436 * current threads, therefore we can't tell if we are trying to retake a lock
437 * we have or someone on the other processor has it. Therefore we just
438 * ignore this test if the locking thread is 0.
441 if ((l
->debug
.state
& USLOCK_TAKEN
) && l
->debug
.lock_thread
&&
442 l
->debug
.lock_thread
== (void *) current_thread()) {
443 printf("%s: lock 0x%x already locked (at 0x%x) by",
444 caller
, (integer_t
) l
, l
->debug
.lock_pc
);
445 printf(" current thread 0x%x (new attempt at pc 0x%x)\n",
446 l
->debug
.lock_thread
, pc
);
449 mp_disable_preemption();
450 usl_trace(l
, cpu_number(), pc
, caller
);
451 mp_enable_preemption();
456 * Debug checks on a usimple_lock just after acquiring it.
458 * Pre-emption has been disabled at this point,
459 * so we are safe in using cpu_number.
467 char caller
[] = "successful usimple_lock";
470 if (!usld_lock_common_checks(l
, caller
))
473 if (!((l
->debug
.state
& ~USLOCK_TAKEN
) == USLOCK_INITIALIZED
))
474 panic("%s: lock 0x%x became uninitialized",
475 caller
, (integer_t
) l
);
476 if ((l
->debug
.state
& USLOCK_TAKEN
))
477 panic("%s: lock 0x%x became TAKEN by someone else",
478 caller
, (integer_t
) l
);
480 mycpu
= cpu_number();
481 l
->debug
.lock_thread
= (void *)current_thread();
482 l
->debug
.state
|= USLOCK_TAKEN
;
483 l
->debug
.lock_pc
= pc
;
484 l
->debug
.lock_cpu
= mycpu
;
486 usl_trace(l
, mycpu
, pc
, caller
);
491 * Debug checks on a usimple_lock just before
492 * releasing it. Note that the caller has not
493 * yet released the hardware lock.
495 * Preemption is still disabled, so there's
496 * no problem using cpu_number.
504 char caller
[] = "usimple_unlock";
507 if (!usld_lock_common_checks(l
, caller
))
510 mycpu
= cpu_number();
512 if (!(l
->debug
.state
& USLOCK_TAKEN
))
513 panic("%s: lock 0x%x hasn't been taken",
514 caller
, (integer_t
) l
);
515 if (l
->debug
.lock_thread
!= (void *) current_thread())
516 panic("%s: unlocking lock 0x%x, owned by thread 0x%x",
517 caller
, (integer_t
) l
, l
->debug
.lock_thread
);
518 if (l
->debug
.lock_cpu
!= mycpu
) {
519 printf("%s: unlocking lock 0x%x on cpu 0x%x",
520 caller
, (integer_t
) l
, mycpu
);
521 printf(" (acquired on cpu 0x%x)\n", l
->debug
.lock_cpu
);
524 usl_trace(l
, mycpu
, pc
, caller
);
526 l
->debug
.unlock_thread
= l
->debug
.lock_thread
;
527 l
->debug
.lock_thread
= INVALID_PC
;
528 l
->debug
.state
&= ~USLOCK_TAKEN
;
529 l
->debug
.unlock_pc
= pc
;
530 l
->debug
.unlock_cpu
= mycpu
;
535 * Debug checks on a usimple_lock just before
536 * attempting to acquire it.
538 * Preemption isn't guaranteed to be disabled.
545 char caller
[] = "usimple_lock_try";
547 if (!usld_lock_common_checks(l
, caller
))
549 mp_disable_preemption();
550 usl_trace(l
, cpu_number(), pc
, caller
);
551 mp_enable_preemption();
556 * Debug checks on a usimple_lock just after
557 * successfully attempting to acquire it.
559 * Preemption has been disabled by the
560 * lock acquisition attempt, so it's safe
569 char caller
[] = "successful usimple_lock_try";
571 if (!usld_lock_common_checks(l
, caller
))
574 if (!((l
->debug
.state
& ~USLOCK_TAKEN
) == USLOCK_INITIALIZED
))
575 panic("%s: lock 0x%x became uninitialized",
576 caller
, (integer_t
) l
);
577 if ((l
->debug
.state
& USLOCK_TAKEN
))
578 panic("%s: lock 0x%x became TAKEN by someone else",
579 caller
, (integer_t
) l
);
581 mycpu
= cpu_number();
582 l
->debug
.lock_thread
= (void *) current_thread();
583 l
->debug
.state
|= USLOCK_TAKEN
;
584 l
->debug
.lock_pc
= pc
;
585 l
->debug
.lock_cpu
= mycpu
;
587 usl_trace(l
, mycpu
, pc
, caller
);
592 * For very special cases, set traced_lock to point to a
593 * specific lock of interest. The result is a series of
594 * XPRs showing lock operations on that lock. The lock_seq
595 * value is used to show the order of those operations.
597 usimple_lock_t traced_lock
;
598 unsigned int lock_seq
;
605 const char * op_name
)
607 if (traced_lock
== l
) {
609 "seq %d, cpu %d, %s @ %x\n",
610 (integer_t
) lock_seq
, (integer_t
) mycpu
,
611 (integer_t
) op_name
, (integer_t
) pc
, 0);
617 #endif /* USLOCK_DEBUG */
620 * Routine: lock_alloc
622 * Allocate a lock for external users who cannot
623 * hard-code the structure definition into their
625 * For now just use kalloc, but a zone is probably
636 if ((l
= (lock_t
*)kalloc(sizeof(lock_t
))) != 0)
637 lock_init(l
, can_sleep
, tag
, tag1
);
644 * Free a lock allocated for external users.
645 * For now just use kfree, but a zone is probably
652 kfree(l
, sizeof(lock_t
));
659 * Initialize a lock; required before use.
660 * Note that clients declare the "struct lock"
661 * variables and then initialize them, rather
662 * than getting a new one from this module.
668 __unused
unsigned short tag
,
671 (void) memset((void *) l
, 0, sizeof(lock_t
));
673 simple_lock_init(&l
->interlock
, tag1
);
674 l
->want_write
= FALSE
;
675 l
->want_upgrade
= FALSE
;
677 l
->can_sleep
= can_sleep
;
682 * Sleep locks. These use the same data structure and algorithm
683 * as the spin locks, but the process sleeps while it is waiting
684 * for the lock. These work on uniprocessor systems.
687 #define DECREMENTER_TIMEOUT 1000000
694 boolean_t lock_miss
= FALSE
;
697 #endif /* MACH_LDEBUG */
699 simple_lock(&l
->interlock
);
702 decrementer
= DECREMENTER_TIMEOUT
;
703 #endif /* MACH_LDEBUG */
706 * Try to acquire the want_write bit.
708 while (l
->want_write
) {
713 i
= lock_wait_time
[l
->can_sleep
? 1 : 0];
715 simple_unlock(&l
->interlock
);
718 Debugger("timeout - want_write");
719 #endif /* MACH_LDEBUG */
720 while (--i
!= 0 && l
->want_write
)
722 simple_lock(&l
->interlock
);
725 if (l
->can_sleep
&& l
->want_write
) {
727 thread_sleep_simple_lock((event_t
) l
,
728 simple_lock_addr(l
->interlock
),
730 /* interlock relocked */
733 l
->want_write
= TRUE
;
735 /* Wait for readers (and upgrades) to finish */
738 decrementer
= DECREMENTER_TIMEOUT
;
739 #endif /* MACH_LDEBUG */
740 while ((l
->read_count
!= 0) || l
->want_upgrade
) {
745 i
= lock_wait_time
[l
->can_sleep
? 1 : 0];
747 simple_unlock(&l
->interlock
);
750 Debugger("timeout - wait for readers");
751 #endif /* MACH_LDEBUG */
752 while (--i
!= 0 && (l
->read_count
!= 0 ||
755 simple_lock(&l
->interlock
);
758 if (l
->can_sleep
&& (l
->read_count
!= 0 || l
->want_upgrade
)) {
760 thread_sleep_simple_lock((event_t
) l
,
761 simple_lock_addr(l
->interlock
),
763 /* interlock relocked */
767 simple_unlock(&l
->interlock
);
774 boolean_t do_wakeup
= FALSE
;
777 simple_lock(&l
->interlock
);
779 if (l
->read_count
!= 0) {
783 if (l
->want_upgrade
) {
784 l
->want_upgrade
= FALSE
;
787 l
->want_write
= FALSE
;
791 * There is no reason to wakeup a waiting thread
792 * if the read-count is non-zero. Consider:
793 * we must be dropping a read lock
794 * threads are waiting only if one wants a write lock
795 * if there are still readers, they can't proceed
798 if (l
->waiting
&& (l
->read_count
== 0)) {
803 simple_unlock(&l
->interlock
);
806 thread_wakeup((event_t
) l
);
816 #endif /* MACH_LDEBUG */
818 simple_lock(&l
->interlock
);
821 decrementer
= DECREMENTER_TIMEOUT
;
822 #endif /* MACH_LDEBUG */
823 while (l
->want_write
|| l
->want_upgrade
) {
824 i
= lock_wait_time
[l
->can_sleep
? 1 : 0];
827 simple_unlock(&l
->interlock
);
830 Debugger("timeout - wait no writers");
831 #endif /* MACH_LDEBUG */
832 while (--i
!= 0 && (l
->want_write
|| l
->want_upgrade
))
834 simple_lock(&l
->interlock
);
837 if (l
->can_sleep
&& (l
->want_write
|| l
->want_upgrade
)) {
839 thread_sleep_simple_lock((event_t
) l
,
840 simple_lock_addr(l
->interlock
),
842 /* interlock relocked */
848 simple_unlock(&l
->interlock
);
853 * Routine: lock_read_to_write
855 * Improves a read-only lock to one with
856 * write permission. If another reader has
857 * already requested an upgrade to a write lock,
858 * no lock is held upon return.
860 * Returns TRUE if the upgrade *failed*.
868 boolean_t do_wakeup
= FALSE
;
871 #endif /* MACH_LDEBUG */
873 simple_lock(&l
->interlock
);
877 if (l
->want_upgrade
) {
879 * Someone else has requested upgrade.
880 * Since we've released a read lock, wake
883 if (l
->waiting
&& (l
->read_count
== 0)) {
888 simple_unlock(&l
->interlock
);
891 thread_wakeup((event_t
) l
);
895 l
->want_upgrade
= TRUE
;
898 decrementer
= DECREMENTER_TIMEOUT
;
899 #endif /* MACH_LDEBUG */
900 while (l
->read_count
!= 0) {
901 i
= lock_wait_time
[l
->can_sleep
? 1 : 0];
904 simple_unlock(&l
->interlock
);
907 Debugger("timeout - read_count");
908 #endif /* MACH_LDEBUG */
909 while (--i
!= 0 && l
->read_count
!= 0)
911 simple_lock(&l
->interlock
);
914 if (l
->can_sleep
&& l
->read_count
!= 0) {
916 thread_sleep_simple_lock((event_t
) l
,
917 simple_lock_addr(l
->interlock
),
919 /* interlock relocked */
923 simple_unlock(&l
->interlock
);
932 boolean_t do_wakeup
= FALSE
;
934 simple_lock(&l
->interlock
);
938 l
->want_upgrade
= FALSE
;
940 l
->want_write
= FALSE
;
947 simple_unlock(&l
->interlock
);
950 thread_wakeup((event_t
) l
);
956 * Routine: lock_try_write
958 * Tries to get a write lock.
960 * Returns FALSE if the lock is not held on return.
969 simple_lock(&l
->interlock
);
971 if (l
->want_write
|| l
->want_upgrade
|| l
->read_count
) {
975 simple_unlock(&l
->interlock
);
983 l
->want_write
= TRUE
;
985 simple_unlock(&l
->interlock
);
991 * Routine: lock_try_read
993 * Tries to get a read lock.
995 * Returns FALSE if the lock is not held on return.
1000 register lock_t
* l
)
1004 simple_lock(&l
->interlock
);
1006 if (l
->want_write
|| l
->want_upgrade
) {
1007 simple_unlock(&l
->interlock
);
1013 simple_unlock(&l
->interlock
);
1021 * Routine: lck_rw_alloc_init
1029 if ((lck
= (lck_rw_t
*)kalloc(sizeof(lck_rw_t
))) != 0)
1030 lck_rw_init(lck
, grp
, attr
);
1036 * Routine: lck_rw_free
1042 lck_rw_destroy(lck
, grp
);
1043 kfree(lck
, sizeof(lck_rw_t
));
1047 * Routine: lck_rw_init
1053 __unused lck_attr_t
*attr
) {
1055 hw_lock_init(&lck
->interlock
);
1056 lck
->want_write
= FALSE
;
1057 lck
->want_upgrade
= FALSE
;
1058 lck
->read_count
= 0;
1059 lck
->can_sleep
= TRUE
;
1060 lck
->lck_rw_tag
= 0;
1062 lck_grp_reference(grp
);
1063 lck_grp_lckcnt_incr(grp
, LCK_TYPE_RW
);
1067 * Routine: lck_rw_destroy
1073 if (lck
->lck_rw_tag
== LCK_RW_TAG_DESTROYED
)
1075 lck
->lck_rw_tag
= LCK_RW_TAG_DESTROYED
;
1076 lck_grp_lckcnt_decr(grp
, LCK_TYPE_RW
);
1077 lck_grp_deallocate(grp
);
1082 * Sleep locks. These use the same data structure and algorithm
1083 * as the spin locks, but the process sleeps while it is waiting
1084 * for the lock. These work on uniprocessor systems.
1087 #define DECREMENTER_TIMEOUT 1000000
1091 * We need to disable interrupts while holding the mutex interlock
1092 * to prevent an IPI intervening.
1093 * Hence, local helper functions lck_interlock_lock()/lck_interlock_unlock().
1096 lck_interlock_lock(lck_rw_t
*lck
)
1100 istate
= ml_set_interrupts_enabled(FALSE
);
1101 hw_lock_lock(&lck
->interlock
);
1107 lck_interlock_unlock(lck_rw_t
*lck
, boolean_t istate
)
1109 hw_lock_unlock(&lck
->interlock
);
1110 ml_set_interrupts_enabled(istate
);
1114 * Routine: lck_rw_lock_exclusive
1117 lck_rw_lock_exclusive(
1121 boolean_t lock_miss
= FALSE
;
1125 #endif /* MACH_LDEBUG */
1128 istate
= lck_interlock_lock(lck
);
1131 decrementer
= DECREMENTER_TIMEOUT
;
1132 #endif /* MACH_LDEBUG */
1135 * Try to acquire the want_write bit.
1137 while (lck
->want_write
) {
1138 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EXCLUSIVE_CODE
) | DBG_FUNC_START
, (int)lck
, 0, 0, 0, 0);
1144 i
= lock_wait_time
[lck
->can_sleep
? 1 : 0];
1146 lck_interlock_unlock(lck
, istate
);
1149 Debugger("timeout - want_write");
1150 #endif /* MACH_LDEBUG */
1151 while (--i
!= 0 && lck
->want_write
)
1153 istate
= lck_interlock_lock(lck
);
1156 if (lck
->can_sleep
&& lck
->want_write
) {
1157 lck
->waiting
= TRUE
;
1158 res
= assert_wait((event_t
) lck
, THREAD_UNINT
);
1159 if (res
== THREAD_WAITING
) {
1160 lck_interlock_unlock(lck
, istate
);
1161 res
= thread_block(THREAD_CONTINUE_NULL
);
1162 istate
= lck_interlock_lock(lck
);
1165 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EXCLUSIVE_CODE
) | DBG_FUNC_END
, (int)lck
, res
, 0, 0, 0);
1167 lck
->want_write
= TRUE
;
1169 /* Wait for readers (and upgrades) to finish */
1172 decrementer
= DECREMENTER_TIMEOUT
;
1173 #endif /* MACH_LDEBUG */
1174 while ((lck
->read_count
!= 0) || lck
->want_upgrade
) {
1179 i
= lock_wait_time
[lck
->can_sleep
? 1 : 0];
1181 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EXCLUSIVE1_CODE
) | DBG_FUNC_START
,
1182 (int)lck
, lck
->read_count
, lck
->want_upgrade
, i
, 0);
1185 lck_interlock_unlock(lck
, istate
);
1188 Debugger("timeout - wait for readers");
1189 #endif /* MACH_LDEBUG */
1190 while (--i
!= 0 && (lck
->read_count
!= 0 ||
1193 istate
= lck_interlock_lock(lck
);
1196 if (lck
->can_sleep
&& (lck
->read_count
!= 0 || lck
->want_upgrade
)) {
1197 lck
->waiting
= TRUE
;
1198 res
= assert_wait((event_t
) lck
, THREAD_UNINT
);
1199 if (res
== THREAD_WAITING
) {
1200 lck_interlock_unlock(lck
, istate
);
1201 res
= thread_block(THREAD_CONTINUE_NULL
);
1202 istate
= lck_interlock_lock(lck
);
1205 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EXCLUSIVE1_CODE
) | DBG_FUNC_END
,
1206 (int)lck
, lck
->read_count
, lck
->want_upgrade
, res
, 0);
1209 lck_interlock_unlock(lck
, istate
);
1214 * Routine: lck_rw_done
1220 boolean_t do_wakeup
= FALSE
;
1221 lck_rw_type_t lck_rw_type
;
1225 istate
= lck_interlock_lock(lck
);
1227 if (lck
->read_count
!= 0) {
1228 lck_rw_type
= LCK_RW_TYPE_SHARED
;
1232 lck_rw_type
= LCK_RW_TYPE_EXCLUSIVE
;
1233 if (lck
->want_upgrade
)
1234 lck
->want_upgrade
= FALSE
;
1236 lck
->want_write
= FALSE
;
1240 * There is no reason to wakeup a waiting thread
1241 * if the read-count is non-zero. Consider:
1242 * we must be dropping a read lock
1243 * threads are waiting only if one wants a write lock
1244 * if there are still readers, they can't proceed
1247 if (lck
->waiting
&& (lck
->read_count
== 0)) {
1248 lck
->waiting
= FALSE
;
1252 lck_interlock_unlock(lck
, istate
);
1255 thread_wakeup((event_t
) lck
);
1256 return(lck_rw_type
);
1263 * Routine: lck_rw_unlock
1268 lck_rw_type_t lck_rw_type
)
1270 if (lck_rw_type
== LCK_RW_TYPE_SHARED
)
1271 lck_rw_unlock_shared(lck
);
1272 else if (lck_rw_type
== LCK_RW_TYPE_EXCLUSIVE
)
1273 lck_rw_unlock_exclusive(lck
);
1275 panic("lck_rw_unlock(): Invalid RW lock type: %d\n", lck_rw_type
);
1280 * Routine: lck_rw_unlock_shared
1283 lck_rw_unlock_shared(
1288 ret
= lck_rw_done(lck
);
1290 if (ret
!= LCK_RW_TYPE_SHARED
)
1291 panic("lck_rw_unlock(): lock held in mode: %d\n", ret
);
1296 * Routine: lck_rw_unlock_exclusive
1299 lck_rw_unlock_exclusive(
1304 ret
= lck_rw_done(lck
);
1306 if (ret
!= LCK_RW_TYPE_EXCLUSIVE
)
1307 panic("lck_rw_unlock_exclusive(): lock held in mode: %d\n", ret
);
1312 * Routine: lck_rw_lock
1317 lck_rw_type_t lck_rw_type
)
1319 if (lck_rw_type
== LCK_RW_TYPE_SHARED
)
1320 lck_rw_lock_shared(lck
);
1321 else if (lck_rw_type
== LCK_RW_TYPE_EXCLUSIVE
)
1322 lck_rw_lock_exclusive(lck
);
1324 panic("lck_rw_lock(): Invalid RW lock type: %x\n", lck_rw_type
);
1329 * Routine: lck_rw_lock_shared
1339 #endif /* MACH_LDEBUG */
1342 istate
= lck_interlock_lock(lck
);
1345 decrementer
= DECREMENTER_TIMEOUT
;
1346 #endif /* MACH_LDEBUG */
1347 while (lck
->want_write
|| lck
->want_upgrade
) {
1348 i
= lock_wait_time
[lck
->can_sleep
? 1 : 0];
1350 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SHARED_CODE
) | DBG_FUNC_START
,
1351 (int)lck
, lck
->want_write
, lck
->want_upgrade
, i
, 0);
1354 lck_interlock_unlock(lck
, istate
);
1357 Debugger("timeout - wait no writers");
1358 #endif /* MACH_LDEBUG */
1359 while (--i
!= 0 && (lck
->want_write
|| lck
->want_upgrade
))
1361 istate
= lck_interlock_lock(lck
);
1364 if (lck
->can_sleep
&& (lck
->want_write
|| lck
->want_upgrade
)) {
1365 lck
->waiting
= TRUE
;
1366 res
= assert_wait((event_t
) lck
, THREAD_UNINT
);
1367 if (res
== THREAD_WAITING
) {
1368 lck_interlock_unlock(lck
, istate
);
1369 res
= thread_block(THREAD_CONTINUE_NULL
);
1370 istate
= lck_interlock_lock(lck
);
1373 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SHARED_CODE
) | DBG_FUNC_END
,
1374 (int)lck
, lck
->want_write
, lck
->want_upgrade
, res
, 0);
1379 lck_interlock_unlock(lck
, istate
);
1384 * Routine: lck_rw_lock_shared_to_exclusive
1386 * Improves a read-only lock to one with
1387 * write permission. If another reader has
1388 * already requested an upgrade to a write lock,
1389 * no lock is held upon return.
1391 * Returns TRUE if the upgrade *failed*.
1395 lck_rw_lock_shared_to_exclusive(
1399 boolean_t do_wakeup
= FALSE
;
1403 #endif /* MACH_LDEBUG */
1406 istate
= lck_interlock_lock(lck
);
1410 if (lck
->want_upgrade
) {
1411 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SH_TO_EX_CODE
) | DBG_FUNC_START
,
1412 (int)lck
, lck
->read_count
, lck
->want_upgrade
, 0, 0);
1415 * Someone else has requested upgrade.
1416 * Since we've released a read lock, wake
1419 if (lck
->waiting
&& (lck
->read_count
== 0)) {
1420 lck
->waiting
= FALSE
;
1424 lck_interlock_unlock(lck
, istate
);
1427 thread_wakeup((event_t
) lck
);
1429 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SH_TO_EX_CODE
) | DBG_FUNC_END
,
1430 (int)lck
, lck
->read_count
, lck
->want_upgrade
, 0, 0);
1435 lck
->want_upgrade
= TRUE
;
1438 decrementer
= DECREMENTER_TIMEOUT
;
1439 #endif /* MACH_LDEBUG */
1440 while (lck
->read_count
!= 0) {
1441 i
= lock_wait_time
[lck
->can_sleep
? 1 : 0];
1443 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SH_TO_EX1_CODE
) | DBG_FUNC_START
,
1444 (int)lck
, lck
->read_count
, i
, 0, 0);
1447 lck_interlock_unlock(lck
, istate
);
1450 Debugger("timeout - read_count");
1451 #endif /* MACH_LDEBUG */
1452 while (--i
!= 0 && lck
->read_count
!= 0)
1454 istate
= lck_interlock_lock(lck
);
1457 if (lck
->can_sleep
&& lck
->read_count
!= 0) {
1458 lck
->waiting
= TRUE
;
1459 res
= assert_wait((event_t
) lck
, THREAD_UNINT
);
1460 if (res
== THREAD_WAITING
) {
1461 lck_interlock_unlock(lck
, istate
);
1462 res
= thread_block(THREAD_CONTINUE_NULL
);
1463 istate
= lck_interlock_lock(lck
);
1466 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SH_TO_EX1_CODE
) | DBG_FUNC_END
,
1467 (int)lck
, lck
->read_count
, 0, 0, 0);
1470 lck_interlock_unlock(lck
, istate
);
1476 * Routine: lck_rw_lock_exclusive_to_shared
1479 lck_rw_lock_exclusive_to_shared(
1482 boolean_t do_wakeup
= FALSE
;
1485 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EX_TO_SH_CODE
) | DBG_FUNC_START
,
1486 (int)lck
, lck
->want_write
, lck
->want_upgrade
, 0, 0);
1488 istate
= lck_interlock_lock(lck
);
1491 if (lck
->want_upgrade
)
1492 lck
->want_upgrade
= FALSE
;
1494 lck
->want_write
= FALSE
;
1497 lck
->waiting
= FALSE
;
1501 lck_interlock_unlock(lck
, istate
);
1504 thread_wakeup((event_t
) lck
);
1506 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EX_TO_SH_CODE
) | DBG_FUNC_END
,
1507 (int)lck
, lck
->want_write
, lck
->want_upgrade
, lck
->read_count
, 0);
1513 * Routine: lck_rw_try_lock
1518 lck_rw_type_t lck_rw_type
)
1520 if (lck_rw_type
== LCK_RW_TYPE_SHARED
)
1521 return(lck_rw_try_lock_shared(lck
));
1522 else if (lck_rw_type
== LCK_RW_TYPE_EXCLUSIVE
)
1523 return(lck_rw_try_lock_exclusive(lck
));
1525 panic("lck_rw_try_lock(): Invalid rw lock type: %x\n", lck_rw_type
);
1530 * Routine: lck_rw_try_lock_exclusive
1532 * Tries to get a write lock.
1534 * Returns FALSE if the lock is not held on return.
1538 lck_rw_try_lock_exclusive(
1543 istate
= lck_interlock_lock(lck
);
1545 if (lck
->want_write
|| lck
->want_upgrade
|| lck
->read_count
) {
1549 lck_interlock_unlock(lck
, istate
);
1557 lck
->want_write
= TRUE
;
1559 lck_interlock_unlock(lck
, istate
);
1565 * Routine: lck_rw_try_lock_shared
1567 * Tries to get a read lock.
1569 * Returns FALSE if the lock is not held on return.
1573 lck_rw_try_lock_shared(
1578 istate
= lck_interlock_lock(lck
);
1580 if (lck
->want_write
|| lck
->want_upgrade
) {
1581 lck_interlock_unlock(lck
, istate
);
1587 lck_interlock_unlock(lck
, istate
);
1593 * Routine: lck_mtx_alloc_init
1602 if ((lck
= (lck_mtx_t
*)kalloc(sizeof(lck_mtx_t
))) != 0)
1603 lck_mtx_init(lck
, grp
, attr
);
1609 * Routine: lck_mtx_free
1616 lck_mtx_destroy(lck
, grp
);
1617 kfree(lck
, sizeof(lck_mtx_t
));
1621 * Routine: lck_mtx_ext_init
1629 lck
->lck_mtx
.lck_mtx_ilk
= 0;
1630 lck
->lck_mtx
.lck_mtx_locked
= 0;
1631 lck
->lck_mtx
.lck_mtx_waiters
= 0;
1632 lck
->lck_mtx
.lck_mtx_pri
= 0;
1633 lck
->lck_mtx_attr
= 0;
1635 if ((attr
->lck_attr_val
) & LCK_ATTR_DEBUG
) {
1636 lck
->lck_mtx_deb
.pc
= 0;
1637 lck
->lck_mtx_deb
.thread
= 0;
1638 lck
->lck_mtx_deb
.type
= MUTEX_TAG
;
1639 lck
->lck_mtx_attr
|= LCK_MTX_ATTR_DEBUG
;
1642 lck
->lck_mtx_grp
= grp
;
1646 * Routine: lck_mtx_init
1654 lck_mtx_ext_t
*lck_ext
;
1656 if ((attr
!= LCK_ATTR_NULL
) && ((attr
->lck_attr_val
) & LCK_ATTR_DEBUG
)) {
1657 if ((lck_ext
= (lck_mtx_ext_t
*)kalloc(sizeof(lck_mtx_ext_t
))) != 0) {
1658 lck_mtx_ext_init(lck_ext
, grp
, attr
);
1659 lck
->lck_mtx_tag
= LCK_MTX_TAG_INDIRECT
;
1660 lck
->lck_mtx_ptr
= lck_ext
;
1663 lck
->lck_mtx_ilk
= 0;
1664 lck
->lck_mtx_locked
= 0;
1665 lck
->lck_mtx_waiters
= 0;
1666 lck
->lck_mtx_pri
= 0;
1668 lck_grp_reference(grp
);
1669 lck_grp_lckcnt_incr(grp
, LCK_TYPE_MTX
);
1673 * Routine: lck_mtx_destroy
1680 boolean_t lck_is_indirect
;
1682 if (lck
->lck_mtx_tag
== LCK_MTX_TAG_DESTROYED
)
1684 lck_is_indirect
= (lck
->lck_mtx_tag
== LCK_MTX_TAG_INDIRECT
);
1685 lck
->lck_mtx_tag
= LCK_MTX_TAG_DESTROYED
;
1686 if (lck_is_indirect
)
1687 kfree(lck
->lck_mtx_ptr
, sizeof(lck_mtx_ext_t
));
1688 lck_grp_lckcnt_decr(grp
, LCK_TYPE_MTX
);
1689 lck_grp_deallocate(grp
);
1694 * Routine: lck_mtx_assert
1698 __unused lck_mtx_t
*lck
,
1699 __unused
unsigned int type
)
1705 void db_show_one_lock(lock_t
*);
1711 db_printf("Read_count = 0x%x, %swant_upgrade, %swant_write, ",
1713 lock
->want_upgrade
? "" : "!",
1714 lock
->want_write
? "" : "!");
1715 db_printf("%swaiting, %scan_sleep\n",
1716 lock
->waiting
? "" : "!", lock
->can_sleep
? "" : "!");
1717 db_printf("Interlock:\n");
1718 db_show_one_simple_lock((db_expr_t
)simple_lock_addr(lock
->interlock
),
1719 TRUE
, (db_expr_t
)0, (char *)0);
1722 #endif /* MACH_KDB */
1725 * The C portion of the mutex package. These routines are only invoked
1726 * if the optimized assembler routines can't do the work.
1730 * Routine: lock_alloc
1732 * Allocate a mutex for external users who cannot
1733 * hard-code the structure definition into their
1735 * For now just use kalloc, but a zone is probably
1744 if ((m
= (mutex_t
*)kalloc(sizeof(mutex_t
))) != 0)
1750 * Routine: mutex_free
1752 * Free a mutex allocated for external users.
1753 * For now just use kfree, but a zone is probably
1760 kfree(m
, sizeof(mutex_t
));
1764 * Routine: _mutex_assert
1772 thread_t thread
= current_thread();
1775 if (panicstr
!= NULL
)
1778 holder
= (thread_t
) mutex
->lck_mtx
.lck_mtx_locked
;
1782 if (thread
!= holder
)
1783 panic("mutex %x not owned\n", mutex
);
1787 if (thread
== holder
)
1788 panic("mutex %x owned\n", mutex
);
1796 * Routines to print out simple_locks and mutexes in a nicely-formatted
1800 char *simple_lock_labels
= "ENTRY ILK THREAD DURATION CALLER";
1801 char *mutex_labels
= "ENTRY LOCKED WAITERS THREAD CALLER";
1804 db_show_one_simple_lock (
1806 boolean_t have_addr
,
1810 simple_lock_t saddr
= (simple_lock_t
)addr
;
1812 if (saddr
== (simple_lock_t
)0 || !have_addr
) {
1813 db_error ("No simple_lock\n");
1816 else if (saddr
->lock_type
!= USLOCK_TAG
)
1817 db_error ("Not a simple_lock\n");
1818 #endif /* USLOCK_DEBUG */
1820 db_printf ("%s\n", simple_lock_labels
);
1821 db_print_simple_lock (saddr
);
1825 db_print_simple_lock (
1829 db_printf ("%08x %3d", addr
, *hw_lock_addr(addr
->interlock
));
1831 db_printf (" %08x", addr
->debug
.lock_thread
);
1832 db_printf (" %08x ", addr
->debug
.duration
[1]);
1833 db_printsym ((int)addr
->debug
.lock_pc
, DB_STGY_ANY
);
1834 #endif /* USLOCK_DEBUG */
1841 boolean_t have_addr
,
1845 mutex_t
* maddr
= (mutex_t
*)addr
;
1847 if (maddr
== (mutex_t
*)0 || !have_addr
)
1848 db_error ("No mutex\n");
1850 else if (maddr
->type
!= MUTEX_TAG
)
1851 db_error ("Not a mutex\n");
1852 #endif /* MACH_LDEBUG */
1854 db_printf ("%s\n", mutex_labels
);
1855 db_print_mutex (maddr
);
1862 db_printf ("%08x %6d %7d",
1863 addr
, *addr
, addr
->lck_mtx
.lck_mtx_waiters
);
1865 db_printf (" %08x ", addr
->thread
);
1866 db_printsym (addr
->pc
, DB_STGY_ANY
);
1867 #endif /* MACH_LDEBUG */
1871 #endif /* MACH_KDB */