2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_OSREFERENCE_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
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
34 * Mach Operating System
35 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
36 * All Rights Reserved.
38 * Permission to use, copy, modify and distribute this software and its
39 * documentation is hereby granted, provided that both the copyright
40 * notice and this permission notice appear in all copies of the
41 * software, derivative works or modified versions, and any portions
42 * thereof, and that both notices appear in supporting documentation.
44 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
45 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
46 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
48 * Carnegie Mellon requests users of this software to return to
50 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
51 * School of Computer Science
52 * Carnegie Mellon University
53 * Pittsburgh PA 15213-3890
55 * any improvements or extensions that they make and grant Carnegie Mellon
56 * the rights to redistribute these changes.
60 * Author: Avadis Tevanian, Jr., Michael Wayne Young
63 * Locking primitives implementation
67 #include <mach_ldebug.h>
69 #include <kern/lock.h>
70 #include <kern/locks.h>
71 #include <kern/kalloc.h>
72 #include <kern/misc_protos.h>
73 #include <kern/thread.h>
74 #include <kern/processor.h>
75 #include <kern/cpu_data.h>
76 #include <kern/cpu_number.h>
77 #include <kern/sched_prim.h>
79 #include <kern/debug.h>
83 #include <ddb/db_command.h>
84 #include <ddb/db_output.h>
85 #include <ddb/db_sym.h>
86 #include <ddb/db_print.h>
90 #include <ppc/Firmware.h>
93 #include <sys/kdebug.h>
95 #define LCK_RW_LCK_EXCLUSIVE_CODE 0x100
96 #define LCK_RW_LCK_EXCLUSIVE1_CODE 0x101
97 #define LCK_RW_LCK_SHARED_CODE 0x102
98 #define LCK_RW_LCK_SH_TO_EX_CODE 0x103
99 #define LCK_RW_LCK_SH_TO_EX1_CODE 0x104
100 #define LCK_RW_LCK_EX_TO_SH_CODE 0x105
103 #define ANY_LOCK_DEBUG (USLOCK_DEBUG || LOCK_DEBUG || MUTEX_DEBUG)
105 unsigned int LcksOpts
=0;
106 unsigned int lock_wait_time
[2] = { (unsigned int)-1, 100 } ;
111 void db_print_simple_lock(
116 #endif /* MACH_KDB */
121 * Perform simple lock checks.
123 int uslock_check
= 1;
124 int max_lock_loops
= 100000000;
125 decl_simple_lock_data(extern , printf_lock
)
126 decl_simple_lock_data(extern , panic_lock
)
128 decl_simple_lock_data(extern , kdb_lock
)
129 #endif /* MACH_KDB */
130 #endif /* USLOCK_DEBUG */
134 * We often want to know the addresses of the callers
135 * of the various lock routines. However, this information
136 * is only used for debugging and statistics.
139 #define INVALID_PC ((void *) VM_MAX_KERNEL_ADDRESS)
140 #define INVALID_THREAD ((void *) VM_MAX_KERNEL_ADDRESS)
142 #define OBTAIN_PC(pc,l) ((pc) = (void *) GET_RETURN_PC(&(l)))
143 #define DECL_PC(pc) pc_t pc;
144 #else /* ANY_LOCK_DEBUG */
148 * Eliminate lint complaints about unused local pc variables.
150 #define OBTAIN_PC(pc,l) ++pc
152 #define OBTAIN_PC(pc,l)
154 #endif /* USLOCK_DEBUG */
158 * Portable lock package implementation of usimple_locks.
162 #define USLDBG(stmt) stmt
163 void usld_lock_init(usimple_lock_t
, unsigned short);
164 void usld_lock_pre(usimple_lock_t
, pc_t
);
165 void usld_lock_post(usimple_lock_t
, pc_t
);
166 void usld_unlock(usimple_lock_t
, pc_t
);
167 void usld_lock_try_pre(usimple_lock_t
, pc_t
);
168 void usld_lock_try_post(usimple_lock_t
, pc_t
);
169 int usld_lock_common_checks(usimple_lock_t
, char *);
170 #else /* USLOCK_DEBUG */
172 #endif /* USLOCK_DEBUG */
175 * Routine: lck_spin_alloc_init
184 if ((lck
= (lck_spin_t
*)kalloc(sizeof(lck_spin_t
))) != 0)
185 lck_spin_init(lck
, grp
, attr
);
191 * Routine: lck_spin_free
198 lck_spin_destroy(lck
, grp
);
199 kfree(lck
, sizeof(lck_spin_t
));
203 * Routine: lck_spin_init
209 __unused lck_attr_t
*attr
)
211 usimple_lock_init((usimple_lock_t
) lck
, 0);
212 lck_grp_reference(grp
);
213 lck_grp_lckcnt_incr(grp
, LCK_TYPE_SPIN
);
217 * Routine: lck_spin_destroy
224 if (lck
->lck_spin_data
[0] == LCK_SPIN_TAG_DESTROYED
)
226 lck
->lck_spin_data
[0] = LCK_SPIN_TAG_DESTROYED
;
227 lck_grp_lckcnt_decr(grp
, LCK_TYPE_SPIN
);
228 lck_grp_deallocate(grp
);
233 * Routine: lck_spin_lock
239 usimple_lock((usimple_lock_t
) lck
);
243 * Routine: lck_spin_unlock
249 usimple_unlock((usimple_lock_t
) lck
);
254 * Routine: lck_spin_try_lock
260 usimple_lock_try((usimple_lock_t
) lck
);
264 * Initialize a usimple_lock.
266 * No change in preemption state.
271 __unused
unsigned short tag
)
273 #ifndef MACHINE_SIMPLE_LOCK
274 USLDBG(usld_lock_init(l
, tag
));
275 hw_lock_init(&l
->interlock
);
277 simple_lock_init((simple_lock_t
)l
,tag
);
283 * Acquire a usimple_lock.
285 * Returns with preemption disabled. Note
286 * that the hw_lock routines are responsible for
287 * maintaining preemption state.
293 #ifndef MACHINE_SIMPLE_LOCK
297 USLDBG(usld_lock_pre(l
, pc
));
299 if(!hw_lock_to(&l
->interlock
, LockTimeOut
)) /* Try to get the lock with a timeout */
300 panic("simple lock deadlock detection - l=%08X, cpu=%d, ret=%08X", l
, cpu_number(), pc
);
302 USLDBG(usld_lock_post(l
, pc
));
304 simple_lock((simple_lock_t
)l
);
310 * Release a usimple_lock.
312 * Returns with preemption enabled. Note
313 * that the hw_lock routines are responsible for
314 * maintaining preemption state.
320 #ifndef MACHINE_SIMPLE_LOCK
324 USLDBG(usld_unlock(l
, pc
));
325 hw_lock_unlock(&l
->interlock
);
327 simple_unlock_rwmb((simple_lock_t
)l
);
333 * Conditionally acquire a usimple_lock.
335 * On success, returns with preemption disabled.
336 * On failure, returns with preemption in the same state
337 * as when first invoked. Note that the hw_lock routines
338 * are responsible for maintaining preemption state.
340 * XXX No stats are gathered on a miss; I preserved this
341 * behavior from the original assembly-language code, but
342 * doesn't it make sense to log misses? XXX
348 #ifndef MACHINE_SIMPLE_LOCK
350 unsigned int success
;
353 USLDBG(usld_lock_try_pre(l
, pc
));
354 if ((success
= hw_lock_try(&l
->interlock
))) {
355 USLDBG(usld_lock_try_post(l
, pc
));
359 return(simple_lock_try((simple_lock_t
)l
));
365 * States of a usimple_lock. The default when initializing
366 * a usimple_lock is setting it up for debug checking.
368 #define USLOCK_CHECKED 0x0001 /* lock is being checked */
369 #define USLOCK_TAKEN 0x0002 /* lock has been taken */
370 #define USLOCK_INIT 0xBAA0 /* lock has been initialized */
371 #define USLOCK_INITIALIZED (USLOCK_INIT|USLOCK_CHECKED)
372 #define USLOCK_CHECKING(l) (uslock_check && \
373 ((l)->debug.state & USLOCK_CHECKED))
376 * Trace activities of a particularly interesting lock.
378 void usl_trace(usimple_lock_t
, int, pc_t
, const char *);
382 * Initialize the debugging information contained
388 __unused
unsigned short tag
)
390 if (l
== USIMPLE_LOCK_NULL
)
391 panic("lock initialization: null lock pointer");
392 l
->lock_type
= USLOCK_TAG
;
393 l
->debug
.state
= uslock_check
? USLOCK_INITIALIZED
: 0;
394 l
->debug
.lock_cpu
= l
->debug
.unlock_cpu
= 0;
395 l
->debug
.lock_pc
= l
->debug
.unlock_pc
= INVALID_PC
;
396 l
->debug
.lock_thread
= l
->debug
.unlock_thread
= INVALID_THREAD
;
397 l
->debug
.duration
[0] = l
->debug
.duration
[1] = 0;
398 l
->debug
.unlock_cpu
= l
->debug
.unlock_cpu
= 0;
399 l
->debug
.unlock_pc
= l
->debug
.unlock_pc
= INVALID_PC
;
400 l
->debug
.unlock_thread
= l
->debug
.unlock_thread
= INVALID_THREAD
;
405 * These checks apply to all usimple_locks, not just
406 * those with USLOCK_CHECKED turned on.
409 usld_lock_common_checks(
413 if (l
== USIMPLE_LOCK_NULL
)
414 panic("%s: null lock pointer", caller
);
415 if (l
->lock_type
!= USLOCK_TAG
)
416 panic("%s: 0x%x is not a usimple lock", caller
, (integer_t
) l
);
417 if (!(l
->debug
.state
& USLOCK_INIT
))
418 panic("%s: 0x%x is not an initialized lock",
419 caller
, (integer_t
) l
);
420 return USLOCK_CHECKING(l
);
425 * Debug checks on a usimple_lock just before attempting
434 char caller
[] = "usimple_lock";
437 if (!usld_lock_common_checks(l
, caller
))
441 * Note that we have a weird case where we are getting a lock when we are]
442 * in the process of putting the system to sleep. We are running with no
443 * current threads, therefore we can't tell if we are trying to retake a lock
444 * we have or someone on the other processor has it. Therefore we just
445 * ignore this test if the locking thread is 0.
448 if ((l
->debug
.state
& USLOCK_TAKEN
) && l
->debug
.lock_thread
&&
449 l
->debug
.lock_thread
== (void *) current_thread()) {
450 printf("%s: lock 0x%x already locked (at 0x%x) by",
451 caller
, (integer_t
) l
, l
->debug
.lock_pc
);
452 printf(" current thread 0x%x (new attempt at pc 0x%x)\n",
453 l
->debug
.lock_thread
, pc
);
456 mp_disable_preemption();
457 usl_trace(l
, cpu_number(), pc
, caller
);
458 mp_enable_preemption();
463 * Debug checks on a usimple_lock just after acquiring it.
465 * Pre-emption has been disabled at this point,
466 * so we are safe in using cpu_number.
474 char caller
[] = "successful usimple_lock";
477 if (!usld_lock_common_checks(l
, caller
))
480 if (!((l
->debug
.state
& ~USLOCK_TAKEN
) == USLOCK_INITIALIZED
))
481 panic("%s: lock 0x%x became uninitialized",
482 caller
, (integer_t
) l
);
483 if ((l
->debug
.state
& USLOCK_TAKEN
))
484 panic("%s: lock 0x%x became TAKEN by someone else",
485 caller
, (integer_t
) l
);
487 mycpu
= cpu_number();
488 l
->debug
.lock_thread
= (void *)current_thread();
489 l
->debug
.state
|= USLOCK_TAKEN
;
490 l
->debug
.lock_pc
= pc
;
491 l
->debug
.lock_cpu
= mycpu
;
493 usl_trace(l
, mycpu
, pc
, caller
);
498 * Debug checks on a usimple_lock just before
499 * releasing it. Note that the caller has not
500 * yet released the hardware lock.
502 * Preemption is still disabled, so there's
503 * no problem using cpu_number.
511 char caller
[] = "usimple_unlock";
514 if (!usld_lock_common_checks(l
, caller
))
517 mycpu
= cpu_number();
519 if (!(l
->debug
.state
& USLOCK_TAKEN
))
520 panic("%s: lock 0x%x hasn't been taken",
521 caller
, (integer_t
) l
);
522 if (l
->debug
.lock_thread
!= (void *) current_thread())
523 panic("%s: unlocking lock 0x%x, owned by thread 0x%x",
524 caller
, (integer_t
) l
, l
->debug
.lock_thread
);
525 if (l
->debug
.lock_cpu
!= mycpu
) {
526 printf("%s: unlocking lock 0x%x on cpu 0x%x",
527 caller
, (integer_t
) l
, mycpu
);
528 printf(" (acquired on cpu 0x%x)\n", l
->debug
.lock_cpu
);
531 usl_trace(l
, mycpu
, pc
, caller
);
533 l
->debug
.unlock_thread
= l
->debug
.lock_thread
;
534 l
->debug
.lock_thread
= INVALID_PC
;
535 l
->debug
.state
&= ~USLOCK_TAKEN
;
536 l
->debug
.unlock_pc
= pc
;
537 l
->debug
.unlock_cpu
= mycpu
;
542 * Debug checks on a usimple_lock just before
543 * attempting to acquire it.
545 * Preemption isn't guaranteed to be disabled.
552 char caller
[] = "usimple_lock_try";
554 if (!usld_lock_common_checks(l
, caller
))
556 mp_disable_preemption();
557 usl_trace(l
, cpu_number(), pc
, caller
);
558 mp_enable_preemption();
563 * Debug checks on a usimple_lock just after
564 * successfully attempting to acquire it.
566 * Preemption has been disabled by the
567 * lock acquisition attempt, so it's safe
576 char caller
[] = "successful usimple_lock_try";
578 if (!usld_lock_common_checks(l
, caller
))
581 if (!((l
->debug
.state
& ~USLOCK_TAKEN
) == USLOCK_INITIALIZED
))
582 panic("%s: lock 0x%x became uninitialized",
583 caller
, (integer_t
) l
);
584 if ((l
->debug
.state
& USLOCK_TAKEN
))
585 panic("%s: lock 0x%x became TAKEN by someone else",
586 caller
, (integer_t
) l
);
588 mycpu
= cpu_number();
589 l
->debug
.lock_thread
= (void *) current_thread();
590 l
->debug
.state
|= USLOCK_TAKEN
;
591 l
->debug
.lock_pc
= pc
;
592 l
->debug
.lock_cpu
= mycpu
;
594 usl_trace(l
, mycpu
, pc
, caller
);
599 * For very special cases, set traced_lock to point to a
600 * specific lock of interest. The result is a series of
601 * XPRs showing lock operations on that lock. The lock_seq
602 * value is used to show the order of those operations.
604 usimple_lock_t traced_lock
;
605 unsigned int lock_seq
;
612 const char * op_name
)
614 if (traced_lock
== l
) {
616 "seq %d, cpu %d, %s @ %x\n",
617 (integer_t
) lock_seq
, (integer_t
) mycpu
,
618 (integer_t
) op_name
, (integer_t
) pc
, 0);
624 #endif /* USLOCK_DEBUG */
627 * Routine: lock_alloc
629 * Allocate a lock for external users who cannot
630 * hard-code the structure definition into their
632 * For now just use kalloc, but a zone is probably
643 if ((l
= (lock_t
*)kalloc(sizeof(lock_t
))) != 0)
644 lock_init(l
, can_sleep
, tag
, tag1
);
651 * Free a lock allocated for external users.
652 * For now just use kfree, but a zone is probably
659 kfree(l
, sizeof(lock_t
));
666 * Initialize a lock; required before use.
667 * Note that clients declare the "struct lock"
668 * variables and then initialize them, rather
669 * than getting a new one from this module.
675 __unused
unsigned short tag
,
678 (void) memset((void *) l
, 0, sizeof(lock_t
));
680 simple_lock_init(&l
->interlock
, tag1
);
681 l
->want_write
= FALSE
;
682 l
->want_upgrade
= FALSE
;
684 l
->can_sleep
= can_sleep
;
689 * Sleep locks. These use the same data structure and algorithm
690 * as the spin locks, but the process sleeps while it is waiting
691 * for the lock. These work on uniprocessor systems.
694 #define DECREMENTER_TIMEOUT 1000000
701 boolean_t lock_miss
= FALSE
;
704 #endif /* MACH_LDEBUG */
706 simple_lock(&l
->interlock
);
709 decrementer
= DECREMENTER_TIMEOUT
;
710 #endif /* MACH_LDEBUG */
713 * Try to acquire the want_write bit.
715 while (l
->want_write
) {
720 i
= lock_wait_time
[l
->can_sleep
? 1 : 0];
722 simple_unlock(&l
->interlock
);
725 Debugger("timeout - want_write");
726 #endif /* MACH_LDEBUG */
727 while (--i
!= 0 && l
->want_write
)
729 simple_lock(&l
->interlock
);
732 if (l
->can_sleep
&& l
->want_write
) {
734 thread_sleep_simple_lock((event_t
) l
,
735 simple_lock_addr(l
->interlock
),
737 /* interlock relocked */
740 l
->want_write
= TRUE
;
742 /* Wait for readers (and upgrades) to finish */
745 decrementer
= DECREMENTER_TIMEOUT
;
746 #endif /* MACH_LDEBUG */
747 while ((l
->read_count
!= 0) || l
->want_upgrade
) {
752 i
= lock_wait_time
[l
->can_sleep
? 1 : 0];
754 simple_unlock(&l
->interlock
);
757 Debugger("timeout - wait for readers");
758 #endif /* MACH_LDEBUG */
759 while (--i
!= 0 && (l
->read_count
!= 0 ||
762 simple_lock(&l
->interlock
);
765 if (l
->can_sleep
&& (l
->read_count
!= 0 || l
->want_upgrade
)) {
767 thread_sleep_simple_lock((event_t
) l
,
768 simple_lock_addr(l
->interlock
),
770 /* interlock relocked */
774 simple_unlock(&l
->interlock
);
781 boolean_t do_wakeup
= FALSE
;
784 simple_lock(&l
->interlock
);
786 if (l
->read_count
!= 0) {
790 if (l
->want_upgrade
) {
791 l
->want_upgrade
= FALSE
;
794 l
->want_write
= FALSE
;
798 * There is no reason to wakeup a waiting thread
799 * if the read-count is non-zero. Consider:
800 * we must be dropping a read lock
801 * threads are waiting only if one wants a write lock
802 * if there are still readers, they can't proceed
805 if (l
->waiting
&& (l
->read_count
== 0)) {
810 simple_unlock(&l
->interlock
);
813 thread_wakeup((event_t
) l
);
823 #endif /* MACH_LDEBUG */
825 simple_lock(&l
->interlock
);
828 decrementer
= DECREMENTER_TIMEOUT
;
829 #endif /* MACH_LDEBUG */
830 while (l
->want_write
|| l
->want_upgrade
) {
831 i
= lock_wait_time
[l
->can_sleep
? 1 : 0];
834 simple_unlock(&l
->interlock
);
837 Debugger("timeout - wait no writers");
838 #endif /* MACH_LDEBUG */
839 while (--i
!= 0 && (l
->want_write
|| l
->want_upgrade
))
841 simple_lock(&l
->interlock
);
844 if (l
->can_sleep
&& (l
->want_write
|| l
->want_upgrade
)) {
846 thread_sleep_simple_lock((event_t
) l
,
847 simple_lock_addr(l
->interlock
),
849 /* interlock relocked */
855 simple_unlock(&l
->interlock
);
860 * Routine: lock_read_to_write
862 * Improves a read-only lock to one with
863 * write permission. If another reader has
864 * already requested an upgrade to a write lock,
865 * no lock is held upon return.
867 * Returns TRUE if the upgrade *failed*.
875 boolean_t do_wakeup
= FALSE
;
878 #endif /* MACH_LDEBUG */
880 simple_lock(&l
->interlock
);
884 if (l
->want_upgrade
) {
886 * Someone else has requested upgrade.
887 * Since we've released a read lock, wake
890 if (l
->waiting
&& (l
->read_count
== 0)) {
895 simple_unlock(&l
->interlock
);
898 thread_wakeup((event_t
) l
);
902 l
->want_upgrade
= TRUE
;
905 decrementer
= DECREMENTER_TIMEOUT
;
906 #endif /* MACH_LDEBUG */
907 while (l
->read_count
!= 0) {
908 i
= lock_wait_time
[l
->can_sleep
? 1 : 0];
911 simple_unlock(&l
->interlock
);
914 Debugger("timeout - read_count");
915 #endif /* MACH_LDEBUG */
916 while (--i
!= 0 && l
->read_count
!= 0)
918 simple_lock(&l
->interlock
);
921 if (l
->can_sleep
&& l
->read_count
!= 0) {
923 thread_sleep_simple_lock((event_t
) l
,
924 simple_lock_addr(l
->interlock
),
926 /* interlock relocked */
930 simple_unlock(&l
->interlock
);
939 boolean_t do_wakeup
= FALSE
;
941 simple_lock(&l
->interlock
);
945 l
->want_upgrade
= FALSE
;
947 l
->want_write
= FALSE
;
954 simple_unlock(&l
->interlock
);
957 thread_wakeup((event_t
) l
);
963 * Routine: lock_try_write
965 * Tries to get a write lock.
967 * Returns FALSE if the lock is not held on return.
976 simple_lock(&l
->interlock
);
978 if (l
->want_write
|| l
->want_upgrade
|| l
->read_count
) {
982 simple_unlock(&l
->interlock
);
990 l
->want_write
= TRUE
;
992 simple_unlock(&l
->interlock
);
998 * Routine: lock_try_read
1000 * Tries to get a read lock.
1002 * Returns FALSE if the lock is not held on return.
1007 register lock_t
* l
)
1011 simple_lock(&l
->interlock
);
1013 if (l
->want_write
|| l
->want_upgrade
) {
1014 simple_unlock(&l
->interlock
);
1020 simple_unlock(&l
->interlock
);
1028 * Routine: lck_rw_alloc_init
1036 if ((lck
= (lck_rw_t
*)kalloc(sizeof(lck_rw_t
))) != 0)
1037 lck_rw_init(lck
, grp
, attr
);
1043 * Routine: lck_rw_free
1049 lck_rw_destroy(lck
, grp
);
1050 kfree(lck
, sizeof(lck_rw_t
));
1054 * Routine: lck_rw_init
1060 __unused lck_attr_t
*attr
) {
1062 hw_lock_init(&lck
->interlock
);
1063 lck
->want_write
= FALSE
;
1064 lck
->want_upgrade
= FALSE
;
1065 lck
->read_count
= 0;
1066 lck
->can_sleep
= TRUE
;
1067 lck
->lck_rw_tag
= 0;
1069 lck_grp_reference(grp
);
1070 lck_grp_lckcnt_incr(grp
, LCK_TYPE_RW
);
1074 * Routine: lck_rw_destroy
1080 if (lck
->lck_rw_tag
== LCK_RW_TAG_DESTROYED
)
1082 lck
->lck_rw_tag
= LCK_RW_TAG_DESTROYED
;
1083 lck_grp_lckcnt_decr(grp
, LCK_TYPE_RW
);
1084 lck_grp_deallocate(grp
);
1089 * Sleep locks. These use the same data structure and algorithm
1090 * as the spin locks, but the process sleeps while it is waiting
1091 * for the lock. These work on uniprocessor systems.
1094 #define DECREMENTER_TIMEOUT 1000000
1098 * We need to disable interrupts while holding the mutex interlock
1099 * to prevent an IPI intervening.
1100 * Hence, local helper functions lck_interlock_lock()/lck_interlock_unlock().
1103 lck_interlock_lock(lck_rw_t
*lck
)
1107 istate
= ml_set_interrupts_enabled(FALSE
);
1108 hw_lock_lock(&lck
->interlock
);
1114 lck_interlock_unlock(lck_rw_t
*lck
, boolean_t istate
)
1116 hw_lock_unlock(&lck
->interlock
);
1117 ml_set_interrupts_enabled(istate
);
1121 * Routine: lck_rw_lock_exclusive
1124 lck_rw_lock_exclusive(
1128 boolean_t lock_miss
= FALSE
;
1132 #endif /* MACH_LDEBUG */
1135 istate
= lck_interlock_lock(lck
);
1138 decrementer
= DECREMENTER_TIMEOUT
;
1139 #endif /* MACH_LDEBUG */
1142 * Try to acquire the want_write bit.
1144 while (lck
->want_write
) {
1145 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EXCLUSIVE_CODE
) | DBG_FUNC_START
, (int)lck
, 0, 0, 0, 0);
1151 i
= lock_wait_time
[lck
->can_sleep
? 1 : 0];
1153 lck_interlock_unlock(lck
, istate
);
1156 Debugger("timeout - want_write");
1157 #endif /* MACH_LDEBUG */
1158 while (--i
!= 0 && lck
->want_write
)
1160 istate
= lck_interlock_lock(lck
);
1163 if (lck
->can_sleep
&& lck
->want_write
) {
1164 lck
->waiting
= TRUE
;
1165 res
= assert_wait((event_t
) lck
, THREAD_UNINT
);
1166 if (res
== THREAD_WAITING
) {
1167 lck_interlock_unlock(lck
, istate
);
1168 res
= thread_block(THREAD_CONTINUE_NULL
);
1169 istate
= lck_interlock_lock(lck
);
1172 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EXCLUSIVE_CODE
) | DBG_FUNC_END
, (int)lck
, res
, 0, 0, 0);
1174 lck
->want_write
= TRUE
;
1176 /* Wait for readers (and upgrades) to finish */
1179 decrementer
= DECREMENTER_TIMEOUT
;
1180 #endif /* MACH_LDEBUG */
1181 while ((lck
->read_count
!= 0) || lck
->want_upgrade
) {
1186 i
= lock_wait_time
[lck
->can_sleep
? 1 : 0];
1188 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EXCLUSIVE1_CODE
) | DBG_FUNC_START
,
1189 (int)lck
, lck
->read_count
, lck
->want_upgrade
, i
, 0);
1192 lck_interlock_unlock(lck
, istate
);
1195 Debugger("timeout - wait for readers");
1196 #endif /* MACH_LDEBUG */
1197 while (--i
!= 0 && (lck
->read_count
!= 0 ||
1200 istate
= lck_interlock_lock(lck
);
1203 if (lck
->can_sleep
&& (lck
->read_count
!= 0 || lck
->want_upgrade
)) {
1204 lck
->waiting
= TRUE
;
1205 res
= assert_wait((event_t
) lck
, THREAD_UNINT
);
1206 if (res
== THREAD_WAITING
) {
1207 lck_interlock_unlock(lck
, istate
);
1208 res
= thread_block(THREAD_CONTINUE_NULL
);
1209 istate
= lck_interlock_lock(lck
);
1212 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EXCLUSIVE1_CODE
) | DBG_FUNC_END
,
1213 (int)lck
, lck
->read_count
, lck
->want_upgrade
, res
, 0);
1216 lck_interlock_unlock(lck
, istate
);
1221 * Routine: lck_rw_done
1227 boolean_t do_wakeup
= FALSE
;
1228 lck_rw_type_t lck_rw_type
;
1232 istate
= lck_interlock_lock(lck
);
1234 if (lck
->read_count
!= 0) {
1235 lck_rw_type
= LCK_RW_TYPE_SHARED
;
1239 lck_rw_type
= LCK_RW_TYPE_EXCLUSIVE
;
1240 if (lck
->want_upgrade
)
1241 lck
->want_upgrade
= FALSE
;
1243 lck
->want_write
= FALSE
;
1247 * There is no reason to wakeup a waiting thread
1248 * if the read-count is non-zero. Consider:
1249 * we must be dropping a read lock
1250 * threads are waiting only if one wants a write lock
1251 * if there are still readers, they can't proceed
1254 if (lck
->waiting
&& (lck
->read_count
== 0)) {
1255 lck
->waiting
= FALSE
;
1259 lck_interlock_unlock(lck
, istate
);
1262 thread_wakeup((event_t
) lck
);
1263 return(lck_rw_type
);
1270 * Routine: lck_rw_unlock
1275 lck_rw_type_t lck_rw_type
)
1277 if (lck_rw_type
== LCK_RW_TYPE_SHARED
)
1278 lck_rw_unlock_shared(lck
);
1279 else if (lck_rw_type
== LCK_RW_TYPE_EXCLUSIVE
)
1280 lck_rw_unlock_exclusive(lck
);
1282 panic("lck_rw_unlock(): Invalid RW lock type: %d\n", lck_rw_type
);
1287 * Routine: lck_rw_unlock_shared
1290 lck_rw_unlock_shared(
1295 ret
= lck_rw_done(lck
);
1297 if (ret
!= LCK_RW_TYPE_SHARED
)
1298 panic("lck_rw_unlock(): lock held in mode: %d\n", ret
);
1303 * Routine: lck_rw_unlock_exclusive
1306 lck_rw_unlock_exclusive(
1311 ret
= lck_rw_done(lck
);
1313 if (ret
!= LCK_RW_TYPE_EXCLUSIVE
)
1314 panic("lck_rw_unlock_exclusive(): lock held in mode: %d\n", ret
);
1319 * Routine: lck_rw_lock
1324 lck_rw_type_t lck_rw_type
)
1326 if (lck_rw_type
== LCK_RW_TYPE_SHARED
)
1327 lck_rw_lock_shared(lck
);
1328 else if (lck_rw_type
== LCK_RW_TYPE_EXCLUSIVE
)
1329 lck_rw_lock_exclusive(lck
);
1331 panic("lck_rw_lock(): Invalid RW lock type: %x\n", lck_rw_type
);
1336 * Routine: lck_rw_lock_shared
1346 #endif /* MACH_LDEBUG */
1349 istate
= lck_interlock_lock(lck
);
1352 decrementer
= DECREMENTER_TIMEOUT
;
1353 #endif /* MACH_LDEBUG */
1354 while (lck
->want_write
|| lck
->want_upgrade
) {
1355 i
= lock_wait_time
[lck
->can_sleep
? 1 : 0];
1357 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SHARED_CODE
) | DBG_FUNC_START
,
1358 (int)lck
, lck
->want_write
, lck
->want_upgrade
, i
, 0);
1361 lck_interlock_unlock(lck
, istate
);
1364 Debugger("timeout - wait no writers");
1365 #endif /* MACH_LDEBUG */
1366 while (--i
!= 0 && (lck
->want_write
|| lck
->want_upgrade
))
1368 istate
= lck_interlock_lock(lck
);
1371 if (lck
->can_sleep
&& (lck
->want_write
|| lck
->want_upgrade
)) {
1372 lck
->waiting
= TRUE
;
1373 res
= assert_wait((event_t
) lck
, THREAD_UNINT
);
1374 if (res
== THREAD_WAITING
) {
1375 lck_interlock_unlock(lck
, istate
);
1376 res
= thread_block(THREAD_CONTINUE_NULL
);
1377 istate
= lck_interlock_lock(lck
);
1380 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SHARED_CODE
) | DBG_FUNC_END
,
1381 (int)lck
, lck
->want_write
, lck
->want_upgrade
, res
, 0);
1386 lck_interlock_unlock(lck
, istate
);
1391 * Routine: lck_rw_lock_shared_to_exclusive
1393 * Improves a read-only lock to one with
1394 * write permission. If another reader has
1395 * already requested an upgrade to a write lock,
1396 * no lock is held upon return.
1398 * Returns TRUE if the upgrade *failed*.
1402 lck_rw_lock_shared_to_exclusive(
1406 boolean_t do_wakeup
= FALSE
;
1410 #endif /* MACH_LDEBUG */
1413 istate
= lck_interlock_lock(lck
);
1417 if (lck
->want_upgrade
) {
1418 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SH_TO_EX_CODE
) | DBG_FUNC_START
,
1419 (int)lck
, lck
->read_count
, lck
->want_upgrade
, 0, 0);
1422 * Someone else has requested upgrade.
1423 * Since we've released a read lock, wake
1426 if (lck
->waiting
&& (lck
->read_count
== 0)) {
1427 lck
->waiting
= FALSE
;
1431 lck_interlock_unlock(lck
, istate
);
1434 thread_wakeup((event_t
) lck
);
1436 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SH_TO_EX_CODE
) | DBG_FUNC_END
,
1437 (int)lck
, lck
->read_count
, lck
->want_upgrade
, 0, 0);
1442 lck
->want_upgrade
= TRUE
;
1445 decrementer
= DECREMENTER_TIMEOUT
;
1446 #endif /* MACH_LDEBUG */
1447 while (lck
->read_count
!= 0) {
1448 i
= lock_wait_time
[lck
->can_sleep
? 1 : 0];
1450 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SH_TO_EX1_CODE
) | DBG_FUNC_START
,
1451 (int)lck
, lck
->read_count
, i
, 0, 0);
1454 lck_interlock_unlock(lck
, istate
);
1457 Debugger("timeout - read_count");
1458 #endif /* MACH_LDEBUG */
1459 while (--i
!= 0 && lck
->read_count
!= 0)
1461 istate
= lck_interlock_lock(lck
);
1464 if (lck
->can_sleep
&& lck
->read_count
!= 0) {
1465 lck
->waiting
= TRUE
;
1466 res
= assert_wait((event_t
) lck
, THREAD_UNINT
);
1467 if (res
== THREAD_WAITING
) {
1468 lck_interlock_unlock(lck
, istate
);
1469 res
= thread_block(THREAD_CONTINUE_NULL
);
1470 istate
= lck_interlock_lock(lck
);
1473 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SH_TO_EX1_CODE
) | DBG_FUNC_END
,
1474 (int)lck
, lck
->read_count
, 0, 0, 0);
1477 lck_interlock_unlock(lck
, istate
);
1483 * Routine: lck_rw_lock_exclusive_to_shared
1486 lck_rw_lock_exclusive_to_shared(
1489 boolean_t do_wakeup
= FALSE
;
1492 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EX_TO_SH_CODE
) | DBG_FUNC_START
,
1493 (int)lck
, lck
->want_write
, lck
->want_upgrade
, 0, 0);
1495 istate
= lck_interlock_lock(lck
);
1498 if (lck
->want_upgrade
)
1499 lck
->want_upgrade
= FALSE
;
1501 lck
->want_write
= FALSE
;
1504 lck
->waiting
= FALSE
;
1508 lck_interlock_unlock(lck
, istate
);
1511 thread_wakeup((event_t
) lck
);
1513 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EX_TO_SH_CODE
) | DBG_FUNC_END
,
1514 (int)lck
, lck
->want_write
, lck
->want_upgrade
, lck
->read_count
, 0);
1520 * Routine: lck_rw_try_lock
1525 lck_rw_type_t lck_rw_type
)
1527 if (lck_rw_type
== LCK_RW_TYPE_SHARED
)
1528 return(lck_rw_try_lock_shared(lck
));
1529 else if (lck_rw_type
== LCK_RW_TYPE_EXCLUSIVE
)
1530 return(lck_rw_try_lock_exclusive(lck
));
1532 panic("lck_rw_try_lock(): Invalid rw lock type: %x\n", lck_rw_type
);
1537 * Routine: lck_rw_try_lock_exclusive
1539 * Tries to get a write lock.
1541 * Returns FALSE if the lock is not held on return.
1545 lck_rw_try_lock_exclusive(
1550 istate
= lck_interlock_lock(lck
);
1552 if (lck
->want_write
|| lck
->want_upgrade
|| lck
->read_count
) {
1556 lck_interlock_unlock(lck
, istate
);
1564 lck
->want_write
= TRUE
;
1566 lck_interlock_unlock(lck
, istate
);
1572 * Routine: lck_rw_try_lock_shared
1574 * Tries to get a read lock.
1576 * Returns FALSE if the lock is not held on return.
1580 lck_rw_try_lock_shared(
1585 istate
= lck_interlock_lock(lck
);
1587 if (lck
->want_write
|| lck
->want_upgrade
) {
1588 lck_interlock_unlock(lck
, istate
);
1594 lck_interlock_unlock(lck
, istate
);
1600 * Routine: lck_mtx_alloc_init
1609 if ((lck
= (lck_mtx_t
*)kalloc(sizeof(lck_mtx_t
))) != 0)
1610 lck_mtx_init(lck
, grp
, attr
);
1616 * Routine: lck_mtx_free
1623 lck_mtx_destroy(lck
, grp
);
1624 kfree(lck
, sizeof(lck_mtx_t
));
1628 * Routine: lck_mtx_ext_init
1636 lck
->lck_mtx
.lck_mtx_ilk
= 0;
1637 lck
->lck_mtx
.lck_mtx_locked
= 0;
1638 lck
->lck_mtx
.lck_mtx_waiters
= 0;
1639 lck
->lck_mtx
.lck_mtx_pri
= 0;
1640 lck
->lck_mtx_attr
= 0;
1642 if ((attr
->lck_attr_val
) & LCK_ATTR_DEBUG
) {
1643 lck
->lck_mtx_deb
.pc
= 0;
1644 lck
->lck_mtx_deb
.thread
= 0;
1645 lck
->lck_mtx_deb
.type
= MUTEX_TAG
;
1646 lck
->lck_mtx_attr
|= LCK_MTX_ATTR_DEBUG
;
1649 lck
->lck_mtx_grp
= grp
;
1653 * Routine: lck_mtx_init
1661 lck_mtx_ext_t
*lck_ext
;
1663 if ((attr
!= LCK_ATTR_NULL
) && ((attr
->lck_attr_val
) & LCK_ATTR_DEBUG
)) {
1664 if ((lck_ext
= (lck_mtx_ext_t
*)kalloc(sizeof(lck_mtx_ext_t
))) != 0) {
1665 lck_mtx_ext_init(lck_ext
, grp
, attr
);
1666 lck
->lck_mtx_tag
= LCK_MTX_TAG_INDIRECT
;
1667 lck
->lck_mtx_ptr
= lck_ext
;
1670 lck
->lck_mtx_ilk
= 0;
1671 lck
->lck_mtx_locked
= 0;
1672 lck
->lck_mtx_waiters
= 0;
1673 lck
->lck_mtx_pri
= 0;
1675 lck_grp_reference(grp
);
1676 lck_grp_lckcnt_incr(grp
, LCK_TYPE_MTX
);
1680 * Routine: lck_mtx_destroy
1687 boolean_t lck_is_indirect
;
1689 if (lck
->lck_mtx_tag
== LCK_MTX_TAG_DESTROYED
)
1691 lck_is_indirect
= (lck
->lck_mtx_tag
== LCK_MTX_TAG_INDIRECT
);
1692 lck
->lck_mtx_tag
= LCK_MTX_TAG_DESTROYED
;
1693 if (lck_is_indirect
)
1694 kfree(lck
->lck_mtx_ptr
, sizeof(lck_mtx_ext_t
));
1695 lck_grp_lckcnt_decr(grp
, LCK_TYPE_MTX
);
1696 lck_grp_deallocate(grp
);
1701 * Routine: lck_mtx_assert
1705 __unused lck_mtx_t
*lck
,
1706 __unused
unsigned int type
)
1712 void db_show_one_lock(lock_t
*);
1718 db_printf("Read_count = 0x%x, %swant_upgrade, %swant_write, ",
1720 lock
->want_upgrade
? "" : "!",
1721 lock
->want_write
? "" : "!");
1722 db_printf("%swaiting, %scan_sleep\n",
1723 lock
->waiting
? "" : "!", lock
->can_sleep
? "" : "!");
1724 db_printf("Interlock:\n");
1725 db_show_one_simple_lock((db_expr_t
)simple_lock_addr(lock
->interlock
),
1726 TRUE
, (db_expr_t
)0, (char *)0);
1729 #endif /* MACH_KDB */
1732 * The C portion of the mutex package. These routines are only invoked
1733 * if the optimized assembler routines can't do the work.
1737 * Routine: lock_alloc
1739 * Allocate a mutex for external users who cannot
1740 * hard-code the structure definition into their
1742 * For now just use kalloc, but a zone is probably
1751 if ((m
= (mutex_t
*)kalloc(sizeof(mutex_t
))) != 0)
1757 * Routine: mutex_free
1759 * Free a mutex allocated for external users.
1760 * For now just use kfree, but a zone is probably
1767 kfree(m
, sizeof(mutex_t
));
1771 * Routine: _mutex_assert
1779 thread_t thread
= current_thread();
1782 if (panicstr
!= NULL
)
1785 holder
= (thread_t
) mutex
->lck_mtx
.lck_mtx_locked
;
1789 if (thread
!= holder
)
1790 panic("mutex %x not owned\n", mutex
);
1794 if (thread
== holder
)
1795 panic("mutex %x owned\n", mutex
);
1803 * Routines to print out simple_locks and mutexes in a nicely-formatted
1807 char *simple_lock_labels
= "ENTRY ILK THREAD DURATION CALLER";
1808 char *mutex_labels
= "ENTRY LOCKED WAITERS THREAD CALLER";
1811 db_show_one_simple_lock (
1813 boolean_t have_addr
,
1817 simple_lock_t saddr
= (simple_lock_t
)addr
;
1819 if (saddr
== (simple_lock_t
)0 || !have_addr
) {
1820 db_error ("No simple_lock\n");
1823 else if (saddr
->lock_type
!= USLOCK_TAG
)
1824 db_error ("Not a simple_lock\n");
1825 #endif /* USLOCK_DEBUG */
1827 db_printf ("%s\n", simple_lock_labels
);
1828 db_print_simple_lock (saddr
);
1832 db_print_simple_lock (
1836 db_printf ("%08x %3d", addr
, *hw_lock_addr(addr
->interlock
));
1838 db_printf (" %08x", addr
->debug
.lock_thread
);
1839 db_printf (" %08x ", addr
->debug
.duration
[1]);
1840 db_printsym ((int)addr
->debug
.lock_pc
, DB_STGY_ANY
);
1841 #endif /* USLOCK_DEBUG */
1848 boolean_t have_addr
,
1852 mutex_t
* maddr
= (mutex_t
*)addr
;
1854 if (maddr
== (mutex_t
*)0 || !have_addr
)
1855 db_error ("No mutex\n");
1857 else if (maddr
->type
!= MUTEX_TAG
)
1858 db_error ("Not a mutex\n");
1859 #endif /* MACH_LDEBUG */
1861 db_printf ("%s\n", mutex_labels
);
1862 db_print_mutex (maddr
);
1869 db_printf ("%08x %6d %7d",
1870 addr
, *addr
, addr
->lck_mtx
.lck_mtx_waiters
);
1872 db_printf (" %08x ", addr
->thread
);
1873 db_printsym (addr
->pc
, DB_STGY_ANY
);
1874 #endif /* MACH_LDEBUG */
1878 #endif /* MACH_KDB */