+
+Llml_slow:
+ test $M_ILOCKED_MSK, %ecx /* is the interlock held */
+ jz Llml_contended /* no, must have been the mutex */
+
+ cmp $(MUTEX_DESTROYED), %ecx /* check to see if its marked destroyed */
+ je lck_mtx_destroyed
+ cmp $(MUTEX_IND), %ecx /* Is this an indirect mutex? */
+ jne Llml_loop /* no... must be interlocked */
+
+ LMTX_ENTER_EXTENDED
+
+ mov M_STATE(%rdx), %ecx
+ test $(M_SPIN_MSK), %ecx
+ jz Llml_loop1
+
+ LMTX_UPDATE_MISS /* M_SPIN_MSK was set, so M_ILOCKED_MSK must also be present */
+Llml_loop:
+ PAUSE
+ mov M_STATE(%rdx), %ecx
+Llml_loop1:
+ test $(M_ILOCKED_MSK | M_MLOCKED_MSK), %ecx
+ jz Llml_try
+ test $(M_MLOCKED_MSK), %ecx
+ jnz Llml_contended /* mutex owned by someone else, go contend for it */
+ jmp Llml_loop
+
+Llml_busy_disabled:
+ PREEMPTION_ENABLE
+ jmp Llml_loop
+
+
+Llml_contended:
+ cmp %rdx, %rdi /* is this an extended mutex */
+ je 0f
+ LMTX_UPDATE_MISS
+0:
+ LMTX_CALLEXT1(lck_mtx_lock_spinwait_x86)
+
+ test %rax, %rax
+ jz Llml_acquired /* acquired mutex, interlock held and preemption disabled */
+
+ cmp $1, %rax /* check for direct wait status */
+ je 2f
+ cmp %rdx, %rdi /* is this an extended mutex */
+ je 2f
+ LMTX_UPDATE_DIRECT_WAIT
+2:
+ mov M_STATE(%rdx), %ecx
+ test $(M_ILOCKED_MSK), %ecx
+ jnz 6f
+
+ mov %rcx, %rax /* eax contains snapshot for cmpxchgl */
+ or $(M_ILOCKED_MSK), %ecx /* try to take the interlock */
+
+ PREEMPTION_DISABLE
+ lock
+ cmpxchg %ecx, M_STATE(%rdx) /* atomic compare and exchange */
+ jne 5f
+
+ test $(M_MLOCKED_MSK), %ecx /* we've got the interlock and */
+ jnz 3f
+ or $(M_MLOCKED_MSK), %ecx /* the mutex is free... grab it directly */
+ mov %ecx, M_STATE(%rdx)
+
+ mov %gs:CPU_ACTIVE_THREAD, %rax
+ mov %rax, M_OWNER(%rdx) /* record owner of mutex */