Changeset 25717 in vbox for trunk/src/VBox/Runtime/r0drv/solaris
- 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/solaris/semevent-r0drv-solaris.c
r25183 r25717 70 70 71 71 72 RTDECL(int) RTSemEventCreate(PRTSEMEVENT pEventSem) 73 { 74 Assert(sizeof(RTSEMEVENTINTERNAL) > sizeof(void *)); 75 AssertPtrReturn(pEventSem, VERR_INVALID_POINTER); 72 RTDECL(int) RTSemEventCreate(PRTSEMEVENT phEventSem) 73 { 74 return RTSemEventCreateEx(phEventSem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, NULL); 75 } 76 77 78 RTDECL(int) RTSemEventCreateEx(PRTSEMEVENT phEventSem, uint32_t fFlags, RTLOCKVALCLASS hClass, const char *pszNameFmt, ...) 79 { 80 AssertCompile(sizeof(RTSEMEVENTINTERNAL) > sizeof(void *)); 81 AssertReturn(!(fFlags & ~RTSEMEVENT_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER); 82 AssertPtrReturn(phEventSem, VERR_INVALID_POINTER); 76 83 RT_ASSERT_PREEMPTIBLE(); 77 84 78 PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)RTMemAlloc(sizeof(*pEventInt)); 79 if (pEventInt) 80 { 81 pEventInt->u32Magic = RTSEMEVENT_MAGIC; 82 pEventInt->cWaiters = 0; 83 pEventInt->cWaking = 0; 84 pEventInt->fSignaled = 0; 85 mutex_init(&pEventInt->Mtx, "IPRT Event Semaphore", MUTEX_DRIVER, (void *)ipltospl(DISP_LEVEL)); 86 cv_init(&pEventInt->Cnd, "IPRT CV", CV_DRIVER, NULL); 87 *pEventSem = pEventInt; 85 PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)RTMemAlloc(sizeof(*pThis)); 86 if (!pThis) 87 return VERR_NO_MEMORY; 88 89 pThis->u32Magic = RTSEMEVENT_MAGIC; 90 pThis->cWaiters = 0; 91 pThis->cWaking = 0; 92 pThis->fSignaled = 0; 93 mutex_init(&pThis->Mtx, "IPRT Event Semaphore", MUTEX_DRIVER, (void *)ipltospl(DISP_LEVEL)); 94 cv_init(&pThis->Cnd, "IPRT CV", CV_DRIVER, NULL); 95 96 *phEventSem = pThis; 97 return VINF_SUCCESS; 98 } 99 100 101 RTDECL(int) RTSemEventDestroy(RTSEMEVENT hEventSem) 102 { 103 PRTSEMEVENTINTERNAL pThis = hEventSem; 104 if (pThis == NIL_RTSEMEVENT) 88 105 return VINF_SUCCESS; 89 } 90 return VERR_NO_MEMORY; 91 } 92 93 94 RTDECL(int) RTSemEventDestroy(RTSEMEVENT EventSem) 95 { 96 if (EventSem == NIL_RTSEMEVENT) 97 return VERR_INVALID_HANDLE; 98 PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem; 99 AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE); 100 AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC, 101 ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic), 102 VERR_INVALID_HANDLE); 106 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 107 AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE); 103 108 RT_ASSERT_INTS_ON(); 104 109 105 mutex_enter(&p EventInt->Mtx);106 ASMAtomicIncU32(&p EventInt->u32Magic); /* make the handle invalid */107 if (p EventInt->cWaiters > 0)110 mutex_enter(&pThis->Mtx); 111 ASMAtomicIncU32(&pThis->u32Magic); /* make the handle invalid */ 112 if (pThis->cWaiters > 0) 108 113 { 109 114 /* abort waiting thread, last man cleans up. */ 110 ASMAtomicXchgU32(&p EventInt->cWaking, pEventInt->cWaking + pEventInt->cWaiters);111 cv_broadcast(&p EventInt->Cnd);112 mutex_exit(&p EventInt->Mtx);113 } 114 else if (p EventInt->cWaking)115 ASMAtomicXchgU32(&pThis->cWaking, pThis->cWaking + pThis->cWaiters); 116 cv_broadcast(&pThis->Cnd); 117 mutex_exit(&pThis->Mtx); 118 } 119 else if (pThis->cWaking) 115 120 { 116 121 /* the last waking thread is gonna do the cleanup */ 117 mutex_exit(&p EventInt->Mtx);122 mutex_exit(&pThis->Mtx); 118 123 } 119 124 else 120 125 { 121 mutex_exit(&p EventInt->Mtx);122 cv_destroy(&p EventInt->Cnd);123 mutex_destroy(&p EventInt->Mtx);124 RTMemFree(p EventInt);126 mutex_exit(&pThis->Mtx); 127 cv_destroy(&pThis->Cnd); 128 mutex_destroy(&pThis->Mtx); 129 RTMemFree(pThis); 125 130 } 126 131 … … 129 134 130 135 131 RTDECL(int) RTSemEventSignal(RTSEMEVENT EventSem)132 { 133 PRTSEMEVENTINTERNAL p EventInt = (PRTSEMEVENTINTERNAL)EventSem;136 RTDECL(int) RTSemEventSignal(RTSEMEVENT hEventSem) 137 { 138 PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)hEventSem; 134 139 RT_ASSERT_PREEMPT_CPUID_VAR(); 135 AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE); 136 AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC, 137 ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic), 138 VERR_INVALID_HANDLE); 140 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 141 AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE); 139 142 RT_ASSERT_INTS_ON(); 140 143 … … 151 154 * or not and only call swtch if RTThreadPreemptDisable wasn't called. 152 155 */ 153 int fAcquired = mutex_tryenter(&p EventInt->Mtx);156 int fAcquired = mutex_tryenter(&pThis->Mtx); 154 157 if (!fAcquired) 155 158 { … … 161 164 RTThreadPreemptRestore(&PreemptState); 162 165 } 163 mutex_enter(&p EventInt->Mtx);164 } 165 166 if (p EventInt->cWaiters > 0)167 { 168 ASMAtomicDecU32(&p EventInt->cWaiters);169 ASMAtomicIncU32(&p EventInt->cWaking);170 cv_signal(&p EventInt->Cnd);166 mutex_enter(&pThis->Mtx); 167 } 168 169 if (pThis->cWaiters > 0) 170 { 171 ASMAtomicDecU32(&pThis->cWaiters); 172 ASMAtomicIncU32(&pThis->cWaking); 173 cv_signal(&pThis->Cnd); 171 174 } 172 175 else 173 ASMAtomicXchgU8(&p EventInt->fSignaled, true);174 175 mutex_exit(&p EventInt->Mtx);176 ASMAtomicXchgU8(&pThis->fSignaled, true); 177 178 mutex_exit(&pThis->Mtx); 176 179 177 180 RT_ASSERT_PREEMPT_CPUID(); … … 180 183 181 184 182 static int rtSemEventWait(RTSEMEVENT EventSem, unsigned cMillies, bool fInterruptible)185 static int rtSemEventWait(RTSEMEVENT hEventSem, unsigned cMillies, bool fInterruptible) 183 186 { 184 187 int rc; 185 PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem; 186 AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE); 187 AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC, 188 ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic), 189 VERR_INVALID_HANDLE); 188 PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)hEventSem; 189 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 190 AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE); 190 191 if (cMillies) 191 192 RT_ASSERT_PREEMPTIBLE(); 192 193 193 mutex_enter(&p EventInt->Mtx);194 195 if (p EventInt->fSignaled)196 { 197 Assert(!p EventInt->cWaiters);198 ASMAtomicXchgU8(&p EventInt->fSignaled, false);194 mutex_enter(&pThis->Mtx); 195 196 if (pThis->fSignaled) 197 { 198 Assert(!pThis->cWaiters); 199 ASMAtomicXchgU8(&pThis->fSignaled, false); 199 200 rc = VINF_SUCCESS; 200 201 } … … 203 204 else 204 205 { 205 ASMAtomicIncU32(&p EventInt->cWaiters);206 ASMAtomicIncU32(&pThis->cWaiters); 206 207 207 208 /* … … 214 215 cTimeout += cTicks; 215 216 if (fInterruptible) 216 rc = cv_timedwait_sig(&p EventInt->Cnd, &pEventInt->Mtx, cTimeout);217 rc = cv_timedwait_sig(&pThis->Cnd, &pThis->Mtx, cTimeout); 217 218 else 218 rc = cv_timedwait(&p EventInt->Cnd, &pEventInt->Mtx, cTimeout);219 rc = cv_timedwait(&pThis->Cnd, &pThis->Mtx, cTimeout); 219 220 } 220 221 else 221 222 { 222 223 if (fInterruptible) 223 rc = cv_wait_sig(&p EventInt->Cnd, &pEventInt->Mtx);224 rc = cv_wait_sig(&pThis->Cnd, &pThis->Mtx); 224 225 else 225 226 { 226 cv_wait(&p EventInt->Cnd, &pEventInt->Mtx);227 cv_wait(&pThis->Cnd, &pThis->Mtx); 227 228 rc = 1; 228 229 } … … 232 233 { 233 234 /* Retured due to call to cv_signal() or cv_broadcast() */ 234 if (p EventInt->u32Magic != RTSEMEVENT_MAGIC)235 if (pThis->u32Magic != RTSEMEVENT_MAGIC) 235 236 { 236 237 rc = VERR_SEM_DESTROYED; 237 if (!ASMAtomicDecU32(&p EventInt->cWaking))238 if (!ASMAtomicDecU32(&pThis->cWaking)) 238 239 { 239 mutex_exit(&p EventInt->Mtx);240 cv_destroy(&p EventInt->Cnd);241 mutex_destroy(&p EventInt->Mtx);242 RTMemFree(p EventInt);240 mutex_exit(&pThis->Mtx); 241 cv_destroy(&pThis->Cnd); 242 mutex_destroy(&pThis->Mtx); 243 RTMemFree(pThis); 243 244 return rc; 244 245 } 245 246 } 246 247 247 ASMAtomicDecU32(&p EventInt->cWaking);248 ASMAtomicDecU32(&pThis->cWaking); 248 249 rc = VINF_SUCCESS; 249 250 } … … 251 252 { 252 253 /* Returned due to timeout being reached */ 253 if (p EventInt->cWaiters > 0)254 ASMAtomicDecU32(&p EventInt->cWaiters);254 if (pThis->cWaiters > 0) 255 ASMAtomicDecU32(&pThis->cWaiters); 255 256 rc = VERR_TIMEOUT; 256 257 } … … 258 259 { 259 260 /* Returned due to pending signal */ 260 if (p EventInt->cWaiters > 0)261 ASMAtomicDecU32(&p EventInt->cWaiters);261 if (pThis->cWaiters > 0) 262 ASMAtomicDecU32(&pThis->cWaiters); 262 263 rc = VERR_INTERRUPTED; 263 264 } 264 265 } 265 266 266 mutex_exit(&p EventInt->Mtx);267 mutex_exit(&pThis->Mtx); 267 268 return rc; 268 269 } 269 270 270 271 271 RTDECL(int) RTSemEventWait(RTSEMEVENT EventSem, unsigned cMillies)272 { 273 return rtSemEventWait( EventSem, cMillies, false /* not interruptible */);274 } 275 276 277 RTDECL(int) RTSemEventWaitNoResume(RTSEMEVENT EventSem, unsigned cMillies)278 { 279 return rtSemEventWait( EventSem, cMillies, true /* interruptible */);280 } 272 RTDECL(int) RTSemEventWait(RTSEMEVENT hEventSem, unsigned cMillies) 273 { 274 return rtSemEventWait(hEventSem, cMillies, false /* not interruptible */); 275 } 276 277 278 RTDECL(int) RTSemEventWaitNoResume(RTSEMEVENT hEventSem, unsigned cMillies) 279 { 280 return rtSemEventWait(hEventSem, cMillies, true /* interruptible */); 281 }
Note:
See TracChangeset
for help on using the changeset viewer.