Changeset 22580 in vbox
- Timestamp:
- Aug 30, 2009 8:38:49 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/freebsd/spinlock-r0drv-freebsd.c
r19565 r22580 33 33 *******************************************************************************/ 34 34 #include "the-freebsd-kernel.h" 35 #include "internal/iprt.h" 35 36 36 37 #include <iprt/spinlock.h> … … 39 40 #include <iprt/assert.h> 40 41 #include <iprt/asm.h> 42 #include <iprt/thread.h> 43 #include <iprt/mp.h> 41 44 42 45 #include "internal/magics.h" … … 53 56 /** Spinlock magic value (RTSPINLOCK_MAGIC). */ 54 57 uint32_t volatile u32Magic; 55 /** A FreeBSD spinlock. (mtx can be both sleep and spin lock.) */ 56 struct mtx Mtx; 58 /** The spinlock. */ 59 uint32_t volatile fLocked; 60 /** Reserved to satisfy compile assertion below. */ 61 uint32_t uReserved; 62 #ifdef RT_MORE_STRICT 63 /** The idAssertCpu variable before acquring the lock for asserting after 64 * releasing the spinlock. */ 65 RTCPUID volatile idAssertCpu; 66 /** The CPU that owns the lock. */ 67 RTCPUID volatile idCpuOwner; 68 #endif 57 69 } RTSPINLOCKINTERNAL, *PRTSPINLOCKINTERNAL; 58 70 … … 63 75 * Allocate. 64 76 */ 77 RT_ASSERT_PREEMPTIBLE(); 65 78 AssertCompile(sizeof(RTSPINLOCKINTERNAL) > sizeof(void *)); 66 79 PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)RTMemAllocZ(sizeof(*pSpinlockInt)); … … 72 85 */ 73 86 pSpinlockInt->u32Magic = RTSPINLOCK_MAGIC; 74 mtx_init(&pSpinlockInt->Mtx, "IPRT Spinlock", NULL, MTX_SPIN);87 pSpinlockInt->fLocked = 0; 75 88 *pSpinlock = pSpinlockInt; 76 89 return VINF_SUCCESS; … … 83 96 * Validate input. 84 97 */ 98 RT_ASSERT_INTS_ON(); 85 99 PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock; 86 100 if (!pSpinlockInt) … … 94 108 */ 95 109 ASMAtomicIncU32(&pSpinlockInt->u32Magic); 96 mtx_destroy(&pSpinlockInt->Mtx);97 110 RTMemFree(pSpinlockInt); 98 111 return VINF_SUCCESS; … … 105 118 AssertPtr(pSpinlockInt); 106 119 Assert(pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC); 120 RT_ASSERT_PREEMPT_CPUID_VAR(); 121 122 for (;;) 123 { 124 pTmp->uFlags = ASMGetFlags(); 125 ASMIntDisable(); 126 critical_enter(); 127 128 for (int c = 50; c > 0; c--) 129 if (ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 1, 0)) 130 { 131 RT_ASSERT_PREEMPT_CPUID_SPIN_ACQUIRED(pSpinlockInt); 132 return; 133 } 134 else 135 cpu_spinwait(); 136 137 /* Enable interrupts while we sleep. */ 138 ASMSetFlags(pTmp->uFlags); 139 critical_exit(); 140 DELAY(1); 141 } 142 } 143 144 145 RTDECL(void) RTSpinlockReleaseNoInts(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp) 146 { 147 PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock; 148 RT_ASSERT_PREEMPT_CPUID_SPIN_RELEASE_VARS(); 149 150 AssertPtr(pSpinlockInt); 151 Assert(pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC); 152 RT_ASSERT_PREEMPT_CPUID_SPIN_RELEASE(pSpinlockInt); 107 153 NOREF(pTmp); 108 154 109 mtx_lock_spin(&pSpinlockInt->Mtx); 110 } 111 112 113 RTDECL(void) RTSpinlockReleaseNoInts(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp) 114 { 115 PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock; 116 AssertPtr(pSpinlockInt); 117 Assert(pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC); 155 if (!ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 0, 1)) 156 AssertMsgFailed(("Spinlock %p was not locked!\n", pSpinlockInt)); 157 ASMSetFlags(pTmp->uFlags); 158 159 critical_exit(); 160 } 161 162 163 RTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp) 164 { 165 PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock; 166 RT_ASSERT_PREEMPT_CPUID_VAR(); 167 AssertPtr(pSpinlockInt); 168 Assert(pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC); 169 118 170 NOREF(pTmp); 119 171 120 mtx_unlock_spin(&pSpinlockInt->Mtx); 121 } 122 123 124 RTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp) 125 { 126 PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock; 127 AssertPtr(pSpinlockInt); 128 Assert(pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC); 172 for (;;) 173 { 174 critical_enter(); 175 for (int c = 50; c > 0; c--) 176 if (ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 1, 0)) 177 { 178 RT_ASSERT_PREEMPT_CPUID_SPIN_ACQUIRED(pSpinlockInt); 179 return; 180 } 181 else 182 cpu_spinwait(); 183 184 critical_exit(); 185 DELAY(1); 186 } 187 } 188 189 190 RTDECL(void) RTSpinlockRelease(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp) 191 { 192 PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock; 193 RT_ASSERT_PREEMPT_CPUID_SPIN_RELEASE_VARS(); 194 195 AssertPtr(pSpinlockInt); 196 Assert(pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC); 197 RT_ASSERT_PREEMPT_CPUID_SPIN_RELEASE(pSpinlockInt); 198 129 199 NOREF(pTmp); 130 200 131 mtx_lock_spin(&pSpinlockInt->Mtx); 132 } 133 134 135 RTDECL(void) RTSpinlockRelease(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp) 136 { 137 PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock; 138 AssertPtr(pSpinlockInt); 139 Assert(pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC); 140 NOREF(pTmp); 141 142 mtx_unlock_spin(&pSpinlockInt->Mtx); 143 } 144 201 if (!ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 0, 1)) 202 AssertMsgFailed(("Spinlock %p was not locked!\n", pSpinlockInt)); 203 204 critical_exit(); 205 } 206
Note:
See TracChangeset
for help on using the changeset viewer.