- Timestamp:
- Oct 16, 2007 5:59:15 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/solaris/semeventmulti-r0drv-solaris.c
r4717 r5335 59 59 AssertPtrReturn(pEventMultiSem, VERR_INVALID_POINTER); 60 60 61 PRTSEMEVENTMULTIINTERNAL p EventMultiInt = (PRTSEMEVENTMULTIINTERNAL)RTMemAlloc(sizeof(*pEventMultiInt));62 if (p EventMultiInt)63 { 64 p EventMultiInt->u32Magic = RTSEMEVENTMULTI_MAGIC;65 p EventMultiInt->cWaiters = 0;66 p EventMultiInt->cWaking = 0;67 p EventMultiInt->fSignaled = 0;68 mutex_init(&p EventMultiInt->Mtx, "IPRT Multiple Release Event Semaphore", MUTEX_DRIVER, NULL);69 cv_init(&p EventMultiInt->Cnd, "IPRT CV", CV_DRIVER, NULL);70 *pEventMultiSem = p EventMultiInt;61 PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)RTMemAlloc(sizeof(*pThis)); 62 if (pThis) 63 { 64 pThis->u32Magic = RTSEMEVENTMULTI_MAGIC; 65 pThis->cWaiters = 0; 66 pThis->cWaking = 0; 67 pThis->fSignaled = 0; 68 mutex_init(&pThis->Mtx, "IPRT Multiple Release Event Semaphore", MUTEX_DRIVER, NULL); 69 cv_init(&pThis->Cnd, "IPRT CV", CV_DRIVER, NULL); 70 *pEventMultiSem = pThis; 71 71 return VINF_SUCCESS; 72 72 } … … 79 79 if (EventMultiSem == NIL_RTSEMEVENTMULTI) /* don't bitch */ 80 80 return VERR_INVALID_HANDLE; 81 PRTSEMEVENTMULTIINTERNAL p EventMultiInt= (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;82 AssertPtrReturn(p EventMultiInt, VERR_INVALID_HANDLE);83 AssertMsgReturn(p EventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC,84 ("p EventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic),85 VERR_INVALID_HANDLE); 86 87 mutex_enter(&p EventMultiInt->Mtx);88 ASMAtomicIncU32(&p EventMultiInt->u32Magic); /* make the handle invalid */89 if (p EventMultiInt->cWaiters > 0)81 PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem; 82 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 83 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, 84 ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic), 85 VERR_INVALID_HANDLE); 86 87 mutex_enter(&pThis->Mtx); 88 ASMAtomicIncU32(&pThis->u32Magic); /* make the handle invalid */ 89 if (pThis->cWaiters > 0) 90 90 { 91 91 /* abort waiting thread, last man cleans up. */ 92 ASMAtomicXchgU32(&p EventMultiInt->cWaking, pEventMultiInt->cWaking + pEventMultiInt->cWaiters);93 cv_ signal(&pEventMultiInt->Cnd);94 mutex_exit(&p EventMultiInt->Mtx);95 } 96 else if (p EventMultiInt->cWaking)92 ASMAtomicXchgU32(&pThis->cWaking, pThis->cWaking + pThis->cWaiters); 93 cv_broadcast(&pThis->Cnd); 94 mutex_exit(&pThis->Mtx); 95 } 96 else if (pThis->cWaking) 97 97 /* the last waking thread is gonna do the cleanup */ 98 mutex_exit(&p EventMultiInt->Mtx);98 mutex_exit(&pThis->Mtx); 99 99 else 100 100 { 101 mutex_exit(&p EventMultiInt->Mtx);102 cv_destroy(&p EventMultiInt->Cnd);103 mutex_destroy(&p EventMultiInt->Mtx);104 RTMemFree(p EventMultiInt);101 mutex_exit(&pThis->Mtx); 102 cv_destroy(&pThis->Cnd); 103 mutex_destroy(&pThis->Mtx); 104 RTMemFree(pThis); 105 105 } 106 106 … … 111 111 RTDECL(int) RTSemEventMultiSignal(RTSEMEVENTMULTI EventMultiSem) 112 112 { 113 PRTSEMEVENTMULTIINTERNAL p EventMultiInt= (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;114 AssertPtrReturn(p EventMultiInt, VERR_INVALID_HANDLE);115 AssertMsgReturn(p EventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC,116 ("p EventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic),117 VERR_INVALID_HANDLE); 118 119 mutex_enter(&p EventMultiInt->Mtx);120 121 ASMAtomicXchgU8(&p EventMultiInt->fSignaled, true);122 if (p EventMultiInt->cWaiters > 0)123 { 124 ASMAtomicXchgU32(&p EventMultiInt->cWaking, pEventMultiInt->cWaking + pEventMultiInt->cWaiters);125 ASMAtomicXchgU32(&p EventMultiInt->cWaiters, 0);126 cv_signal(&p EventMultiInt->Cnd);127 } 128 129 mutex_exit(&p EventMultiInt->Mtx);113 PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem; 114 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 115 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, 116 ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic), 117 VERR_INVALID_HANDLE); 118 119 mutex_enter(&pThis->Mtx); 120 121 ASMAtomicXchgU8(&pThis->fSignaled, true); 122 if (pThis->cWaiters > 0) 123 { 124 ASMAtomicXchgU32(&pThis->cWaking, pThis->cWaking + pThis->cWaiters); 125 ASMAtomicXchgU32(&pThis->cWaiters, 0); 126 cv_signal(&pThis->Cnd); 127 } 128 129 mutex_exit(&pThis->Mtx); 130 130 return VINF_SUCCESS; 131 131 } … … 134 134 RTDECL(int) RTSemEventMultiReset(RTSEMEVENTMULTI EventMultiSem) 135 135 { 136 PRTSEMEVENTMULTIINTERNAL p EventMultiInt= (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;137 AssertPtrReturn(p EventMultiInt, VERR_INVALID_HANDLE);138 AssertMsgReturn(p EventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC,139 ("p EventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic),140 VERR_INVALID_HANDLE); 141 142 mutex_enter(&p EventMultiInt->Mtx);143 ASMAtomicXchgU8(&p EventMultiInt->fSignaled, false);144 mutex_exit(&p EventMultiInt->Mtx);136 PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem; 137 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 138 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, 139 ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic), 140 VERR_INVALID_HANDLE); 141 142 mutex_enter(&pThis->Mtx); 143 ASMAtomicXchgU8(&pThis->fSignaled, false); 144 mutex_exit(&pThis->Mtx); 145 145 return VINF_SUCCESS; 146 146 } … … 150 150 { 151 151 int rc; 152 PRTSEMEVENTMULTIINTERNAL p EventMultiInt= (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;153 AssertPtrReturn(p EventMultiInt, VERR_INVALID_HANDLE);154 AssertMsgReturn(p EventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC,155 ("p EventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic),156 VERR_INVALID_HANDLE); 157 158 mutex_enter(&p EventMultiInt->Mtx);159 160 if (p EventMultiInt->fSignaled)152 PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem; 153 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 154 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, 155 ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic), 156 VERR_INVALID_HANDLE); 157 158 mutex_enter(&pThis->Mtx); 159 160 if (pThis->fSignaled) 161 161 rc = VINF_SUCCESS; 162 162 else … … 175 175 timeout += cTicks; 176 176 177 ASMAtomicIncU32(&pEventMultiInt->cWaiters); 178 179 /** @todo r=bird: Is this interruptible or non-interruptible? */ 180 rc = cv_timedwait_sig(&pEventMultiInt->Cnd, &pEventMultiInt->Mtx, timeout); 177 ASMAtomicIncU32(&pThis->cWaiters); 178 179 if (fInterruptible) 180 rc = cv_timedwait_sig(&pThis->Cnd, &pThis->Mtx, timeout); 181 else 182 rc = cv_timedwait(&pThis->Cnd, &pThis->Mtx, timeout); 181 183 if (rc > 0) 182 184 { 183 185 /* Retured due to call to cv_signal() or cv_broadcast() */ 184 if (pEventMultiInt->u32Magic != RTSEMEVENT_MAGIC) 186 if (RT_LIKELY(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC)) 187 rc = VINF_SUCCESS; 188 else 185 189 { 186 190 rc = VERR_SEM_DESTROYED; 187 if (!ASMAtomicDecU32(&p EventMultiInt->cWaking))191 if (!ASMAtomicDecU32(&pThis->cWaking)) 188 192 { 189 mutex_exit(&p EventMultiInt->Mtx);190 cv_destroy(&p EventMultiInt->Cnd);191 mutex_destroy(&p EventMultiInt->Mtx);192 RTMemFree(p EventMultiInt);193 mutex_exit(&pThis->Mtx); 194 cv_destroy(&pThis->Cnd); 195 mutex_destroy(&pThis->Mtx); 196 RTMemFree(pThis); 193 197 return rc; 194 198 } 195 199 } 196 197 ASMAtomicDecU32(&pEventMultiInt->cWaking); 198 rc = VINF_SUCCESS; 200 ASMAtomicDecU32(&pThis->cWaking); 199 201 } 200 202 else if (rc == -1) 201 203 { 202 204 /* Returned due to timeout being reached */ 203 if (p EventMultiInt->cWaiters > 0)204 ASMAtomicDecU32(&p EventMultiInt->cWaiters);205 if (pThis->cWaiters > 0) 206 ASMAtomicDecU32(&pThis->cWaiters); 205 207 rc = VERR_TIMEOUT; 206 208 } … … 208 210 { 209 211 /* Returned due to pending signal */ 210 if (p EventMultiInt->cWaiters > 0)211 ASMAtomicDecU32(&p EventMultiInt->cWaiters);212 if (pThis->cWaiters > 0) 213 ASMAtomicDecU32(&pThis->cWaiters); 212 214 rc = VERR_INTERRUPTED; 213 215 } 214 216 } 215 217 216 mutex_exit(&p EventMultiInt->Mtx);218 mutex_exit(&pThis->Mtx); 217 219 return rc; 218 220 }
Note:
See TracChangeset
for help on using the changeset viewer.