2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
26 * Mach Operating System
27 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
28 * All Rights Reserved.
30 * Permission to use, copy, modify and distribute this software and its
31 * documentation is hereby granted, provided that both the copyright
32 * notice and this permission notice appear in all copies of the
33 * software, derivative works or modified versions, and any portions
34 * thereof, and that both notices appear in supporting documentation.
36 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
37 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
40 * Carnegie Mellon requests users of this software to return to
42 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
43 * School of Computer Science
44 * Carnegie Mellon University
45 * Pittsburgh PA 15213-3890
47 * any improvements or extensions that they make and grant Carnegie Mellon
48 * the rights to redistribute these changes.
52 * Author: Avadis Tevanian, Jr., Michael Wayne Young
55 * Locking primitives implementation
59 #include <mach_ldebug.h>
61 #include <kern/lock.h>
62 #include <kern/locks.h>
63 #include <kern/kalloc.h>
64 #include <kern/misc_protos.h>
65 #include <kern/thread.h>
66 #include <kern/processor.h>
67 #include <kern/cpu_data.h>
68 #include <kern/cpu_number.h>
69 #include <kern/sched_prim.h>
71 #include <kern/debug.h>
75 #include <ddb/db_command.h>
76 #include <ddb/db_output.h>
77 #include <ddb/db_sym.h>
78 #include <ddb/db_print.h>
81 #include <i386/machine_cpu.h>
83 #include <sys/kdebug.h>
85 #define LCK_RW_LCK_EXCLUSIVE_CODE 0x100
86 #define LCK_RW_LCK_EXCLUSIVE1_CODE 0x101
87 #define LCK_RW_LCK_SHARED_CODE 0x102
88 #define LCK_RW_LCK_SH_TO_EX_CODE 0x103
89 #define LCK_RW_LCK_SH_TO_EX1_CODE 0x104
90 #define LCK_RW_LCK_EX_TO_SH_CODE 0x105
92 #define LCK_MTX_LCK_SPIN 0x200
94 #define ANY_LOCK_DEBUG (USLOCK_DEBUG || LOCK_DEBUG || MUTEX_DEBUG)
96 unsigned int LcksOpts
=0;
97 unsigned int lock_wait_time
[2] = { (unsigned int)-1, 100 } ;
102 void db_print_simple_lock(
107 #endif /* MACH_KDB */
112 * Perform simple lock checks.
114 int uslock_check
= 1;
115 int max_lock_loops
= 100000000;
116 decl_simple_lock_data(extern , printf_lock
)
117 decl_simple_lock_data(extern , panic_lock
)
119 decl_simple_lock_data(extern , kdb_lock
)
120 #endif /* MACH_KDB */
121 #endif /* USLOCK_DEBUG */
125 * We often want to know the addresses of the callers
126 * of the various lock routines. However, this information
127 * is only used for debugging and statistics.
130 #define INVALID_PC ((void *) VM_MAX_KERNEL_ADDRESS)
131 #define INVALID_THREAD ((void *) VM_MAX_KERNEL_ADDRESS)
133 #define OBTAIN_PC(pc,l) ((pc) = (void *) GET_RETURN_PC(&(l)))
134 #define DECL_PC(pc) pc_t pc;
135 #else /* ANY_LOCK_DEBUG */
139 * Eliminate lint complaints about unused local pc variables.
141 #define OBTAIN_PC(pc,l) ++pc
143 #define OBTAIN_PC(pc,l)
145 #endif /* USLOCK_DEBUG */
149 * Portable lock package implementation of usimple_locks.
153 #define USLDBG(stmt) stmt
154 void usld_lock_init(usimple_lock_t
, unsigned short);
155 void usld_lock_pre(usimple_lock_t
, pc_t
);
156 void usld_lock_post(usimple_lock_t
, pc_t
);
157 void usld_unlock(usimple_lock_t
, pc_t
);
158 void usld_lock_try_pre(usimple_lock_t
, pc_t
);
159 void usld_lock_try_post(usimple_lock_t
, pc_t
);
160 int usld_lock_common_checks(usimple_lock_t
, char *);
161 #else /* USLOCK_DEBUG */
163 #endif /* USLOCK_DEBUG */
166 * Routine: lck_spin_alloc_init
175 if ((lck
= (lck_spin_t
*)kalloc(sizeof(lck_spin_t
))) != 0)
176 lck_spin_init(lck
, grp
, attr
);
182 * Routine: lck_spin_free
189 lck_spin_destroy(lck
, grp
);
190 kfree(lck
, sizeof(lck_spin_t
));
194 * Routine: lck_spin_init
200 __unused lck_attr_t
*attr
)
202 usimple_lock_init((usimple_lock_t
) lck
, 0);
203 lck_grp_reference(grp
);
204 lck_grp_lckcnt_incr(grp
, LCK_TYPE_SPIN
);
208 * Routine: lck_spin_destroy
215 if (lck
->lck_spin_data
[0] == LCK_SPIN_TAG_DESTROYED
)
217 lck
->lck_spin_data
[0] = LCK_SPIN_TAG_DESTROYED
;
218 lck_grp_lckcnt_decr(grp
, LCK_TYPE_SPIN
);
219 lck_grp_deallocate(grp
);
224 * Routine: lck_spin_lock
230 usimple_lock((usimple_lock_t
) lck
);
234 * Routine: lck_spin_unlock
240 usimple_unlock((usimple_lock_t
) lck
);
245 * Routine: lck_spin_try_lock
251 return(usimple_lock_try((usimple_lock_t
) lck
));
255 * Initialize a usimple_lock.
257 * No change in preemption state.
262 __unused
unsigned short tag
)
264 #ifndef MACHINE_SIMPLE_LOCK
265 USLDBG(usld_lock_init(l
, tag
));
266 hw_lock_init(&l
->interlock
);
268 simple_lock_init((simple_lock_t
)l
,tag
);
274 * Acquire a usimple_lock.
276 * Returns with preemption disabled. Note
277 * that the hw_lock routines are responsible for
278 * maintaining preemption state.
284 #ifndef MACHINE_SIMPLE_LOCK
288 USLDBG(usld_lock_pre(l
, pc
));
290 if(!hw_lock_to(&l
->interlock
, LockTimeOut
)) /* Try to get the lock with a timeout */
291 panic("simple lock deadlock detection - l=%08X, cpu=%d, ret=%08X", l
, cpu_number(), pc
);
293 USLDBG(usld_lock_post(l
, pc
));
295 simple_lock((simple_lock_t
)l
);
301 * Release a usimple_lock.
303 * Returns with preemption enabled. Note
304 * that the hw_lock routines are responsible for
305 * maintaining preemption state.
311 #ifndef MACHINE_SIMPLE_LOCK
315 USLDBG(usld_unlock(l
, pc
));
316 hw_lock_unlock(&l
->interlock
);
318 simple_unlock_rwmb((simple_lock_t
)l
);
324 * Conditionally acquire a usimple_lock.
326 * On success, returns with preemption disabled.
327 * On failure, returns with preemption in the same state
328 * as when first invoked. Note that the hw_lock routines
329 * are responsible for maintaining preemption state.
331 * XXX No stats are gathered on a miss; I preserved this
332 * behavior from the original assembly-language code, but
333 * doesn't it make sense to log misses? XXX
339 #ifndef MACHINE_SIMPLE_LOCK
341 unsigned int success
;
344 USLDBG(usld_lock_try_pre(l
, pc
));
345 if ((success
= hw_lock_try(&l
->interlock
))) {
346 USLDBG(usld_lock_try_post(l
, pc
));
350 return(simple_lock_try((simple_lock_t
)l
));
356 * States of a usimple_lock. The default when initializing
357 * a usimple_lock is setting it up for debug checking.
359 #define USLOCK_CHECKED 0x0001 /* lock is being checked */
360 #define USLOCK_TAKEN 0x0002 /* lock has been taken */
361 #define USLOCK_INIT 0xBAA0 /* lock has been initialized */
362 #define USLOCK_INITIALIZED (USLOCK_INIT|USLOCK_CHECKED)
363 #define USLOCK_CHECKING(l) (uslock_check && \
364 ((l)->debug.state & USLOCK_CHECKED))
367 * Trace activities of a particularly interesting lock.
369 void usl_trace(usimple_lock_t
, int, pc_t
, const char *);
373 * Initialize the debugging information contained
379 __unused
unsigned short tag
)
381 if (l
== USIMPLE_LOCK_NULL
)
382 panic("lock initialization: null lock pointer");
383 l
->lock_type
= USLOCK_TAG
;
384 l
->debug
.state
= uslock_check
? USLOCK_INITIALIZED
: 0;
385 l
->debug
.lock_cpu
= l
->debug
.unlock_cpu
= 0;
386 l
->debug
.lock_pc
= l
->debug
.unlock_pc
= INVALID_PC
;
387 l
->debug
.lock_thread
= l
->debug
.unlock_thread
= INVALID_THREAD
;
388 l
->debug
.duration
[0] = l
->debug
.duration
[1] = 0;
389 l
->debug
.unlock_cpu
= l
->debug
.unlock_cpu
= 0;
390 l
->debug
.unlock_pc
= l
->debug
.unlock_pc
= INVALID_PC
;
391 l
->debug
.unlock_thread
= l
->debug
.unlock_thread
= INVALID_THREAD
;
396 * These checks apply to all usimple_locks, not just
397 * those with USLOCK_CHECKED turned on.
400 usld_lock_common_checks(
404 if (l
== USIMPLE_LOCK_NULL
)
405 panic("%s: null lock pointer", caller
);
406 if (l
->lock_type
!= USLOCK_TAG
)
407 panic("%s: 0x%x is not a usimple lock", caller
, (integer_t
) l
);
408 if (!(l
->debug
.state
& USLOCK_INIT
))
409 panic("%s: 0x%x is not an initialized lock",
410 caller
, (integer_t
) l
);
411 return USLOCK_CHECKING(l
);
416 * Debug checks on a usimple_lock just before attempting
425 char caller
[] = "usimple_lock";
428 if (!usld_lock_common_checks(l
, caller
))
432 * Note that we have a weird case where we are getting a lock when we are]
433 * in the process of putting the system to sleep. We are running with no
434 * current threads, therefore we can't tell if we are trying to retake a lock
435 * we have or someone on the other processor has it. Therefore we just
436 * ignore this test if the locking thread is 0.
439 if ((l
->debug
.state
& USLOCK_TAKEN
) && l
->debug
.lock_thread
&&
440 l
->debug
.lock_thread
== (void *) current_thread()) {
441 printf("%s: lock 0x%x already locked (at 0x%x) by",
442 caller
, (integer_t
) l
, l
->debug
.lock_pc
);
443 printf(" current thread 0x%x (new attempt at pc 0x%x)\n",
444 l
->debug
.lock_thread
, pc
);
447 mp_disable_preemption();
448 usl_trace(l
, cpu_number(), pc
, caller
);
449 mp_enable_preemption();
454 * Debug checks on a usimple_lock just after acquiring it.
456 * Pre-emption has been disabled at this point,
457 * so we are safe in using cpu_number.
465 char caller
[] = "successful usimple_lock";
468 if (!usld_lock_common_checks(l
, caller
))
471 if (!((l
->debug
.state
& ~USLOCK_TAKEN
) == USLOCK_INITIALIZED
))
472 panic("%s: lock 0x%x became uninitialized",
473 caller
, (integer_t
) l
);
474 if ((l
->debug
.state
& USLOCK_TAKEN
))
475 panic("%s: lock 0x%x became TAKEN by someone else",
476 caller
, (integer_t
) l
);
478 mycpu
= cpu_number();
479 l
->debug
.lock_thread
= (void *)current_thread();
480 l
->debug
.state
|= USLOCK_TAKEN
;
481 l
->debug
.lock_pc
= pc
;
482 l
->debug
.lock_cpu
= mycpu
;
484 usl_trace(l
, mycpu
, pc
, caller
);
489 * Debug checks on a usimple_lock just before
490 * releasing it. Note that the caller has not
491 * yet released the hardware lock.
493 * Preemption is still disabled, so there's
494 * no problem using cpu_number.
502 char caller
[] = "usimple_unlock";
505 if (!usld_lock_common_checks(l
, caller
))
508 mycpu
= cpu_number();
510 if (!(l
->debug
.state
& USLOCK_TAKEN
))
511 panic("%s: lock 0x%x hasn't been taken",
512 caller
, (integer_t
) l
);
513 if (l
->debug
.lock_thread
!= (void *) current_thread())
514 panic("%s: unlocking lock 0x%x, owned by thread 0x%x",
515 caller
, (integer_t
) l
, l
->debug
.lock_thread
);
516 if (l
->debug
.lock_cpu
!= mycpu
) {
517 printf("%s: unlocking lock 0x%x on cpu 0x%x",
518 caller
, (integer_t
) l
, mycpu
);
519 printf(" (acquired on cpu 0x%x)\n", l
->debug
.lock_cpu
);
522 usl_trace(l
, mycpu
, pc
, caller
);
524 l
->debug
.unlock_thread
= l
->debug
.lock_thread
;
525 l
->debug
.lock_thread
= INVALID_PC
;
526 l
->debug
.state
&= ~USLOCK_TAKEN
;
527 l
->debug
.unlock_pc
= pc
;
528 l
->debug
.unlock_cpu
= mycpu
;
533 * Debug checks on a usimple_lock just before
534 * attempting to acquire it.
536 * Preemption isn't guaranteed to be disabled.
543 char caller
[] = "usimple_lock_try";
545 if (!usld_lock_common_checks(l
, caller
))
547 mp_disable_preemption();
548 usl_trace(l
, cpu_number(), pc
, caller
);
549 mp_enable_preemption();
554 * Debug checks on a usimple_lock just after
555 * successfully attempting to acquire it.
557 * Preemption has been disabled by the
558 * lock acquisition attempt, so it's safe
567 char caller
[] = "successful usimple_lock_try";
569 if (!usld_lock_common_checks(l
, caller
))
572 if (!((l
->debug
.state
& ~USLOCK_TAKEN
) == USLOCK_INITIALIZED
))
573 panic("%s: lock 0x%x became uninitialized",
574 caller
, (integer_t
) l
);
575 if ((l
->debug
.state
& USLOCK_TAKEN
))
576 panic("%s: lock 0x%x became TAKEN by someone else",
577 caller
, (integer_t
) l
);
579 mycpu
= cpu_number();
580 l
->debug
.lock_thread
= (void *) current_thread();
581 l
->debug
.state
|= USLOCK_TAKEN
;
582 l
->debug
.lock_pc
= pc
;
583 l
->debug
.lock_cpu
= mycpu
;
585 usl_trace(l
, mycpu
, pc
, caller
);
590 * For very special cases, set traced_lock to point to a
591 * specific lock of interest. The result is a series of
592 * XPRs showing lock operations on that lock. The lock_seq
593 * value is used to show the order of those operations.
595 usimple_lock_t traced_lock
;
596 unsigned int lock_seq
;
603 const char * op_name
)
605 if (traced_lock
== l
) {
607 "seq %d, cpu %d, %s @ %x\n",
608 (integer_t
) lock_seq
, (integer_t
) mycpu
,
609 (integer_t
) op_name
, (integer_t
) pc
, 0);
615 #endif /* USLOCK_DEBUG */
618 * Routine: lock_alloc
620 * Allocate a lock for external users who cannot
621 * hard-code the structure definition into their
623 * For now just use kalloc, but a zone is probably
634 if ((l
= (lock_t
*)kalloc(sizeof(lock_t
))) != 0)
635 lock_init(l
, can_sleep
, tag
, tag1
);
642 * Free a lock allocated for external users.
643 * For now just use kfree, but a zone is probably
650 kfree(l
, sizeof(lock_t
));
657 * Initialize a lock; required before use.
658 * Note that clients declare the "struct lock"
659 * variables and then initialize them, rather
660 * than getting a new one from this module.
666 __unused
unsigned short tag
,
667 __unused
unsigned short tag1
)
669 hw_lock_init(&l
->interlock
);
670 l
->want_write
= FALSE
;
671 l
->want_upgrade
= FALSE
;
673 l
->can_sleep
= can_sleep
;
679 * Sleep locks. These use the same data structure and algorithm
680 * as the spin locks, but the process sleeps while it is waiting
681 * for the lock. These work on uniprocessor systems.
684 #define DECREMENTER_TIMEOUT 1000000
690 lck_rw_lock_exclusive(l
);
697 (void) lck_rw_done(l
);
704 lck_rw_lock_shared(l
);
709 * Routine: lock_read_to_write
711 * Improves a read-only lock to one with
712 * write permission. If another reader has
713 * already requested an upgrade to a write lock,
714 * no lock is held upon return.
716 * Returns TRUE if the upgrade *failed*.
723 return lck_rw_lock_shared_to_exclusive(l
);
730 lck_rw_lock_exclusive_to_shared(l
);
736 * Routine: lck_rw_alloc_init
744 if ((lck
= (lck_rw_t
*)kalloc(sizeof(lck_rw_t
))) != 0)
745 lck_rw_init(lck
, grp
, attr
);
751 * Routine: lck_rw_free
757 lck_rw_destroy(lck
, grp
);
758 kfree(lck
, sizeof(lck_rw_t
));
762 * Routine: lck_rw_init
770 lck_attr_t
*lck_attr
= (attr
!= LCK_ATTR_NULL
) ?
771 attr
: &LockDefaultLckAttr
;
773 hw_lock_init(&lck
->interlock
);
774 lck
->want_write
= FALSE
;
775 lck
->want_upgrade
= FALSE
;
777 lck
->can_sleep
= TRUE
;
779 lck
->read_priority
= (lck_attr
->lck_attr_val
&
780 LCK_ATTR_RW_SHARED_PRIORITY
) != 0;
782 lck_grp_reference(grp
);
783 lck_grp_lckcnt_incr(grp
, LCK_TYPE_RW
);
787 * Routine: lck_rw_destroy
793 if (lck
->lck_rw_tag
== LCK_RW_TAG_DESTROYED
)
795 lck
->lck_rw_tag
= LCK_RW_TAG_DESTROYED
;
796 lck_grp_lckcnt_decr(grp
, LCK_TYPE_RW
);
797 lck_grp_deallocate(grp
);
802 * Sleep locks. These use the same data structure and algorithm
803 * as the spin locks, but the process sleeps while it is waiting
804 * for the lock. These work on uniprocessor systems.
807 #define DECREMENTER_TIMEOUT 1000000
811 * We need to disable interrupts while holding the mutex interlock
812 * to prevent an IPI intervening.
813 * Hence, local helper functions lck_interlock_lock()/lck_interlock_unlock().
816 lck_interlock_lock(lck_rw_t
*lck
)
820 istate
= ml_set_interrupts_enabled(FALSE
);
821 hw_lock_lock(&lck
->interlock
);
827 lck_interlock_unlock(lck_rw_t
*lck
, boolean_t istate
)
829 hw_lock_unlock(&lck
->interlock
);
830 ml_set_interrupts_enabled(istate
);
835 * This inline is used when busy-waiting for an rw lock.
836 * If interrupts were disabled when the lock primitive was called,
837 * we poll the IPI handler for pending tlb flushes.
838 * XXX This is a hack to avoid deadlocking on the pmap_system_lock.
841 lck_rw_lock_pause(boolean_t interrupts_enabled
)
843 if (!interrupts_enabled
)
844 handle_pending_TLB_flushes();
849 * Routine: lck_rw_lock_exclusive
852 lck_rw_lock_exclusive(
856 boolean_t lock_miss
= FALSE
;
860 #endif /* MACH_LDEBUG */
863 istate
= lck_interlock_lock(lck
);
866 decrementer
= DECREMENTER_TIMEOUT
;
867 #endif /* MACH_LDEBUG */
870 * Try to acquire the want_write bit.
872 while (lck
->want_write
) {
873 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EXCLUSIVE_CODE
) | DBG_FUNC_START
, (int)lck
, 0, 0, 0, 0);
879 i
= lock_wait_time
[lck
->can_sleep
? 1 : 0];
881 lck_interlock_unlock(lck
, istate
);
884 Debugger("timeout - want_write");
885 #endif /* MACH_LDEBUG */
886 while (--i
!= 0 && lck
->want_write
)
887 lck_rw_lock_pause(istate
);
888 istate
= lck_interlock_lock(lck
);
891 if (lck
->can_sleep
&& lck
->want_write
) {
893 res
= assert_wait((event_t
) lck
, THREAD_UNINT
);
894 if (res
== THREAD_WAITING
) {
895 lck_interlock_unlock(lck
, istate
);
896 res
= thread_block(THREAD_CONTINUE_NULL
);
897 istate
= lck_interlock_lock(lck
);
900 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EXCLUSIVE_CODE
) | DBG_FUNC_END
, (int)lck
, res
, 0, 0, 0);
902 lck
->want_write
= TRUE
;
904 /* Wait for readers (and upgrades) to finish */
907 decrementer
= DECREMENTER_TIMEOUT
;
908 #endif /* MACH_LDEBUG */
909 while ((lck
->read_count
!= 0) || lck
->want_upgrade
) {
914 i
= lock_wait_time
[lck
->can_sleep
? 1 : 0];
916 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EXCLUSIVE1_CODE
) | DBG_FUNC_START
,
917 (int)lck
, lck
->read_count
, lck
->want_upgrade
, i
, 0);
920 lck_interlock_unlock(lck
, istate
);
923 Debugger("timeout - wait for readers");
924 #endif /* MACH_LDEBUG */
925 while (--i
!= 0 && (lck
->read_count
!= 0 ||
927 lck_rw_lock_pause(istate
);
928 istate
= lck_interlock_lock(lck
);
931 if (lck
->can_sleep
&& (lck
->read_count
!= 0 || lck
->want_upgrade
)) {
933 res
= assert_wait((event_t
) lck
, THREAD_UNINT
);
934 if (res
== THREAD_WAITING
) {
935 lck_interlock_unlock(lck
, istate
);
936 res
= thread_block(THREAD_CONTINUE_NULL
);
937 istate
= lck_interlock_lock(lck
);
940 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EXCLUSIVE1_CODE
) | DBG_FUNC_END
,
941 (int)lck
, lck
->read_count
, lck
->want_upgrade
, res
, 0);
944 lck_interlock_unlock(lck
, istate
);
949 * Routine: lck_rw_done
955 boolean_t do_wakeup
= FALSE
;
956 lck_rw_type_t lck_rw_type
;
960 istate
= lck_interlock_lock(lck
);
962 if (lck
->read_count
!= 0) {
963 lck_rw_type
= LCK_RW_TYPE_SHARED
;
967 lck_rw_type
= LCK_RW_TYPE_EXCLUSIVE
;
968 if (lck
->want_upgrade
)
969 lck
->want_upgrade
= FALSE
;
971 lck
->want_write
= FALSE
;
975 * There is no reason to wakeup a waiting thread
976 * if the read-count is non-zero. Consider:
977 * we must be dropping a read lock
978 * threads are waiting only if one wants a write lock
979 * if there are still readers, they can't proceed
982 if (lck
->waiting
&& (lck
->read_count
== 0)) {
983 lck
->waiting
= FALSE
;
987 lck_interlock_unlock(lck
, istate
);
990 thread_wakeup((event_t
) lck
);
998 * Routine: lck_rw_unlock
1003 lck_rw_type_t lck_rw_type
)
1005 if (lck_rw_type
== LCK_RW_TYPE_SHARED
)
1006 lck_rw_unlock_shared(lck
);
1007 else if (lck_rw_type
== LCK_RW_TYPE_EXCLUSIVE
)
1008 lck_rw_unlock_exclusive(lck
);
1010 panic("lck_rw_unlock(): Invalid RW lock type: %d\n", lck_rw_type
);
1015 * Routine: lck_rw_unlock_shared
1018 lck_rw_unlock_shared(
1023 ret
= lck_rw_done(lck
);
1025 if (ret
!= LCK_RW_TYPE_SHARED
)
1026 panic("lck_rw_unlock(): lock held in mode: %d\n", ret
);
1031 * Routine: lck_rw_unlock_exclusive
1034 lck_rw_unlock_exclusive(
1039 ret
= lck_rw_done(lck
);
1041 if (ret
!= LCK_RW_TYPE_EXCLUSIVE
)
1042 panic("lck_rw_unlock_exclusive(): lock held in mode: %d\n", ret
);
1047 * Routine: lck_rw_lock
1052 lck_rw_type_t lck_rw_type
)
1054 if (lck_rw_type
== LCK_RW_TYPE_SHARED
)
1055 lck_rw_lock_shared(lck
);
1056 else if (lck_rw_type
== LCK_RW_TYPE_EXCLUSIVE
)
1057 lck_rw_lock_exclusive(lck
);
1059 panic("lck_rw_lock(): Invalid RW lock type: %x\n", lck_rw_type
);
1064 * Routine: lck_rw_lock_shared
1074 #endif /* MACH_LDEBUG */
1077 istate
= lck_interlock_lock(lck
);
1080 decrementer
= DECREMENTER_TIMEOUT
;
1081 #endif /* MACH_LDEBUG */
1082 while ((lck
->want_write
&& (lck
->read_priority
?
1083 lck
->read_count
== 0 : TRUE
)) ||
1084 lck
->want_upgrade
) {
1086 i
= lock_wait_time
[lck
->can_sleep
? 1 : 0];
1088 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SHARED_CODE
) | DBG_FUNC_START
,
1089 (int)lck
, lck
->want_write
, lck
->want_upgrade
, i
, 0);
1092 lck_interlock_unlock(lck
, istate
);
1095 Debugger("timeout - wait no writers");
1096 #endif /* MACH_LDEBUG */
1098 ((lck
->want_write
&& (lck
->read_priority
?
1099 lck
->read_count
== 0 : TRUE
)) ||
1101 lck_rw_lock_pause(istate
);
1102 istate
= lck_interlock_lock(lck
);
1105 if (lck
->can_sleep
&&
1106 ((lck
->want_write
&& (lck
->read_priority
?
1107 lck
->read_count
== 0 : TRUE
)) ||
1108 lck
->want_upgrade
)) {
1109 lck
->waiting
= TRUE
;
1110 res
= assert_wait((event_t
) lck
, THREAD_UNINT
);
1111 if (res
== THREAD_WAITING
) {
1112 lck_interlock_unlock(lck
, istate
);
1113 res
= thread_block(THREAD_CONTINUE_NULL
);
1114 istate
= lck_interlock_lock(lck
);
1117 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SHARED_CODE
) | DBG_FUNC_END
,
1118 (int)lck
, lck
->want_write
, lck
->want_upgrade
, res
, 0);
1123 lck_interlock_unlock(lck
, istate
);
1128 * Routine: lck_rw_lock_shared_to_exclusive
1130 * Improves a read-only lock to one with
1131 * write permission. If another reader has
1132 * already requested an upgrade to a write lock,
1133 * no lock is held upon return.
1135 * Returns TRUE if the upgrade *failed*.
1139 lck_rw_lock_shared_to_exclusive(
1143 boolean_t do_wakeup
= FALSE
;
1147 #endif /* MACH_LDEBUG */
1150 istate
= lck_interlock_lock(lck
);
1154 if (lck
->want_upgrade
) {
1155 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SH_TO_EX_CODE
) | DBG_FUNC_START
,
1156 (int)lck
, lck
->read_count
, lck
->want_upgrade
, 0, 0);
1159 * Someone else has requested upgrade.
1160 * Since we've released a read lock, wake
1163 if (lck
->waiting
&& (lck
->read_count
== 0)) {
1164 lck
->waiting
= FALSE
;
1168 lck_interlock_unlock(lck
, istate
);
1171 thread_wakeup((event_t
) lck
);
1173 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SH_TO_EX_CODE
) | DBG_FUNC_END
,
1174 (int)lck
, lck
->read_count
, lck
->want_upgrade
, 0, 0);
1179 lck
->want_upgrade
= TRUE
;
1182 decrementer
= DECREMENTER_TIMEOUT
;
1183 #endif /* MACH_LDEBUG */
1184 while (lck
->read_count
!= 0) {
1185 i
= lock_wait_time
[lck
->can_sleep
? 1 : 0];
1187 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_SH_TO_EX1_CODE
) | DBG_FUNC_START
,
1188 (int)lck
, lck
->read_count
, i
, 0, 0);
1191 lck_interlock_unlock(lck
, istate
);
1194 Debugger("timeout - read_count");
1195 #endif /* MACH_LDEBUG */
1196 while (--i
!= 0 && lck
->read_count
!= 0)
1197 lck_rw_lock_pause(istate
);
1198 istate
= lck_interlock_lock(lck
);
1201 if (lck
->can_sleep
&& lck
->read_count
!= 0) {
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_SH_TO_EX1_CODE
) | DBG_FUNC_END
,
1211 (int)lck
, lck
->read_count
, 0, 0, 0);
1214 lck_interlock_unlock(lck
, istate
);
1220 * Routine: lck_rw_lock_exclusive_to_shared
1223 lck_rw_lock_exclusive_to_shared(
1226 boolean_t do_wakeup
= FALSE
;
1229 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EX_TO_SH_CODE
) | DBG_FUNC_START
,
1230 (int)lck
, lck
->want_write
, lck
->want_upgrade
, 0, 0);
1232 istate
= lck_interlock_lock(lck
);
1235 if (lck
->want_upgrade
)
1236 lck
->want_upgrade
= FALSE
;
1238 lck
->want_write
= FALSE
;
1241 lck
->waiting
= FALSE
;
1245 lck_interlock_unlock(lck
, istate
);
1248 thread_wakeup((event_t
) lck
);
1250 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_RW_LCK_EX_TO_SH_CODE
) | DBG_FUNC_END
,
1251 (int)lck
, lck
->want_write
, lck
->want_upgrade
, lck
->read_count
, 0);
1257 * Routine: lck_rw_try_lock
1262 lck_rw_type_t lck_rw_type
)
1264 if (lck_rw_type
== LCK_RW_TYPE_SHARED
)
1265 return(lck_rw_try_lock_shared(lck
));
1266 else if (lck_rw_type
== LCK_RW_TYPE_EXCLUSIVE
)
1267 return(lck_rw_try_lock_exclusive(lck
));
1269 panic("lck_rw_try_lock(): Invalid rw lock type: %x\n", lck_rw_type
);
1274 * Routine: lck_rw_try_lock_exclusive
1276 * Tries to get a write lock.
1278 * Returns FALSE if the lock is not held on return.
1282 lck_rw_try_lock_exclusive(
1287 istate
= lck_interlock_lock(lck
);
1289 if (lck
->want_write
|| lck
->want_upgrade
|| lck
->read_count
) {
1293 lck_interlock_unlock(lck
, istate
);
1301 lck
->want_write
= TRUE
;
1303 lck_interlock_unlock(lck
, istate
);
1309 * Routine: lck_rw_try_lock_shared
1311 * Tries to get a read lock.
1313 * Returns FALSE if the lock is not held on return.
1317 lck_rw_try_lock_shared(
1322 istate
= lck_interlock_lock(lck
);
1324 if (lck
->want_write
|| lck
->want_upgrade
) {
1325 lck_interlock_unlock(lck
, istate
);
1331 lck_interlock_unlock(lck
, istate
);
1337 * Routine: lck_mtx_alloc_init
1346 if ((lck
= (lck_mtx_t
*)kalloc(sizeof(lck_mtx_t
))) != 0)
1347 lck_mtx_init(lck
, grp
, attr
);
1353 * Routine: lck_mtx_free
1360 lck_mtx_destroy(lck
, grp
);
1361 kfree(lck
, sizeof(lck_mtx_t
));
1365 * Routine: lck_mtx_ext_init
1373 lck
->lck_mtx
.lck_mtx_ilk
= 0;
1374 lck
->lck_mtx
.lck_mtx_locked
= 0;
1375 lck
->lck_mtx
.lck_mtx_waiters
= 0;
1376 lck
->lck_mtx
.lck_mtx_pri
= 0;
1377 lck
->lck_mtx_attr
= 0;
1379 if ((attr
->lck_attr_val
) & LCK_ATTR_DEBUG
) {
1380 lck
->lck_mtx_deb
.pc
= 0;
1381 lck
->lck_mtx_deb
.thread
= 0;
1382 lck
->lck_mtx_deb
.type
= MUTEX_TAG
;
1383 lck
->lck_mtx_attr
|= LCK_MTX_ATTR_DEBUG
;
1386 lck
->lck_mtx_grp
= grp
;
1390 * Routine: lck_mtx_init
1398 lck_mtx_ext_t
*lck_ext
;
1400 if ((attr
!= LCK_ATTR_NULL
) && ((attr
->lck_attr_val
) & LCK_ATTR_DEBUG
)) {
1401 if ((lck_ext
= (lck_mtx_ext_t
*)kalloc(sizeof(lck_mtx_ext_t
))) != 0) {
1402 lck_mtx_ext_init(lck_ext
, grp
, attr
);
1403 lck
->lck_mtx_tag
= LCK_MTX_TAG_INDIRECT
;
1404 lck
->lck_mtx_ptr
= lck_ext
;
1407 lck
->lck_mtx_ilk
= 0;
1408 lck
->lck_mtx_locked
= 0;
1409 lck
->lck_mtx_waiters
= 0;
1410 lck
->lck_mtx_pri
= 0;
1412 lck_grp_reference(grp
);
1413 lck_grp_lckcnt_incr(grp
, LCK_TYPE_MTX
);
1417 * Routine: lck_mtx_destroy
1424 boolean_t lck_is_indirect
;
1426 if (lck
->lck_mtx_tag
== LCK_MTX_TAG_DESTROYED
)
1428 lck_is_indirect
= (lck
->lck_mtx_tag
== LCK_MTX_TAG_INDIRECT
);
1429 lck
->lck_mtx_tag
= LCK_MTX_TAG_DESTROYED
;
1430 if (lck_is_indirect
)
1431 kfree(lck
->lck_mtx_ptr
, sizeof(lck_mtx_ext_t
));
1432 lck_grp_lckcnt_decr(grp
, LCK_TYPE_MTX
);
1433 lck_grp_deallocate(grp
);
1438 * Routine: lck_mtx_assert
1442 __unused lck_mtx_t
*lck
,
1443 __unused
unsigned int type
)
1448 * Routine: lck_mtx_lock_spin
1450 * Invoked trying to acquire a mutex when there is contention but
1451 * the holder is running on another processor. We spin for up to a maximum
1452 * time waiting for the lock to be released.
1454 * Called with the interlock unlocked.
1464 if (lck
->lck_mtx_tag
!= LCK_MTX_TAG_INDIRECT
)
1467 mutex
= &lck
->lck_mtx_ptr
->lck_mtx
;
1470 MACHDBG_CODE(DBG_MACH_LOCKS
, LCK_MTX_LCK_SPIN
) | DBG_FUNC_START
,
1471 (int)lck
, (int)mutex
->lck_mtx_locked
, 0, 0, 0);
1473 deadline
= mach_absolute_time() + MutexSpin
;
1476 * - mutex is locked, and
1477 * - owner is running on another processor, and
1478 * - owner is not is the idle delay, and
1479 * - we haven't spun for long enough.
1481 while ((holder
= (thread_t
) mutex
->lck_mtx_locked
) != NULL
&&
1482 (holder
->machine
.specFlags
& OnProc
) != 0 &&
1483 (holder
->options
& TH_OPT_DELAYIDLE
) == 0 &&
1484 mach_absolute_time() < deadline
)
1489 * Called from assembly code when a mutex interlock is held.
1490 * We spin here re-checking the interlock but panic if we timeout.
1491 * Note: here with interrupts disabled.
1494 lck_mtx_interlock_spin(
1500 if (lck
->lck_mtx_tag
!= LCK_MTX_TAG_INDIRECT
)
1503 mutex
= &lck
->lck_mtx_ptr
->lck_mtx
;
1505 deadline
= mach_absolute_time() + LockTimeOut
;
1506 while (mutex
->lck_mtx_ilk
!= 0) {
1508 if (mach_absolute_time() > deadline
)
1509 panic("interlock timeout for mutex %p", lck
);
1516 void db_show_one_lock(lock_t
*);
1522 db_printf("Read_count = 0x%x, %swant_upgrade, %swant_write, ",
1524 lock
->want_upgrade
? "" : "!",
1525 lock
->want_write
? "" : "!");
1526 db_printf("%swaiting, %scan_sleep\n",
1527 lock
->waiting
? "" : "!", lock
->can_sleep
? "" : "!");
1528 db_printf("Interlock:\n");
1529 db_show_one_simple_lock((db_expr_t
) ((vm_offset_t
)simple_lock_addr(lock
->interlock
)),
1530 TRUE
, (db_expr_t
)0, (char *)0);
1533 #endif /* MACH_KDB */
1536 * The C portion of the mutex package. These routines are only invoked
1537 * if the optimized assembler routines can't do the work.
1541 * Routine: lock_alloc
1543 * Allocate a mutex for external users who cannot
1544 * hard-code the structure definition into their
1546 * For now just use kalloc, but a zone is probably
1555 if ((m
= (mutex_t
*)kalloc(sizeof(mutex_t
))) != 0)
1561 * Routine: mutex_free
1563 * Free a mutex allocated for external users.
1564 * For now just use kfree, but a zone is probably
1571 kfree(m
, sizeof(mutex_t
));
1575 * Routine: _mutex_assert
1583 thread_t thread
= current_thread();
1586 if (panicstr
!= NULL
)
1589 holder
= (thread_t
) mutex
->lck_mtx
.lck_mtx_locked
;
1593 if (thread
!= holder
)
1594 panic("mutex %x not owned\n", mutex
);
1598 if (thread
== holder
)
1599 panic("mutex %x owned\n", mutex
);
1607 * Routines to print out simple_locks and mutexes in a nicely-formatted
1611 const char *simple_lock_labels
= "ENTRY ILK THREAD DURATION CALLER";
1612 const char *mutex_labels
= "ENTRY LOCKED WAITERS THREAD CALLER";
1615 db_show_one_simple_lock (
1617 boolean_t have_addr
,
1618 __unused db_expr_t count
,
1619 __unused
char * modif
)
1621 simple_lock_t saddr
= (simple_lock_t
) ((vm_offset_t
) addr
);
1623 if (saddr
== (simple_lock_t
)0 || !have_addr
) {
1624 db_error ("No simple_lock\n");
1627 else if (saddr
->lock_type
!= USLOCK_TAG
)
1628 db_error ("Not a simple_lock\n");
1629 #endif /* USLOCK_DEBUG */
1631 db_printf ("%s\n", simple_lock_labels
);
1632 db_print_simple_lock (saddr
);
1636 db_print_simple_lock (
1640 db_printf ("%08x %3d", addr
, *hw_lock_addr(addr
->interlock
));
1642 db_printf (" %08x", addr
->debug
.lock_thread
);
1643 db_printf (" %08x ", addr
->debug
.duration
[1]);
1644 db_printsym ((int)addr
->debug
.lock_pc
, DB_STGY_ANY
);
1645 #endif /* USLOCK_DEBUG */
1652 boolean_t have_addr
,
1653 __unused db_expr_t count
,
1654 __unused
char * modif
)
1656 mutex_t
* maddr
= (mutex_t
*)((vm_offset_t
) addr
);
1658 if (maddr
== (mutex_t
*)0 || !have_addr
)
1659 db_error ("No mutex\n");
1661 else if (maddr
->type
!= MUTEX_TAG
)
1662 db_error ("Not a mutex\n");
1663 #endif /* MACH_LDEBUG */
1665 db_printf ("%s\n", mutex_labels
);
1666 db_print_mutex (maddr
);
1673 db_printf ("%08x %6d %7d",
1674 addr
, *addr
, addr
->lck_mtx
.lck_mtx_waiters
);
1676 db_printf (" %08x ", addr
->thread
);
1677 db_printsym (addr
->pc
, DB_STGY_ANY
);
1678 #endif /* MACH_LDEBUG */
1682 #endif /* MACH_KDB */