RTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock) { PRTSPINLOCKINTERNAL pThis = (PRTSPINLOCKINTERNAL)Spinlock; RT_ASSERT_PREEMPT_CPUID_VAR(); AssertPtr(pThis); Assert(pThis->u32Magic == RTSPINLOCK_MAGIC); if (pThis->fFlags & RTSPINLOCK_FLAGS_INTERRUPT_SAFE) { for (;;) { uint32_t fIntSaved = ASMIntDisableFlags(); critical_enter(); int c = 50; for (;;) { if (ASMAtomicCmpXchgU32(&pThis->fLocked, 1, 0)) { RT_ASSERT_PREEMPT_CPUID_SPIN_ACQUIRED(pThis); pThis->fIntSaved = fIntSaved; return; } if (--c <= 0) break; cpu_spinwait(); } /* Enable interrupts while we sleep. */ ASMSetFlags(fIntSaved); critical_exit(); DELAY(1); } } else { for (;;) { critical_enter(); int c = 50; for (;;) { if (ASMAtomicCmpXchgU32(&pThis->fLocked, 1, 0)) { RT_ASSERT_PREEMPT_CPUID_SPIN_ACQUIRED(pThis); return; } if (--c <= 0) break; cpu_spinwait(); } critical_exit(); DELAY(1); } } }
RTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock) { PRTSPINLOCKINTERNAL pThis = (PRTSPINLOCKINTERNAL)Spinlock; RT_ASSERT_PREEMPT_CPUID_VAR(); AssertMsg(pThis && pThis->u32Magic == RTSPINLOCK_MAGIC, ("pThis=%p u32Magic=%08x\n", pThis, pThis ? (int)pThis->u32Magic : 0)); if (pThis->fFlags & RTSPINLOCK_FLAGS_INTERRUPT_SAFE) { unsigned long fIntSaved; spin_lock_irqsave(&pThis->Spinlock, fIntSaved); pThis->fIntSaved = fIntSaved; } else spin_lock(&pThis->Spinlock); RT_ASSERT_PREEMPT_CPUID_SPIN_ACQUIRED(pThis); }
RTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock) { PRTSPINLOCKINTERNAL pThis = (PRTSPINLOCKINTERNAL)Spinlock; RT_ASSERT_PREEMPT_CPUID_VAR(); AssertPtr(pThis); Assert(pThis->u32Magic == RTSPINLOCK_MAGIC); if (pThis->fFlags & RTSPINLOCK_FLAGS_INTERRUPT_SAFE) { #if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) uint32_t fIntSaved = ASMIntDisableFlags(); #endif mutex_enter(&pThis->Mtx); /* * Solaris 10 doesn't preserve the interrupt flag, but since we're at PIL_MAX we should be * fine and not get interrupts while lock is held. Re-disable interrupts to not upset * assertions & assumptions callers might have. */ #if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) ASMIntDisable(); #endif #if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) Assert(!ASMIntAreEnabled()); #endif pThis->fIntSaved = fIntSaved; } else { #if defined(RT_STRICT) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)) bool fIntsOn = ASMIntAreEnabled(); #endif mutex_enter(&pThis->Mtx); #if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) AssertMsg(fIntsOn == ASMIntAreEnabled(), ("fIntsOn=%RTbool\n", fIntsOn)); #endif } RT_ASSERT_PREEMPT_CPUID_SPIN_ACQUIRED(pThis); }