Changeset 25717 in vbox for trunk/src/VBox/Runtime/r0drv/os2
- Timestamp:
- Jan 11, 2010 1:24:09 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 56457
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/os2/semevent-r0drv-os2.cpp
r8245 r25717 65 65 66 66 67 RTDECL(int) RTSemEventCreate(PRTSEMEVENT pEventSem) 68 { 69 Assert(sizeof(RTSEMEVENTINTERNAL) > sizeof(void *)); 70 AssertPtrReturn(pEventSem, VERR_INVALID_POINTER); 71 72 PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)RTMemAlloc(sizeof(*pEventInt)); 73 if (pEventInt) 74 { 75 pEventInt->u32Magic = RTSEMEVENT_MAGIC; 76 pEventInt->cWaiters = 0; 77 pEventInt->cWaking = 0; 78 pEventInt->fSignaled = 0; 79 KernAllocSpinLock(&pEventInt->Spinlock); 80 *pEventSem = pEventInt; 67 RTDECL(int) RTSemEventCreate(PRTSEMEVENT phEventSem) 68 { 69 return RTSemEventCreateEx(phEventSem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, NULL); 70 } 71 72 73 RTDECL(int) RTSemEventCreateEx(PRTSEMEVENT phEventSem, uint32_t fFlags, RTLOCKVALCLASS hClass, const char *pszNameFmt, ...) 74 { 75 AssertReturn(!(fFlags & ~RTSEMEVENT_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER); 76 AssertCompile(sizeof(RTSEMEVENTINTERNAL) > sizeof(void *)); 77 AssertPtrReturn(phEventSem, VERR_INVALID_POINTER); 78 79 PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)RTMemAlloc(sizeof(*pThis)); 80 if (!pThis) 81 return VERR_NO_MEMORY; 82 83 pThis->u32Magic = RTSEMEVENT_MAGIC; 84 pThis->cWaiters = 0; 85 pThis->cWaking = 0; 86 pThis->fSignaled = 0; 87 KernAllocSpinLock(&pThis->Spinlock); 88 89 *phEventSem = pThis; 90 return VINF_SUCCESS; 91 } 92 93 94 RTDECL(int) RTSemEventDestroy(RTSEMEVENT hEventSem) 95 { 96 PRTSEMEVENTINTERNAL pThis = hEventSem; 97 if (pThis == NIL_RTSEMEVENT) 81 98 return VINF_SUCCESS; 82 } 83 return VERR_NO_MEMORY; 84 } 85 86 87 RTDECL(int) RTSemEventDestroy(RTSEMEVENT EventSem) 88 { 89 if (EventSem == NIL_RTSEMEVENT) /* don't bitch */ 90 return VERR_INVALID_HANDLE; 91 PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem; 92 AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE); 93 AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC, 94 ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic), 95 VERR_INVALID_HANDLE); 96 97 KernAcquireSpinLock(&pEventInt->Spinlock); 98 ASMAtomicIncU32(&pEventInt->u32Magic); /* make the handle invalid */ 99 if (pEventInt->cWaiters > 0) 99 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 100 AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE); 101 102 KernAcquireSpinLock(&pThis->Spinlock); 103 ASMAtomicIncU32(&pThis->u32Magic); /* make the handle invalid */ 104 if (pThis->cWaiters > 0) 100 105 { 101 106 /* abort waiting thread, last man cleans up. */ 102 ASMAtomicXchgU32(&p EventInt->cWaking, pEventInt->cWaking + pEventInt->cWaiters);107 ASMAtomicXchgU32(&pThis->cWaking, pThis->cWaking + pThis->cWaiters); 103 108 ULONG cThreads; 104 KernWakeup((ULONG)p EventInt, WAKEUP_DATA | WAKEUP_BOOST, &cThreads, (ULONG)VERR_SEM_DESTROYED);105 KernReleaseSpinLock(&p EventInt->Spinlock);106 } 107 else if (p EventInt->cWaking)109 KernWakeup((ULONG)pThis, WAKEUP_DATA | WAKEUP_BOOST, &cThreads, (ULONG)VERR_SEM_DESTROYED); 110 KernReleaseSpinLock(&pThis->Spinlock); 111 } 112 else if (pThis->cWaking) 108 113 /* the last waking thread is gonna do the cleanup */ 109 KernReleaseSpinLock(&p EventInt->Spinlock);114 KernReleaseSpinLock(&pThis->Spinlock); 110 115 else 111 116 { 112 KernReleaseSpinLock(&p EventInt->Spinlock);113 KernFreeSpinLock(&p EventInt->Spinlock);114 RTMemFree(p EventInt);117 KernReleaseSpinLock(&pThis->Spinlock); 118 KernFreeSpinLock(&pThis->Spinlock); 119 RTMemFree(pThis); 115 120 } 116 121 … … 119 124 120 125 121 RTDECL(int) RTSemEventSignal(RTSEMEVENT EventSem) 122 { 123 PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem; 124 AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE); 125 AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC, 126 ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic), 127 VERR_INVALID_HANDLE); 128 129 KernAcquireSpinLock(&pEventInt->Spinlock); 130 131 if (pEventInt->cWaiters > 0) 132 { 133 ASMAtomicDecU32(&pEventInt->cWaiters); 134 ASMAtomicIncU32(&pEventInt->cWaking); 126 RTDECL(int) RTSemEventSignal(RTSEMEVENT hEventSem) 127 { 128 PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)hEventSem; 129 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 130 AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE); 131 132 KernAcquireSpinLock(&pThis->Spinlock); 133 134 if (pThis->cWaiters > 0) 135 { 136 ASMAtomicDecU32(&pThis->cWaiters); 137 ASMAtomicIncU32(&pThis->cWaking); 135 138 ULONG cThreads; 136 KernWakeup((ULONG)p EventInt, WAKEUP_DATA | WAKEUP_ONE, &cThreads, VINF_SUCCESS);139 KernWakeup((ULONG)pThis, WAKEUP_DATA | WAKEUP_ONE, &cThreads, VINF_SUCCESS); 137 140 if (RT_UNLIKELY(!cThreads)) 138 141 { 139 142 /* shouldn't ever happen on OS/2 */ 140 ASMAtomicXchgU8(&p EventInt->fSignaled, true);141 ASMAtomicDecU32(&p EventInt->cWaking);142 ASMAtomicIncU32(&p EventInt->cWaiters);143 ASMAtomicXchgU8(&pThis->fSignaled, true); 144 ASMAtomicDecU32(&pThis->cWaking); 145 ASMAtomicIncU32(&pThis->cWaiters); 143 146 } 144 147 } 145 148 else 146 ASMAtomicXchgU8(&p EventInt->fSignaled, true);147 148 KernReleaseSpinLock(&p EventInt->Spinlock);149 ASMAtomicXchgU8(&pThis->fSignaled, true); 150 151 KernReleaseSpinLock(&pThis->Spinlock); 149 152 return VINF_SUCCESS; 150 153 } 151 154 152 155 153 static int rtSemEventWait(RTSEMEVENT EventSem, unsigned cMillies, bool fInterruptible) 154 { 155 PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem; 156 AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE); 157 AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC, 158 ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic), 159 VERR_INVALID_HANDLE); 160 161 KernAcquireSpinLock(&pEventInt->Spinlock); 156 static int rtSemEventWait(RTSEMEVENT hEventSem, unsigned cMillies, bool fInterruptible) 157 { 158 PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)hEventSem; 159 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 160 AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE); 161 162 KernAcquireSpinLock(&pThis->Spinlock); 162 163 163 164 int rc; 164 if (p EventInt->fSignaled)165 { 166 Assert(!p EventInt->cWaiters);167 ASMAtomicXchgU8(&p EventInt->fSignaled, false);165 if (pThis->fSignaled) 166 { 167 Assert(!pThis->cWaiters); 168 ASMAtomicXchgU8(&pThis->fSignaled, false); 168 169 rc = VINF_SUCCESS; 169 170 } 170 171 else 171 172 { 172 ASMAtomicIncU32(&p EventInt->cWaiters);173 ASMAtomicIncU32(&pThis->cWaiters); 173 174 174 175 ULONG ulData = (ULONG)VERR_INTERNAL_ERROR; 175 rc = KernBlock((ULONG)p EventInt,176 rc = KernBlock((ULONG)pThis, 176 177 cMillies == RT_INDEFINITE_WAIT ? SEM_INDEFINITE_WAIT : cMillies, 177 178 BLOCK_SPINLOCK | (!fInterruptible ? BLOCK_UNINTERRUPTABLE : 0), 178 &p EventInt->Spinlock,179 &pThis->Spinlock, 179 180 &ulData); 180 181 switch (rc) … … 183 184 rc = (int)ulData; 184 185 Assert(rc == VINF_SUCCESS || rc == VERR_SEM_DESTROYED); 185 Assert(p EventInt->cWaking > 0);186 if ( !ASMAtomicDecU32(&p EventInt->cWaking)187 && p EventInt->u32Magic != RTSEMEVENT_MAGIC)186 Assert(pThis->cWaking > 0); 187 if ( !ASMAtomicDecU32(&pThis->cWaking) 188 && pThis->u32Magic != RTSEMEVENT_MAGIC) 188 189 { 189 190 /* The event was destroyed (ulData == VINF_SUCCESS if it was after we awoke), as 190 191 the last thread do the cleanup. */ 191 KernReleaseSpinLock(&p EventInt->Spinlock);192 KernFreeSpinLock(&p EventInt->Spinlock);193 RTMemFree(p EventInt);192 KernReleaseSpinLock(&pThis->Spinlock); 193 KernFreeSpinLock(&pThis->Spinlock); 194 RTMemFree(pThis); 194 195 return rc; 195 196 } … … 198 199 case ERROR_TIMEOUT: 199 200 Assert(cMillies != RT_INDEFINITE_WAIT); 200 ASMAtomicDecU32(&p EventInt->cWaiters);201 ASMAtomicDecU32(&pThis->cWaiters); 201 202 rc = VERR_TIMEOUT; 202 203 break; … … 204 205 case ERROR_INTERRUPT: 205 206 Assert(fInterruptible); 206 ASMAtomicDecU32(&p EventInt->cWaiters);207 ASMAtomicDecU32(&pThis->cWaiters); 207 208 rc = VERR_INTERRUPTED; 208 209 break; … … 215 216 } 216 217 217 KernReleaseSpinLock(&p EventInt->Spinlock);218 KernReleaseSpinLock(&pThis->Spinlock); 218 219 return rc; 219 220 } 220 221 221 222 222 RTDECL(int) RTSemEventWait(RTSEMEVENT EventSem, unsigned cMillies)223 { 224 return rtSemEventWait( EventSem, cMillies, false /* not interruptible */);225 } 226 227 228 RTDECL(int) RTSemEventWaitNoResume(RTSEMEVENT EventSem, unsigned cMillies)229 { 230 return rtSemEventWait( EventSem, cMillies, true /* interruptible */);231 } 232 223 RTDECL(int) RTSemEventWait(RTSEMEVENT hEventSem, unsigned cMillies) 224 { 225 return rtSemEventWait(hEventSem, cMillies, false /* not interruptible */); 226 } 227 228 229 RTDECL(int) RTSemEventWaitNoResume(RTSEMEVENT hEventSem, unsigned cMillies) 230 { 231 return rtSemEventWait(hEventSem, cMillies, true /* interruptible */); 232 } 233
Note:
See TracChangeset
for help on using the changeset viewer.