2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_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. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
32 * Mach Operating System
33 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
34 * All Rights Reserved.
36 * Permission to use, copy, modify and distribute this software and its
37 * documentation is hereby granted, provided that both the copyright
38 * notice and this permission notice appear in all copies of the
39 * software, derivative works or modified versions, and any portions
40 * thereof, and that both notices appear in supporting documentation.
42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
46 * Carnegie Mellon requests users of this software to return to
48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
49 * School of Computer Science
50 * Carnegie Mellon University
51 * Pittsburgh PA 15213-3890
53 * any improvements or extensions that they make and grant Carnegie Mellon
54 * the rights to redistribute these changes.
58 * Author: Avadis Tevanian, Jr., Michael Wayne Young
61 * Locking primitives implementation
65 #include <mach_ldebug.h>
67 #include <kern/lock.h>
68 #include <kern/locks.h>
69 #include <kern/kalloc.h>
70 #include <kern/misc_protos.h>
71 #include <kern/thread.h>
72 #include <kern/processor.h>
73 #include <kern/cpu_data.h>
74 #include <kern/cpu_number.h>
75 #include <kern/sched_prim.h>
77 #include <kern/debug.h>
81 #include <ddb/db_command.h>
82 #include <ddb/db_output.h>
83 #include <ddb/db_sym.h>
84 #include <ddb/db_print.h>
88 #include <ppc/Firmware.h>
91 #include <sys/kdebug.h>
93 #define LCK_RW_LCK_EXCLUSIVE_CODE 0x100
94 #define LCK_RW_LCK_EXCLUSIVE1_CODE 0x101
95 #define LCK_RW_LCK_SHARED_CODE 0x102
96 #define LCK_RW_LCK_SH_TO_EX_CODE 0x103
97 #define LCK_RW_LCK_SH_TO_EX1_CODE 0x104
98 #define LCK_RW_LCK_EX_TO_SH_CODE 0x105
101 #define ANY_LOCK_DEBUG (USLOCK_DEBUG || LOCK_DEBUG || MUTEX_DEBUG)
103 unsigned int LcksOpts
=0;
104 unsigned int lock_wait_time
[2] = { (unsigned int)-1, 100 } ;
109 void db_print_simple_lock(
114 #endif /* MACH_KDB */
119 * Perform simple lock checks.
121 int uslock_check
= 1;
122 int max_lock_loops
= 100000000;
123 decl_simple_lock_data(extern , printf_lock
)
124 decl_simple_lock_data(extern , panic_lock
)
126 decl_simple_lock_data(extern , kdb_lock
)
127 #endif /* MACH_KDB */
128 #endif /* USLOCK_DEBUG */
132 * We often want to know the addresses of the callers
133 * of the various lock routines. However, this information
134 * is only used for debugging and statistics.
137 #define INVALID_PC ((void *) VM_MAX_KERNEL_ADDRESS)
138 #define INVALID_THREAD ((void *) VM_MAX_KERNEL_ADDRESS)
140 #define OBTAIN_PC(pc,l) ((pc) = (void *) GET_RETURN_PC(&(l)))
141 #define DECL_PC(pc) pc_t pc;
142 #else /* ANY_LOCK_DEBUG */
146 * Eliminate lint complaints about unused local pc variables.
148 #define OBTAIN_PC(pc,l) ++pc
150 #define OBTAIN_PC(pc,l)
152 #endif /* USLOCK_DEBUG */
156 * Portable lock package implementation of usimple_locks.
160 #define USLDBG(stmt) stmt
161 void usld_lock_init(usimple_lock_t
, unsigned short);
162 void usld_lock_pre(usimple_lock_t
, pc_t
);
163 void usld_lock_post(usimple_lock_t
, pc_t
);
164 void usld_unlock(usimple_lock_t
, pc_t
);
165 void usld_lock_try_pre(usimple_lock_t
, pc_t
);
166 void usld_lock_try_post(usimple_lock_t
, pc_t
);
167 int usld_lock_common_checks(usimple_lock_t
, char *);
168 #else /* USLOCK_DEBUG */
170 #endif /* USLOCK_DEBUG */
173 * Routine: lck_spin_alloc_init
182 if ((lck
= (lck_spin_t
*)kalloc(sizeof(lck_spin_t
))) != 0)
183 lck_spin_init(lck
, grp
, attr
);
189 * Routine: lck_spin_free
196 lck_spin_destroy(lck
, grp
);
197 kfree(lck
, sizeof(lck_spin_t
));
201 * Routine: lck_spin_init
207 __unused lck_attr_t
*attr
)
209 usimple_lock_init((usimple_lock_t
) lck
, 0);
210 lck_grp_reference(grp
);
211 lck_grp_lckcnt_incr(grp
, LCK_TYPE_SPIN
);
215 * Routine: lck_spin_destroy
222 if (lck
->lck_spin_data
[0] == LCK_SPIN_TAG_DESTROYED
)
224 lck
->lck_spin_data
[0] = LCK_SPIN_TAG_DESTROYED
;
225 lck_grp_lckcnt_decr(grp
, LCK_TYPE_SPIN
);
226 lck_grp_deallocate(grp
);
231 * Routine: lck_spin_lock
237 usimple_lock((usimple_lock_t
) lck
);
241 * Routine: lck_spin_unlock
247 usimple_unlock((usimple_lock_t
) lck
);
252 * Routine: lck_spin_try_lock
258 usimple_lock_try((usimple_lock_t
) lck
);
262 * Initialize a usimple_lock.
264 * No change in preemption state.
269 __unused
unsigned short tag
)
271 #ifndef MACHINE_SIMPLE_LOCK
272 USLDBG(usld_lock_init(l
, tag
));
273 hw_lock_init(&l
->interlock
);
275 simple_lock_init((simple_lock_t
)l
,tag
);
281 * Acquire a usimple_lock.
283 * Returns with preemption disabled. Note
284 * that the hw_lock routines are responsible for
285 * maintaining preemption state.
291 #ifndef MACHINE_SIMPLE_LOCK
295 USLDBG(usld_lock_pre(l
, pc
));
297 if(!hw_lock_to(&l
->interlock
, LockTimeOut
)) /* Try to get the lock with a timeout */
298 panic("simple lock deadlock detection - l=%08X, cpu=%d, ret=%08X", l
, cpu_number(), pc
);
300 USLDBG(usld_lock_post(l
, pc
));
302 simple_lock((simple_lock_t
)l
);
308 * Release a usimple_lock.
310 * Returns with preemption enabled. Note
311 * that the hw_lock routines are responsible for
312 * maintaining preemption state.
318 #ifndef MACHINE_SIMPLE_LOCK
322 USLDBG(usld_unlock(l
, pc
));
323 hw_lock_unlock(&l
->interlock
);
325 simple_unlock_rwmb((simple_lock_t
)l
);
331 * Conditionally acquire a usimple_lock.
333 * On success, returns with preemption disabled.
334 * On failure, returns with preemption in the same state
335 * as when first invoked. Note that the hw_lock routines
336 * are responsible for maintaining preemption state.
338 * XXX No stats are gathered on a miss; I preserved this
339 * behavior from the original assembly-language code, but
340 * doesn't it make sense to log misses? XXX
346 #ifndef MACHINE_SIMPLE_LOCK
348 unsigned int success
;
351 USLDBG(usld_lock_try_pre(l
, pc
));
352 if ((success
= hw_lock_try(&l
->interlock
))) {
353 USLDBG(usld_lock_try_post(l
, pc
));
357 return(simple_lock_try((simple_lock_t
)l
));
363 * States of a usimple_lock. The default when initializing
364 * a usimple_lock is setting it up for debug checking.
366 #define USLOCK_CHECKED 0x0001 /* lock is being checked */
367 #define USLOCK_TAKEN 0x0002 /* lock has been taken */
368 #define USLOCK_INIT 0xBAA0 /* lock has been initialized */
369 #define USLOCK_INITIALIZED (USLOCK_INIT|USLOCK_CHECKED)
370 #define USLOCK_CHECKING(l) (uslock_check && \
371 ((l)->debug.state & USLOCK_CHECKED))
374 * Trace activities of a particularly interesting lock.
376 void usl_trace(usimple_lock_t
, int, pc_t
, const char *);
380 * Initialize the debugging information contained
386 __unused
unsigned short tag
)
388 if (l
== USIMPLE_LOCK_NULL
)
389 panic("lock initialization: null lock pointer");
390 l
->lock_type
= USLOCK_TAG
;
391 l
->debug
.state
= uslock_check
? USLOCK_INITIALIZED
: 0;
392 l
->debug
.lock_cpu
= l
->debug
.unlock_cpu
= 0;
393 l
->debug
.lock_pc
= l
->debug
.unlock_pc
= INVALID_PC
;
394 l
->debug
.lock_thread
= l
->debug
.unlock_thread
= INVALID_THREAD
;
395 l
->debug
.duration
[0] = l
->debug
.duration
[1] = 0;
396 l
->debug
.unlock_cpu
= l
->debug
.unlock_cpu
= 0;
397 l
->debug
.unlock_pc
= l
->debug
.unlock_pc
= INVALID_PC
;
398 l
->debug
.unlock_thread
= l
->debug
.unlock_thread
= INVALID_THREAD
;
403 * These checks apply to all usimple_locks, not just
404 * those with USLOCK_CHECKED turned on.
407 usld_lock_common_checks(
411 if (l
== USIMPLE_LOCK_NULL
)
412 panic("%s: null lock pointer", caller
);
413 if (l
->lock_type
!= USLOCK_TAG
)
414 panic("%s: 0x%x is not a usimple lock", caller
, (integer_t
) l
);
415 if (!(l
->debug
.state
& USLOCK_INIT
))
416 panic("%s: 0x%x is not an initialized lock",
417 caller
, (integer_t
) l
);
418 return USLOCK_CHECKING(l
);
423 * Debug checks on a usimple_lock just before attempting
432 char caller
[] = "usimple_lock";
435 if (!usld_lock_common_checks(l
, caller
))
439 * Note that we have a weird case where we are getting a lock when we are]
440 * in the process of putting the system to sleep. We are running with no
441 * current threads, therefore we can't tell if we are trying to retake a lock
442 * we have or someone on the other processor has it. Therefore we just
443 * ignore this test if the locking thread is 0.
446 if ((l
->debug
.state
& USLOCK_TAKEN
) && l
->debug
.lock_thread
&&
447 l
->debug
.lock_thread
== (void *) current_thread()) {
448 printf("%s: lock 0x%x already locked (at 0x%x) by",
449 caller
, (integer_t
) l
, l
->debug
.lock_pc
);
450 printf(" current thread 0x%x (new attempt at pc 0x%x)\n",
451 l
->debug
.lock_thread
, pc
);
454 mp_disable_preemption();
455 usl_trace(l
, cpu_number(), pc
, caller
);
456 mp_enable_preemption();
461 * Debug checks on a usimple_lock just after acquiring it.
463 * Pre-emption has been disabled at this point,
464 * so we are safe in using cpu_number.
472 char caller
[] = "successful usimple_lock";
475 if (!usld_lock_common_checks(l
, caller
))
478 if (!((l
->debug
.state
& ~USLOCK_TAKEN
) == USLOCK_INITIALIZED
))
479 panic("%s: lock 0x%x became uninitialized",
480 caller
, (integer_t
) l
);
481 if ((l
->debug
.state
& USLOCK_TAKEN
))
482 panic("%s: lock 0x%x became TAKEN by someone else",
483 caller
, (integer_t
) l
);
485 mycpu
= cpu_number();
486 l
->debug
.lock_thread
= (void *)current_thread();
487 l
->debug
.state
|= USLOCK_TAKEN
;
488 l
->debug
.lock_pc
= pc
;
489 l
->debug
.lock_cpu
= mycpu
;
491 usl_trace(l
, mycpu
, pc
, caller
);
496 * Debug checks on a usimple_lock just before
497 * releasing it. Note that the caller has not
498 * yet released the hardware lock.
500 * Preemption is still disabled, so there's
501 * no problem using cpu_number.
509 char caller
[] = "usimple_unlock";
512 if (!usld_lock_common_checks(l
, caller
))
515 mycpu
= cpu_number();
517 if (!(l
->debug
.state
& USLOCK_TAKEN
))
518 panic("%s: lock 0x%x hasn't been taken",
519 caller
, (integer_t
) l
);
520 if (l
->debug
.lock_thread
!= (void *) current_thread())
521 panic("%s: unlocking lock 0x%x, owned by thread 0x%x",
522 caller
, (integer_t
) l
, l
->debug
.lock_thread
);
523 if (l
->debug
.lock_cpu
!= mycpu
) {
524 printf("%s: unlocking lock 0x%x on cpu 0x%x",
525 caller
, (integer_t
) l
, mycpu
);
526 printf(" (acquired on cpu 0x%x)\n", l
->debug
.lock_cpu
);
529 usl_trace(l
, mycpu
, pc
, caller
);
531 l
->debug
.unlock_thread
= l
->debug
.lock_thread
;
532 l
->debug
.lock_thread
= INVALID_PC
;
533 l
->debug
.state
&= ~USLOCK_TAKEN
;
534 l
->debug
.unlock_pc
= pc
;
535 l
->debug
.unlock_cpu
= mycpu
;
540 * Debug checks on a usimple_lock just before
541 * attempting to acquire it.
543 * Preemption isn't guaranteed to be disabled.
550 char caller
[] = "usimple_lock_try";
552 if (!usld_lock_common_checks(l
, caller
))
554 mp_disable_preemption();
555 usl_trace(l
, cpu_number(), pc
, caller
);
556 mp_enable_preemption();
561 * Debug checks on a usimple_lock just after
562 * successfully attempting to acquire it.
564 * Preemption has been disabled by the
565 * lock acquisition attempt, so it's safe
574 char caller
[] = "successful usimple_lock_try";
576 if (!usld_lock_common_checks(l
, caller
))
579 if (!((l
->debug
.state
& ~USLOCK_TAKEN
) == USLOCK_INITIALIZED
))
580 panic("%s: lock 0x%x became uninitialized",
581 caller
, (integer_t
) l
);
582 if ((l
->debug
.state
& USLOCK_TAKEN
))
583 panic("%s: lock 0x%x became TAKEN by someone else",
584 caller
, (integer_t
) l
);
586 mycpu
= cpu_number();
587 l
->debug
.lock_thread
= (void *) current_thread();
588 l
->debug
.state
|= USLOCK_TAKEN
;
589 l
->debug
.lock_pc
= pc
;
590 l
->debug
.lock_cpu
= mycpu
;
592 usl_trace(l
, mycpu
, pc
, caller
);
597 * For very special cases, set traced_lock to point to a
598 * specific lock of interest. The result is a series of
599 * XPRs showing lock operations on that lock. The lock_seq
600 * value is used to show the order of those operations.
602 usimple_lock_t traced_lock
;
603 unsigned int lock_seq
;
610 const char * op_name
)
612 if (traced_lock
== l
) {
614 "seq %d, cpu %d, %s @ %x\n",
615 (integer_t
) lock_seq
, (integer_t
) mycpu
,
616 (integer_t
) op_name
, (integer_t
) pc
, 0);
622 #endif /* USLOCK_DEBUG */
625 * Routine: lock_alloc
627 * Allocate a lock for external users who cannot
628 * hard-code the structure definition into their
630 * For now just use kalloc, but a zone is probably
641 if ((l
= (lock_t
*)kalloc(sizeof(lock_t
))) != 0)
642 lock_init(l
, can_sleep
, tag
, tag1
);
649 * Free a lock allocated for external users.
650 * For now just use kfree, but a zone is probably
657 kfree(l
, sizeof(lock_t
));
664 * Initialize a lock; required before use.
665 * Note that clients declare the "struct lock"
666 * variables and then initialize them, rather
667 * than getting a new one from this module.
673 __unused
unsigned short tag
,
676 (void) memset((void *) l
, 0, sizeof(lock_t
));
678 simple_lock_init(&l
->interlock
, tag1
);
679 l
->want_write
= FALSE
;
680 l
->want_upgrade
= FALSE
;
682 l
->can_sleep
= can_sleep
;
687 * Sleep locks. These use the same data structure and algorithm
688 * as the spin locks, but the process sleeps while it is waiting
689 * for the lock. These work on uniprocessor systems.
692 #define DECREMENTER_TIMEOUT 1000000
699 boolean_t lock_miss
= FALSE
;
702 #endif /* MACH_LDEBUG */
704 simple_lock(&l
->interlock
);
707 decrementer
= DECREMENTER_TIMEOUT
;
708 #endif /* MACH_LDEBUG */
711 * Try to acquire the want_write bit.
713 while (l
->want_write
) {
718 i
= lock_wait_time
[l
->can_sleep
? 1 : 0];
720 simple_unlock(&l
->interlock
);
723 Debugger("timeout - want_write");
724 #endif /* MACH_LDEBUG */
725 while (--i
!= 0 && l
->want_write
)
727 simple_lock(&l
->interlock
);
730 if (l
->can_sleep
&& l
->want_write
) {
732 thread_sleep_simple_lock((event_t
) l
,
733 simple_lock_addr(l
->interlock
),
735 /* interlock relocked */
738 l
->want_write
= TRUE
;
740 /* Wait for readers (and upgrades) to finish */
743 decrementer
= DECREMENTER_TIMEOUT
;
744 #endif /* MACH_LDEBUG */
745 while ((l
->read_count
!= 0) || l
->want_upgrade
) {
750 i
= lock_wait_time
[l
->can_sleep
? 1 : 0];
752 simple_unlock(&l
->interlock
);
755 Debugger("timeout - wait for readers");
756 #endif /* MACH_LDEBUG */
757 while (--i
!= 0 && (l
->read_count
!= 0 ||
760 simple_lock(&l
->interlock
);
763 if (l
->can_sleep
&& (l
->read_count
!= 0 || l
->want_upgrade
)) {
765 thread_sleep_simple_lock((event_t
) l
,
766 simple_lock_addr(l
->interlock
),
768 /* interlock relocked */
772 simple_unlock(&l
->interlock
);
779 boolean_t do_wakeup
= FALSE
;
782 simple_lock(&l
->interlock
);
784 if (l
->read_count
!= 0) {
788 if (l
->want_upgrade
) {
789 l
->want_upgrade
= FALSE
;
792 l
->want_write
= FALSE
;
796 * There is no reason to wakeup a waiting thread
797 * if the read-count is non-zero. Consider:
798 * we must be dropping a read lock
799 * threads are waiting only if one wants a write lock
800 * if there are still readers, they can't proceed
803 if (l
->waiting
&& (l
->read_count
== 0)) {
808 simple_unlock(&l
->interlock
);
811 thread_wakeup((event_t
) l
);
821 #endif /* MACH_LDEBUG */
823 simple_lock(&l
->interlock
);
826 decrementer
= DECREMENTER_TIMEOUT
;
827 #endif /* MACH_LDEBUG */
828 while (l
->want_write
|| l
->want_upgrade
) {
829 i
= lock_wait_time
[l
->can_sleep
? 1 : 0];
832 simple_unlock(&l
->interlock
);
835 Debugger("timeout - wait no writers");
836 #endif /* MACH_LDEBUG */
837 while (--i
!= 0 && (l
->want_write
|| l
->want_upgrade
))
839 simple_lock(&l
->interlock
);
842 if (l
->can_sleep
&& (l
->want_write
|| l
->want_upgrade
)) {
844 thread_sleep_simple_lock((event_t
) l
,
845 simple_lock_addr(l
->interlock
),
847 /* interlock relocked */
853 simple_unlock(&l
->interlock
);
858 * Routine: lock_read_to_write
860 * Improves a read-only lock to one with
861 * write permission. If another reader has
862 * already requested an upgrade to a write lock,
863 * no lock is held upon return.
865 * Returns TRUE if the upgrade *failed*.
873 boolean_t do_wakeup
= FALSE
;
876 #endif /* MACH_LDEBUG */
878 simple_lock(&l
->interlock
);
882 if (l
->want_upgrade
) {
884 * Someone else has requested upgrade.
885 * Since we've released a read lock, wake
888 if (l
->waiting
&& (l
->read_count
== 0)) {
893 simple_unlock(&l
->interlock
);
896 thread_wakeup((event_t
) l
);
900 l
->want_upgrade
= TRUE
;
903 decrementer
= DECREMENTER_TIMEOUT
;
904 #endif /* MACH_LDEBUG */
905 while (l
->read_count
!= 0) {
906 i
= lock_wait_time
[l
->can_sleep
? 1 : 0];
909 simple_unlock(&l
->interlock
);
912 Debugger("timeout - read_count");
913 #endif /* MACH_LDEBUG */
914 while (--i
!= 0 && l
->read_count
!= 0)
916 simple_lock(&l
->interlock
);
919 if (l
->can_sleep
&& l
->read_count
!= 0) {
921 thread_sleep_simple_lock((event_t
) l
,
922 simple_lock_addr(l
->interlock
),
924 /* interlock relocked */
928 simple_unlock(&l
->interlock
);
937 boolean_t do_wakeup
= FALSE
;
939 simple_lock(&l
->interlock
);
943 l
->want_upgrade
= FALSE
;
945 l
->want_write
= FALSE
;
952 simple_unlock(&l
->interlock
);
955 thread_wakeup((event_t
) l
);
961 * Routine: lock_try_write
963 * Tries to get a write lock.
965 * Returns FALSE if the lock is not held on return.
974 simple_lock(&l
->interlock
);
976 if (l
->want_write
|| l
->want_upgrade
|| l
->read_count
) {
980 simple_unlock(&l
->interlock
);
988 l
->want_write
= TRUE
;
990 simple_unlock(&l
->interlock
);
996 * Routine: lock_try_read
998 * Tries to get a read lock.
1000 * Returns FALSE if the lock is not held on return.
1005 register lock_t
* l
)
1009 simple_lock(&l
->interlock
);
1011 if (l
->want_write
|| l
->want_upgrade
) {
1012 simple_unlock(&l
->interlock
);
1018 simple_unlock(&l
->interlock
);
1026 * Routine: lck_rw_alloc_init
1034 if ((lck
= (lck_rw_t
*)kalloc(sizeof(lck_rw_t
))) != 0)
1035 lck_rw_init(lck
, grp
, attr
);
1041 * Routine: lck_rw_free
1047 lck_rw_destroy(lck
, grp
);
1048 kfree(lck
, sizeof(lck_rw_t
));
1052 * Routine: lck_rw_init
1058 __unused lck_attr_t
*attr
) {
1060 hw_lock_init(&lck
->interlock
);
1061 lck
->want_write
= FALSE
;
1062 lck
->want_upgrade
= FALSE
;
1063 lck
->read_count
= 0;
1064 lck
->can_sleep
= TRUE
;
1065 lck
->lck_rw_tag
= 0;
1067 lck_grp_reference(grp
);
1068 lck_grp_lckcnt_incr(grp
, LCK_TYPE_RW
);
1072 * Routine: lck_rw_destroy
1078 if (lck
->lck_rw_tag
== LCK_RW_TAG_DESTROYED
)
1080 lck
->lck_rw_tag
= LCK_RW_TAG_DESTROYED
;
1081 lck_grp_lckcnt_decr(grp
, LCK_TYPE_RW
);
1082 lck_grp_deallocate(grp
);
1087 * Sleep locks. These use the same data structure and algorithm
1088 * as the spin locks, but the process sleeps while it is waiting
1089 * for the lock. These work on uniprocessor systems.
1092 #define DECREMENTER_TIMEOUT 1000000
1096 * We need to disable interrupts while holding the mutex interlock
1097 * to prevent an IPI intervening.
1098 * Hence, local helper functions lck_interlock_lock()/lck_interlock_unlock().
1101 lck_interlock_lock(lck_rw_t
*lck
)
1105 istate
= ml_set_interrupts_enabled(FALSE
);
1106 hw_lock_lock(&lck
->interlock
);
1112 lck_interlock_unlock(lck_rw_t
*lck
, boolean_t istate
)
1114 hw_lock_unlock(&lck
->interlock
);
1115 ml_set_interrupts_enabled(istate
);
1119 * Routine: lck_rw_lock_exclusive
1122 lck_rw_lock_exclusive(
1126 boolean_t lock_miss
= FALSE
;
1130 #endif /* MACH_LDEBUG */
1133 istate
= lck_interlock_lock(lck
);
1136 decrementer
= DECREMENTER_TIMEOUT
;
1137 #endif /* MACH_LDEBUG */
1140 * Try to acquire the want_write bit.
1142 while (lck
->want_write
) {
1143 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EXCLUSIVE_CODE
) | DBG_FUNC_START
, (int)lck
, 0, 0, 0, 0);
1149 i
= lock_wait_time
[lck
->can_sleep
? 1 : 0];
1151 lck_interlock_unlock(lck
, istate
);
1154 Debugger("timeout - want_write");
1155 #endif /* MACH_LDEBUG */
1156 while (--i
!= 0 && lck
->want_write
)
1158 istate
= lck_interlock_lock(lck
);
1161 if (lck
->can_sleep
&& lck
->want_write
) {
1162 lck
->waiting
= TRUE
;
1163 res
= assert_wait((event_t
) lck
, THREAD_UNINT
);
1164 if (res
== THREAD_WAITING
) {
1165 lck_interlock_unlock(lck
, istate
);
1166 res
= thread_block(THREAD_CONTINUE_NULL
);
1167 istate
= lck_interlock_lock(lck
);
1170 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EXCLUSIVE_CODE
) | DBG_FUNC_END
, (int)lck
, res
, 0, 0, 0);
1172 lck
->want_write
= TRUE
;
1174 /* Wait for readers (and upgrades) to finish */
1177 decrementer
= DECREMENTER_TIMEOUT
;
1178 #endif /* MACH_LDEBUG */
1179 while ((lck
->read_count
!= 0) || lck
->want_upgrade
) {
1184 i
= lock_wait_time
[lck
->can_sleep
? 1 : 0];
1186 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EXCLUSIVE1_CODE
) | DBG_FUNC_START
,
1187 (int)lck
, lck
->read_count
, lck
->want_upgrade
, i
, 0);
1190 lck_interlock_unlock(lck
, istate
);
1193 Debugger("timeout - wait for readers");
1194 #endif /* MACH_LDEBUG */
1195 while (--i
!= 0 && (lck
->read_count
!= 0 ||
1198 istate
= lck_interlock_lock(lck
);
1201 if (lck
->can_sleep
&& (lck
->read_count
!= 0 || lck
->want_upgrade
)) {
1202 lck
->waiting
= TRUE
;
1203 res
= assert_wait((event_t
) lck
, THREAD_UNINT
);
1204 if (res
== THREAD_WAITING
) {
1205 lck_interlock_unlock(lck
, istate
);
1206 res
= thread_block(THREAD_CONTINUE_NULL
);
1207 istate
= lck_interlock_lock(lck
);
1210 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EXCLUSIVE1_CODE
) | DBG_FUNC_END
,
1211 (int)lck
, lck
->read_count
, lck
->want_upgrade
, res
, 0);
1214 lck_interlock_unlock(lck
, istate
);
1219 * Routine: lck_rw_done
1225 boolean_t do_wakeup
= FALSE
;
1226 lck_rw_type_t lck_rw_type
;
1230 istate
= lck_interlock_lock(lck
);
1232 if (lck
->read_count
!= 0) {
1233 lck_rw_type
= LCK_RW_TYPE_SHARED
;
1237 lck_rw_type
= LCK_RW_TYPE_EXCLUSIVE
;
1238 if (lck
->want_upgrade
)
1239 lck
->want_upgrade
= FALSE
;
1241 lck
->want_write
= FALSE
;
1245 * There is no reason to wakeup a waiting thread
1246 * if the read-count is non-zero. Consider:
1247 * we must be dropping a read lock
1248 * threads are waiting only if one wants a write lock
1249 * if there are still readers, they can't proceed
1252 if (lck
->waiting
&& (lck
->read_count
== 0)) {
1253 lck
->waiting
= FALSE
;
1257 lck_interlock_unlock(lck
, istate
);
1260 thread_wakeup((event_t
) lck
);
1261 return(lck_rw_type
);
1268 * Routine: lck_rw_unlock
1273 lck_rw_type_t lck_rw_type
)
1275 if (lck_rw_type
== LCK_RW_TYPE_SHARED
)
1276 lck_rw_unlock_shared(lck
);
1277 else if (lck_rw_type
== LCK_RW_TYPE_EXCLUSIVE
)
1278 lck_rw_unlock_exclusive(lck
);
1280 panic("lck_rw_unlock(): Invalid RW lock type: %d\n", lck_rw_type
);
1285 * Routine: lck_rw_unlock_shared
1288 lck_rw_unlock_shared(
1293 ret
= lck_rw_done(lck
);
1295 if (ret
!= LCK_RW_TYPE_SHARED
)
1296 panic("lck_rw_unlock(): lock held in mode: %d\n", ret
);
1301 * Routine: lck_rw_unlock_exclusive
1304 lck_rw_unlock_exclusive(
1309 ret
= lck_rw_done(lck
);
1311 if (ret
!= LCK_RW_TYPE_EXCLUSIVE
)
1312 panic("lck_rw_unlock_exclusive(): lock held in mode: %d\n", ret
);
1317 * Routine: lck_rw_lock
1322 lck_rw_type_t lck_rw_type
)
1324 if (lck_rw_type
== LCK_RW_TYPE_SHARED
)
1325 lck_rw_lock_shared(lck
);
1326 else if (lck_rw_type
== LCK_RW_TYPE_EXCLUSIVE
)
1327 lck_rw_lock_exclusive(lck
);
1329 panic("lck_rw_lock(): Invalid RW lock type: %x\n", lck_rw_type
);
1334 * Routine: lck_rw_lock_shared
1344 #endif /* MACH_LDEBUG */
1347 istate
= lck_interlock_lock(lck
);
1350 decrementer
= DECREMENTER_TIMEOUT
;
1351 #endif /* MACH_LDEBUG */
1352 while (lck
->want_write
|| lck
->want_upgrade
) {
1353 i
= lock_wait_time
[lck
->can_sleep
? 1 : 0];
1355 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SHARED_CODE
) | DBG_FUNC_START
,
1356 (int)lck
, lck
->want_write
, lck
->want_upgrade
, i
, 0);
1359 lck_interlock_unlock(lck
, istate
);
1362 Debugger("timeout - wait no writers");
1363 #endif /* MACH_LDEBUG */
1364 while (--i
!= 0 && (lck
->want_write
|| lck
->want_upgrade
))
1366 istate
= lck_interlock_lock(lck
);
1369 if (lck
->can_sleep
&& (lck
->want_write
|| lck
->want_upgrade
)) {
1370 lck
->waiting
= TRUE
;
1371 res
= assert_wait((event_t
) lck
, THREAD_UNINT
);
1372 if (res
== THREAD_WAITING
) {
1373 lck_interlock_unlock(lck
, istate
);
1374 res
= thread_block(THREAD_CONTINUE_NULL
);
1375 istate
= lck_interlock_lock(lck
);
1378 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SHARED_CODE
) | DBG_FUNC_END
,
1379 (int)lck
, lck
->want_write
, lck
->want_upgrade
, res
, 0);
1384 lck_interlock_unlock(lck
, istate
);
1389 * Routine: lck_rw_lock_shared_to_exclusive
1391 * Improves a read-only lock to one with
1392 * write permission. If another reader has
1393 * already requested an upgrade to a write lock,
1394 * no lock is held upon return.
1396 * Returns TRUE if the upgrade *failed*.
1400 lck_rw_lock_shared_to_exclusive(
1404 boolean_t do_wakeup
= FALSE
;
1408 #endif /* MACH_LDEBUG */
1411 istate
= lck_interlock_lock(lck
);
1415 if (lck
->want_upgrade
) {
1416 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SH_TO_EX_CODE
) | DBG_FUNC_START
,
1417 (int)lck
, lck
->read_count
, lck
->want_upgrade
, 0, 0);
1420 * Someone else has requested upgrade.
1421 * Since we've released a read lock, wake
1424 if (lck
->waiting
&& (lck
->read_count
== 0)) {
1425 lck
->waiting
= FALSE
;
1429 lck_interlock_unlock(lck
, istate
);
1432 thread_wakeup((event_t
) lck
);
1434 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SH_TO_EX_CODE
) | DBG_FUNC_END
,
1435 (int)lck
, lck
->read_count
, lck
->want_upgrade
, 0, 0);
1440 lck
->want_upgrade
= TRUE
;
1443 decrementer
= DECREMENTER_TIMEOUT
;
1444 #endif /* MACH_LDEBUG */
1445 while (lck
->read_count
!= 0) {
1446 i
= lock_wait_time
[lck
->can_sleep
? 1 : 0];
1448 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SH_TO_EX1_CODE
) | DBG_FUNC_START
,
1449 (int)lck
, lck
->read_count
, i
, 0, 0);
1452 lck_interlock_unlock(lck
, istate
);
1455 Debugger("timeout - read_count");
1456 #endif /* MACH_LDEBUG */
1457 while (--i
!= 0 && lck
->read_count
!= 0)
1459 istate
= lck_interlock_lock(lck
);
1462 if (lck
->can_sleep
&& lck
->read_count
!= 0) {
1463 lck
->waiting
= TRUE
;
1464 res
= assert_wait((event_t
) lck
, THREAD_UNINT
);
1465 if (res
== THREAD_WAITING
) {
1466 lck_interlock_unlock(lck
, istate
);
1467 res
= thread_block(THREAD_CONTINUE_NULL
);
1468 istate
= lck_interlock_lock(lck
);
1471 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SH_TO_EX1_CODE
) | DBG_FUNC_END
,
1472 (int)lck
, lck
->read_count
, 0, 0, 0);
1475 lck_interlock_unlock(lck
, istate
);
1481 * Routine: lck_rw_lock_exclusive_to_shared
1484 lck_rw_lock_exclusive_to_shared(
1487 boolean_t do_wakeup
= FALSE
;
1490 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EX_TO_SH_CODE
) | DBG_FUNC_START
,
1491 (int)lck
, lck
->want_write
, lck
->want_upgrade
, 0, 0);
1493 istate
= lck_interlock_lock(lck
);
1496 if (lck
->want_upgrade
)
1497 lck
->want_upgrade
= FALSE
;
1499 lck
->want_write
= FALSE
;
1502 lck
->waiting
= FALSE
;
1506 lck_interlock_unlock(lck
, istate
);
1509 thread_wakeup((event_t
) lck
);
1511 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EX_TO_SH_CODE
) | DBG_FUNC_END
,
1512 (int)lck
, lck
->want_write
, lck
->want_upgrade
, lck
->read_count
, 0);
1518 * Routine: lck_rw_try_lock
1523 lck_rw_type_t lck_rw_type
)
1525 if (lck_rw_type
== LCK_RW_TYPE_SHARED
)
1526 return(lck_rw_try_lock_shared(lck
));
1527 else if (lck_rw_type
== LCK_RW_TYPE_EXCLUSIVE
)
1528 return(lck_rw_try_lock_exclusive(lck
));
1530 panic("lck_rw_try_lock(): Invalid rw lock type: %x\n", lck_rw_type
);
1535 * Routine: lck_rw_try_lock_exclusive
1537 * Tries to get a write lock.
1539 * Returns FALSE if the lock is not held on return.
1543 lck_rw_try_lock_exclusive(
1548 istate
= lck_interlock_lock(lck
);
1550 if (lck
->want_write
|| lck
->want_upgrade
|| lck
->read_count
) {
1554 lck_interlock_unlock(lck
, istate
);
1562 lck
->want_write
= TRUE
;
1564 lck_interlock_unlock(lck
, istate
);
1570 * Routine: lck_rw_try_lock_shared
1572 * Tries to get a read lock.
1574 * Returns FALSE if the lock is not held on return.
1578 lck_rw_try_lock_shared(
1583 istate
= lck_interlock_lock(lck
);
1585 if (lck
->want_write
|| lck
->want_upgrade
) {
1586 lck_interlock_unlock(lck
, istate
);
1592 lck_interlock_unlock(lck
, istate
);
1598 * Routine: lck_mtx_alloc_init
1607 if ((lck
= (lck_mtx_t
*)kalloc(sizeof(lck_mtx_t
))) != 0)
1608 lck_mtx_init(lck
, grp
, attr
);
1614 * Routine: lck_mtx_free
1621 lck_mtx_destroy(lck
, grp
);
1622 kfree(lck
, sizeof(lck_mtx_t
));
1626 * Routine: lck_mtx_ext_init
1634 lck
->lck_mtx
.lck_mtx_ilk
= 0;
1635 lck
->lck_mtx
.lck_mtx_locked
= 0;
1636 lck
->lck_mtx
.lck_mtx_waiters
= 0;
1637 lck
->lck_mtx
.lck_mtx_pri
= 0;
1638 lck
->lck_mtx_attr
= 0;
1640 if ((attr
->lck_attr_val
) & LCK_ATTR_DEBUG
) {
1641 lck
->lck_mtx_deb
.pc
= 0;
1642 lck
->lck_mtx_deb
.thread
= 0;
1643 lck
->lck_mtx_deb
.type
= MUTEX_TAG
;
1644 lck
->lck_mtx_attr
|= LCK_MTX_ATTR_DEBUG
;
1647 lck
->lck_mtx_grp
= grp
;
1651 * Routine: lck_mtx_init
1659 lck_mtx_ext_t
*lck_ext
;
1661 if ((attr
!= LCK_ATTR_NULL
) && ((attr
->lck_attr_val
) & LCK_ATTR_DEBUG
)) {
1662 if ((lck_ext
= (lck_mtx_ext_t
*)kalloc(sizeof(lck_mtx_ext_t
))) != 0) {
1663 lck_mtx_ext_init(lck_ext
, grp
, attr
);
1664 lck
->lck_mtx_tag
= LCK_MTX_TAG_INDIRECT
;
1665 lck
->lck_mtx_ptr
= lck_ext
;
1668 lck
->lck_mtx_ilk
= 0;
1669 lck
->lck_mtx_locked
= 0;
1670 lck
->lck_mtx_waiters
= 0;
1671 lck
->lck_mtx_pri
= 0;
1673 lck_grp_reference(grp
);
1674 lck_grp_lckcnt_incr(grp
, LCK_TYPE_MTX
);
1678 * Routine: lck_mtx_destroy
1685 boolean_t lck_is_indirect
;
1687 if (lck
->lck_mtx_tag
== LCK_MTX_TAG_DESTROYED
)
1689 lck_is_indirect
= (lck
->lck_mtx_tag
== LCK_MTX_TAG_INDIRECT
);
1690 lck
->lck_mtx_tag
= LCK_MTX_TAG_DESTROYED
;
1691 if (lck_is_indirect
)
1692 kfree(lck
->lck_mtx_ptr
, sizeof(lck_mtx_ext_t
));
1693 lck_grp_lckcnt_decr(grp
, LCK_TYPE_MTX
);
1694 lck_grp_deallocate(grp
);
1699 * Routine: lck_mtx_assert
1703 __unused lck_mtx_t
*lck
,
1704 __unused
unsigned int type
)
1710 void db_show_one_lock(lock_t
*);
1716 db_printf("Read_count = 0x%x, %swant_upgrade, %swant_write, ",
1718 lock
->want_upgrade
? "" : "!",
1719 lock
->want_write
? "" : "!");
1720 db_printf("%swaiting, %scan_sleep\n",
1721 lock
->waiting
? "" : "!", lock
->can_sleep
? "" : "!");
1722 db_printf("Interlock:\n");
1723 db_show_one_simple_lock((db_expr_t
)simple_lock_addr(lock
->interlock
),
1724 TRUE
, (db_expr_t
)0, (char *)0);
1727 #endif /* MACH_KDB */
1730 * The C portion of the mutex package. These routines are only invoked
1731 * if the optimized assembler routines can't do the work.
1735 * Routine: lock_alloc
1737 * Allocate a mutex for external users who cannot
1738 * hard-code the structure definition into their
1740 * For now just use kalloc, but a zone is probably
1749 if ((m
= (mutex_t
*)kalloc(sizeof(mutex_t
))) != 0)
1755 * Routine: mutex_free
1757 * Free a mutex allocated for external users.
1758 * For now just use kfree, but a zone is probably
1765 kfree(m
, sizeof(mutex_t
));
1769 * Routine: _mutex_assert
1777 thread_t thread
= current_thread();
1780 if (panicstr
!= NULL
)
1783 holder
= (thread_t
) mutex
->lck_mtx
.lck_mtx_locked
;
1787 if (thread
!= holder
)
1788 panic("mutex %x not owned\n", mutex
);
1792 if (thread
== holder
)
1793 panic("mutex %x owned\n", mutex
);
1801 * Routines to print out simple_locks and mutexes in a nicely-formatted
1805 char *simple_lock_labels
= "ENTRY ILK THREAD DURATION CALLER";
1806 char *mutex_labels
= "ENTRY LOCKED WAITERS THREAD CALLER";
1809 db_show_one_simple_lock (
1811 boolean_t have_addr
,
1815 simple_lock_t saddr
= (simple_lock_t
)addr
;
1817 if (saddr
== (simple_lock_t
)0 || !have_addr
) {
1818 db_error ("No simple_lock\n");
1821 else if (saddr
->lock_type
!= USLOCK_TAG
)
1822 db_error ("Not a simple_lock\n");
1823 #endif /* USLOCK_DEBUG */
1825 db_printf ("%s\n", simple_lock_labels
);
1826 db_print_simple_lock (saddr
);
1830 db_print_simple_lock (
1834 db_printf ("%08x %3d", addr
, *hw_lock_addr(addr
->interlock
));
1836 db_printf (" %08x", addr
->debug
.lock_thread
);
1837 db_printf (" %08x ", addr
->debug
.duration
[1]);
1838 db_printsym ((int)addr
->debug
.lock_pc
, DB_STGY_ANY
);
1839 #endif /* USLOCK_DEBUG */
1846 boolean_t have_addr
,
1850 mutex_t
* maddr
= (mutex_t
*)addr
;
1852 if (maddr
== (mutex_t
*)0 || !have_addr
)
1853 db_error ("No mutex\n");
1855 else if (maddr
->type
!= MUTEX_TAG
)
1856 db_error ("Not a mutex\n");
1857 #endif /* MACH_LDEBUG */
1859 db_printf ("%s\n", mutex_labels
);
1860 db_print_mutex (maddr
);
1867 db_printf ("%08x %6d %7d",
1868 addr
, *addr
, addr
->lck_mtx
.lck_mtx_waiters
);
1870 db_printf (" %08x ", addr
->thread
);
1871 db_printsym (addr
->pc
, DB_STGY_ANY
);
1872 #endif /* MACH_LDEBUG */
1876 #endif /* MACH_KDB */