-ENTRY(hw_lock_held)
- FRAME
- movl L_ARG0,%edx /* fetch lock pointer */
-
- movb $1,%cl
- testb %cl,0(%edx) /* check lock value */
- jne 1f /* non-zero means locked */
- xorl %eax,%eax /* tell caller: lock wasn't locked */
- EMARF
- ret
-
-1: movl $1,%eax /* tell caller: lock was locked */
- EMARF
- ret
-
-
-
-#if 0
-
-
-ENTRY(_usimple_lock_init)
- FRAME
- movl L_ARG0,%edx /* fetch lock pointer */
- xorl %eax,%eax
- movb %al,USL_INTERLOCK(%edx) /* unlock the HW lock */
- EMARF
- ret
-
-ENTRY(_simple_lock)
- FRAME
- movl L_ARG0,%edx /* fetch lock pointer */
-
- CHECK_SIMPLE_LOCK_TYPE()
-
- DISABLE_PREEMPTION(%eax)
-
-sl_get_hw:
- movb $1,%cl
- xchgb USL_INTERLOCK(%edx),%cl /* try to acquire the HW lock */
- testb %cl,%cl /* did we succeed? */
-
-#if MACH_LDEBUG
- je 5f
- CHECK_MYLOCK(S_THREAD)
- jmp sl_get_hw
-5:
-#else /* MACH_LDEBUG */
- jne sl_get_hw /* no, try again */
-#endif /* MACH_LDEBUG */
-
-#if MACH_LDEBUG
- movl L_PC,%ecx
- movl %ecx,S_PC
- movl $ CPD_ACTIVE_THREAD,%eax
- movl %gs:(%eax),%ecx
- movl %ecx,S_THREAD
- incl CX(EXT(simple_lock_count),%eax)
-#if 0
- METER_SIMPLE_LOCK_LOCK(%edx)
-#endif
-#if NCPUS == 1
- pushf
- pushl %edx
- cli
- call EXT(lock_stack_push)
- popl %edx
- popfl
-#endif /* NCPUS == 1 */
-#endif /* MACH_LDEBUG */
-
- EMARF
- ret
-
-ENTRY(_simple_lock_try)
- FRAME
- movl L_ARG0,%edx /* fetch lock pointer */
-
- CHECK_SIMPLE_LOCK_TYPE()
-
- DISABLE_PREEMPTION(%eax)
-
- movb $1,%cl
- xchgb USL_INTERLOCK(%edx),%cl /* try to acquire the HW lock */
- testb %cl,%cl /* did we succeed? */
- jne 1f /* no, return failure */
-
-#if MACH_LDEBUG
- movl L_PC,%ecx
- movl %ecx,S_PC
- movl $ CPD_ACTIVE_THREAD,%eax
- movl %gs:(%eax),%ecx
- movl %ecx,S_THREAD
- incl CX(EXT(simple_lock_count),%eax)
-#if 0
- METER_SIMPLE_LOCK_LOCK(%edx)
-#endif
-#if NCPUS == 1
- pushf
- pushl %edx
- cli
- call EXT(lock_stack_push)
- popl %edx
- popfl
-#endif /* NCPUS == 1 */
-#endif /* MACH_LDEBUG */
-
- movl $1,%eax /* return success */
-
- EMARF
- ret
-
-1:
- ENABLE_PREEMPTION(%eax)
-
- xorl %eax,%eax /* and return failure */
-
- EMARF
- ret
-
-ENTRY(_simple_unlock)
- FRAME
- movl L_ARG0,%edx /* fetch lock pointer */
-
- CHECK_SIMPLE_LOCK_TYPE()
- CHECK_THREAD(S_THREAD)
-
-#if MACH_LDEBUG
- xorl %eax,%eax
- movl %eax,S_THREAD /* disown thread */
- MP_DISABLE_PREEMPTION(%eax)
- CPU_NUMBER(%eax)
- decl CX(EXT(simple_lock_count),%eax)
- MP_ENABLE_PREEMPTION(%eax)
-#if 0
- METER_SIMPLE_LOCK_UNLOCK(%edx)
-#endif
-#if NCPUS == 1
- pushf
- pushl %edx
- cli
- call EXT(lock_stack_pop)
- popl %edx
- popfl
-#endif /* NCPUS == 1 */
-#endif /* MACH_LDEBUG */
-
- xorb %cl,%cl
- xchgb USL_INTERLOCK(%edx),%cl /* unlock the HW lock */
-
- ENABLE_PREEMPTION(%eax)
-
- EMARF
- ret
-
-#endif /* 0 */
-
-
-ENTRY(mutex_init)
- FRAME
- movl L_ARG0,%edx /* fetch lock pointer */
- xorl %eax,%eax
- movb %al,M_ILK /* clear interlock */
- movb %al,M_LOCKED /* clear locked flag */
- movw %ax,M_WAITERS /* init waiter count */
- movw %ax,M_PROMOTED_PRI
-
-#if MACH_LDEBUG
- movl $ MUTEX_TAG,M_TYPE /* set lock type */
- movl %eax,M_PC /* init caller pc */
- movl %eax,M_THREAD /* and owning thread */
-#endif
-#if ETAP_LOCK_TRACE
- movl L_ARG1,%ecx /* fetch event type */
- pushl %ecx /* push event type */
- pushl %edx /* push mutex address */
- call EXT(etap_mutex_init) /* init ETAP data */
- addl $8,%esp
-#endif /* ETAP_LOCK_TRACE */
-
- EMARF
- ret
-
-ENTRY2(mutex_lock,_mutex_lock)
- FRAME
-
-#if ETAP_LOCK_TRACE
- subl $12,%esp /* make room for locals */
- movl $0,SWT_HI /* set wait time to zero (HI) */
- movl $0,SWT_LO /* set wait time to zero (LO) */
- movl $0,MISSED /* clear local miss marker */
-#endif /* ETAP_LOCK_TRACE */
-
- movl L_ARG0,%edx /* fetch lock pointer */
-
- CHECK_MUTEX_TYPE()
- CHECK_NO_SIMPLELOCKS()
- CHECK_PREEMPTION_LEVEL()
-
-ml_retry:
- DISABLE_PREEMPTION(%eax)
-
-ml_get_hw:
- movb $1,%cl
- xchgb %cl,M_ILK
- testb %cl,%cl /* did we succeed? */
- jne ml_get_hw /* no, try again */
-
- movb $1,%cl
- xchgb %cl,M_LOCKED /* try to set locked flag */
- testb %cl,%cl /* is the mutex locked? */
- jne ml_fail /* yes, we lose */
-
- pushl %edx
- call EXT(mutex_lock_acquire)
- addl $4,%esp
- movl L_ARG0,%edx
-
-#if MACH_LDEBUG
- movl L_PC,%ecx
- movl %ecx,M_PC
- movl $ CPD_ACTIVE_THREAD,%eax
- movl %gs:(%eax),%ecx
- movl %ecx,M_THREAD
- testl %ecx,%ecx
- je 3f
- incl TH_MUTEX_COUNT(%ecx)
-3:
-#endif
-
- xorb %cl,%cl
- xchgb %cl,M_ILK
-
- ENABLE_PREEMPTION(%eax)
-
-#if ETAP_LOCK_TRACE
- movl L_PC,%eax /* fetch pc */
- pushl SWT_LO /* push wait time (low) */
- pushl SWT_HI /* push wait time (high) */
- pushl %eax /* push pc */
- pushl %edx /* push mutex address */
- call EXT(etap_mutex_hold) /* collect hold timestamp */
- addl $16+12,%esp /* clean up stack, adjusting for locals */
-#endif /* ETAP_LOCK_TRACE */
-
- EMARF
- ret
-
-ml_fail:
-#if ETAP_LOCK_TRACE
- cmp $0,MISSED /* did we already take a wait timestamp? */
- jne ml_block /* yup. carry-on */
- pushl %edx /* push mutex address */
- call EXT(etap_mutex_miss) /* get wait timestamp */
- movl %eax,SWT_HI /* set wait time (high word) */
- movl %edx,SWT_LO /* set wait time (low word) */
- popl %edx /* clean up stack */
- movl $1,MISSED /* mark wait timestamp as taken */
-#endif /* ETAP_LOCK_TRACE */
-
-ml_block:
- CHECK_MYLOCK(M_THREAD)
- xorl %eax,%eax
- pushl %eax /* no promotion here yet */
- pushl %edx /* push mutex address */
- call EXT(mutex_lock_wait) /* wait for the lock */
- addl $8,%esp
- movl L_ARG0,%edx /* refetch lock pointer */
- jmp ml_retry /* and try again */
-
-ENTRY2(mutex_try,_mutex_try)
- FRAME
-
-#if ETAP_LOCK_TRACE
- subl $8,%esp /* make room for locals */
- movl $0,SWT_HI /* set wait time to zero (HI) */
- movl $0,SWT_LO /* set wait time to zero (LO) */
-#endif /* ETAP_LOCK_TRACE */
-
- movl L_ARG0,%edx /* fetch lock pointer */
-
- CHECK_MUTEX_TYPE()
- CHECK_NO_SIMPLELOCKS()
-
- DISABLE_PREEMPTION(%eax)
-
-mt_get_hw:
- movb $1,%cl
- xchgb %cl,M_ILK
- testb %cl,%cl
- jne mt_get_hw
-
- movb $1,%cl
- xchgb %cl,M_LOCKED
- testb %cl,%cl
- jne mt_fail
-
- pushl %edx
- call EXT(mutex_lock_acquire)
- addl $4,%esp
- movl L_ARG0,%edx
-
-#if MACH_LDEBUG
- movl L_PC,%ecx
- movl %ecx,M_PC
- movl $ CPD_ACTIVE_THREAD,%ecx
- movl %gs:(%ecx),%ecx
- movl %ecx,M_THREAD
- testl %ecx,%ecx
- je 1f
- incl TH_MUTEX_COUNT(%ecx)
-1:
-#endif
-
- xorb %cl,%cl
- xchgb %cl,M_ILK
-
- ENABLE_PREEMPTION(%eax)
-
-#if ETAP_LOCK_TRACE
- movl L_PC,%eax /* fetch pc */
- pushl SWT_LO /* push wait time (low) */
- pushl SWT_HI /* push wait time (high) */
- pushl %eax /* push pc */
- pushl %edx /* push mutex address */
- call EXT(etap_mutex_hold) /* get start hold timestamp */
- addl $16,%esp /* clean up stack, adjusting for locals */
-#endif /* ETAP_LOCK_TRACE */
-
- movl $1,%eax
-
-#if MACH_LDEBUG || ETAP_LOCK_TRACE
-#if ETAP_LOCK_TRACE
- addl $8,%esp /* pop stack claimed on entry */
-#endif
-#endif
-
- EMARF
- ret
-
-mt_fail:
-#if MACH_LDEBUG
- movl L_PC,%ecx
- movl %ecx,M_PC
- movl $ CPD_ACTIVE_THREAD,%ecx
- movl %gs:(%ecx),%ecx
- movl %ecx,M_THREAD
- testl %ecx,%ecx
- je 1f
- incl TH_MUTEX_COUNT(%ecx)
-1:
-#endif
-
- xorb %cl,%cl
- xchgb %cl,M_ILK
-
- ENABLE_PREEMPTION(%eax)
-
-#if ETAP_LOCK_TRACE
- movl L_PC,%eax /* fetch pc */
- pushl SWT_LO /* push wait time (low) */
- pushl SWT_HI /* push wait time (high) */
- pushl %eax /* push pc */
- pushl %edx /* push mutex address */
- call EXT(etap_mutex_hold) /* get start hold timestamp */
- addl $16,%esp /* clean up stack, adjusting for locals */
-#endif /* ETAP_LOCK_TRACE */
-
- xorl %eax,%eax
-
-#if MACH_LDEBUG || ETAP_LOCK_TRACE
-#if ETAP_LOCK_TRACE
- addl $8,%esp /* pop stack claimed on entry */
-#endif
-#endif