- Timestamp:
- Oct 11, 2010 9:55:12 AM (14 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuest/linux/Makefile
r33011 r33033 119 119 generic/RTLogWriteStdErr-stub-generic.o \ 120 120 generic/RTLogWriteStdOut-stub-generic.o \ 121 generic/RTSemEventWait-2-ex-generic.o \ 122 generic/RTSemEventWaitNoResume-2-ex-generic.o \ 121 123 generic/RTSemEventMultiWait-2-ex-generic.o \ 122 124 generic/RTSemEventMultiWaitNoResume-2-ex-generic.o \ -
trunk/src/VBox/Additions/common/VBoxGuest/linux/files_vboxguest
r33011 r33033 123 123 ${PATH_ROOT}/src/VBox/Runtime/generic/RTLogWriteStdErr-stub-generic.cpp=>generic/RTLogWriteStdErr-stub-generic.c \ 124 124 ${PATH_ROOT}/src/VBox/Runtime/generic/RTLogWriteStdOut-stub-generic.cpp=>generic/RTLogWriteStdOut-stub-generic.c \ 125 ${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventWait-2-ex-generic.cpp=>generic/RTSemEventWait-2-ex-generic.c \ 126 ${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventWaitNoResume-2-ex-generic.cpp=>generic/RTSemEventWaitNoResume-2-ex-generic.c \ 125 127 ${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventMultiWait-2-ex-generic.cpp=>generic/RTSemEventMultiWait-2-ex-generic.c \ 126 128 ${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp=>generic/RTSemEventMultiWaitNoResume-2-ex-generic.c \ -
trunk/src/VBox/HostDrivers/Support/linux/Makefile
r33011 r33033 131 131 generic/RTLogWriteUser-generic.o \ 132 132 generic/RTMpGetArraySize-generic.o \ 133 generic/RTSemEventWait-2-ex-generic.o \ 134 generic/RTSemEventWaitNoResume-2-ex-generic.o \ 133 135 generic/RTSemEventMultiWait-2-ex-generic.o \ 134 136 generic/RTSemEventMultiWaitNoResume-2-ex-generic.o \ -
trunk/src/VBox/HostDrivers/Support/linux/files_vboxdrv
r33011 r33033 129 129 ${PATH_ROOT}/src/VBox/Runtime/generic/RTLogWriteUser-generic.cpp=>generic/RTLogWriteUser-generic.c \ 130 130 ${PATH_ROOT}/src/VBox/Runtime/generic/RTMpGetArraySize-generic.cpp=>generic/RTMpGetArraySize-generic.c \ 131 ${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventWait-2-ex-generic.cpp=>generic/RTSemEventWait-2-ex-generic.c \ 132 ${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventWaitNoResume-2-ex-generic.cpp=>generic/RTSemEventWaitNoResume-2-ex-generic.c \ 131 133 ${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventMultiWait-2-ex-generic.cpp=>generic/RTSemEventMultiWait-2-ex-generic.c \ 132 134 ${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp=>generic/RTSemEventMultiWaitNoResume-2-ex-generic.c \ -
trunk/src/VBox/HostDrivers/Support/testcase/tstSupSem.cpp
r33032 r33033 282 282 283 283 #endif /* !OS2 && !WINDOWS */ 284 285 if (RTTestErrorCount(hTest) == 0) 286 { 287 RTTestSub(hTest, "SRE Timeout Accuracy"); 288 RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS); 289 290 static unsigned const s_acMsIntervals[] = { 0, 1, 2, 3, 4, 8, 10, 16, 32 }; 291 for (unsigned i = 0; i < RT_ELEMENTS(s_acMsIntervals); i++) 292 { 293 uint64_t cMs = s_acMsIntervals[i]; 294 uint64_t cNsMinSys = UINT64_MAX; 295 uint64_t cNsMin = UINT64_MAX; 296 uint64_t cNsTotalSys= 0; 297 uint64_t cNsTotal = 0; 298 for (unsigned j = 0; j < 10; j++) 299 { 300 uint64_t u64StartSys = RTTimeSystemNanoTS(); 301 uint64_t u64Start = RTTimeNanoTS(); 302 int rcX = SUPSemEventWaitNoResume(pSession, hEvent, cMs); 303 if (rc == VERR_TIMEOUT) 304 RTTestFailed(hTest, "%Rrc j=%u cMs=%u", rcX, j, cMs); 305 uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys; 306 uint64_t cNsElapsed = RTTimeNanoTS() - u64Start; 307 if (cNsElapsedSys < cNsMinSys) 308 cNsMinSys = cNsElapsedSys; 309 if (cNsElapsed < cNsMin) 310 cNsMin = cNsElapsed; 311 cNsTotalSys += cNsElapsedSys; 312 cNsTotal += cNsElapsed; 313 } 314 RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS, "%u ms min (clock=sys)", cMs); 315 RTTestValueF(hTest, cNsTotalSys / 10, RTTESTUNIT_NS, "%u ms avg - (clock=sys)", cMs); 316 RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS, "%u ms min (clock=gip)", cMs); 317 RTTestValueF(hTest, cNsTotal / 10, RTTESTUNIT_NS, "%u ms avg - (clock=gip)", cMs); 318 } 319 320 RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED); 321 } 284 322 285 323 if (RTTestErrorCount(hTest) == 0) -
trunk/src/VBox/Runtime/Makefile.kmk
r33011 r33033 1430 1430 generic/RTAssertShouldPanic-generic.cpp \ 1431 1431 generic/RTLogWriteStdOut-stub-generic.cpp \ 1432 generic/RTSemEventWait-2-ex-generic.cpp \ 1433 generic/RTSemEventWaitNoResume-2-ex-generic.cpp \ 1432 1434 generic/RTSemEventMultiWait-2-ex-generic.cpp \ 1433 1435 generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp \ -
trunk/src/VBox/Runtime/r0drv/linux/semevent-r0drv-linux.c
r29661 r33033 5 5 6 6 /* 7 * Copyright (C) 2006-20 07Oracle Corporation7 * Copyright (C) 2006-2010 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 32 32 #include "internal/iprt.h" 33 33 #include <iprt/semaphore.h> 34 #include <iprt/alloc.h> 34 35 #include <iprt/asm.h> 35 36 #include <iprt/assert.h> 36 #include <iprt/asm.h>37 37 #include <iprt/err.h> 38 38 #include <iprt/lockvalidator.h> 39 #include <iprt/mem.h> 40 41 #include "waitqueue-r0drv-linux.h" 39 42 #include "internal/magics.h" 40 43 … … 52 55 /** The object status - !0 when signaled and 0 when reset. */ 53 56 uint32_t volatile fState; 57 /** Reference counter. */ 58 uint32_t volatile cRefs; 54 59 /** The wait queue. */ 55 60 wait_queue_head_t Head; … … 75 80 pThis->u32Magic = RTSEMEVENT_MAGIC; 76 81 pThis->fState = 0; 82 pThis->cRefs = 1; 77 83 init_waitqueue_head(&pThis->Head); 78 84 … … 81 87 } 82 88 RT_EXPORT_SYMBOL(RTSemEventCreate); 89 90 91 /** 92 * Retains a reference to the event semaphore. 93 * 94 * @param pThis The event semaphore. 95 */ 96 DECLINLINE(void) rtR0SemEventLnxRetain(PRTSEMEVENTINTERNAL pThis) 97 { 98 uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs); 99 Assert(cRefs < 100000); NOREF(cRefs); 100 } 101 102 103 /** 104 * Releases a reference to the event semaphore. 105 * 106 * @param pThis The event semaphore. 107 */ 108 DECLINLINE(void) rtR0SemEventLnxRelease(PRTSEMEVENTINTERNAL pThis) 109 { 110 if (RT_UNLIKELY(ASMAtomicDecU32(&pThis->cRefs) == 0)) 111 RTMemFree(pThis); 112 } 83 113 84 114 … … 92 122 return VINF_SUCCESS; 93 123 AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE); 124 Assert(pThis->cRefs > 0); 94 125 95 126 /* … … 100 131 Assert(!waitqueue_active(&pThis->Head)); 101 132 wake_up_all(&pThis->Head); 102 RTMemFree(pThis);133 rtR0SemEventLnxRelease(pThis); 103 134 return VINF_SUCCESS; 104 135 } … … 114 145 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 115 146 AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE); 147 rtR0SemEventLnxRetain(pThis); 116 148 117 149 /* … … 121 153 wake_up(&pThis->Head); 122 154 155 rtR0SemEventLnxRelease(pThis); 123 156 return VINF_SUCCESS; 124 157 } … … 127 160 128 161 /** 129 * Worker for RTSemEvent and RTSemEventNoResume.162 * Worker for RTSemEventWaitEx and RTSemEventWaitExDebug. 130 163 * 131 164 * @returns VBox status code. 132 165 * @param pThis The event semaphore. 133 * @param cMillies The number of milliseconds to wait. 134 * @param fInterruptible Whether it's an interruptible wait or not. 135 */ 136 static int rtSemEventWait(PRTSEMEVENTINTERNAL pThis, RTMSINTERVAL cMillies, bool fInterruptible) 137 { 138 /* 139 * Ok wait for it. 140 */ 141 DEFINE_WAIT(Wait); 142 int rc = VINF_SUCCESS; 143 long lTimeout = cMillies == RT_INDEFINITE_WAIT ? MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(cMillies); 144 IPRT_DEBUG_SEMS_STATE(pThis, 'e'); 145 for (;;) 166 * @param fFlags See RTSemEventWaitEx. 167 * @param uTimeout See RTSemEventWaitEx. 168 * @param pSrcPos The source code position of the wait. 169 */ 170 static int rtR0SemEventLnxWait(PRTSEMEVENTINTERNAL pThis, uint32_t fFlags, uint64_t uTimeout, 171 PCRTLOCKVALSRCPOS pSrcPos) 172 { 173 int rc; 174 175 /* 176 * Validate the input. 177 */ 178 AssertPtrReturn(pThis, VERR_INVALID_PARAMETER); 179 AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER); 180 rtR0SemEventLnxRetain(pThis); 181 182 /* 183 * Try grab the event without setting up the wait. 184 */ 185 if ( 1 /** @todo check if there are someone waiting already - waitqueue_active, but then what do we do below? */ 186 && ASMAtomicCmpXchgU32(&pThis->fState, 0, 1)) 187 rc = VINF_SUCCESS; 188 else 146 189 { 147 /* make everything thru schedule_timeout() atomic scheduling wise. */ 148 prepare_to_wait(&pThis->Head, &Wait, fInterruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); 149 150 /* check the condition. */ 151 if (ASMAtomicCmpXchgU32(&pThis->fState, 0, 1)) 152 break; 153 154 /* check for pending signals. */ 155 if (fInterruptible && signal_pending(current)) 190 /* 191 * We have to wait. 192 */ 193 RTR0SEMLNXWAIT Wait; 194 rc = rtR0SemLnxWaitInit(&Wait, fFlags, uTimeout, &pThis->Head); 195 if (RT_SUCCESS(rc)) 156 196 { 157 rc = VERR_INTERRUPTED; 158 break; 159 } 160 161 /* wait */ 162 lTimeout = schedule_timeout(lTimeout); 163 164 after_wait(&Wait); 165 166 /* Check if someone destroyed the semaphore while we were waiting. */ 167 if (pThis->u32Magic != RTSEMEVENT_MAGIC) 168 { 169 rc = VERR_SEM_DESTROYED; 170 break; 171 } 172 173 /* check for timeout. */ 174 if (!lTimeout) 175 { 176 rc = VERR_TIMEOUT; 177 break; 197 IPRT_DEBUG_SEMS_STATE(pThis, 'E'); 198 for (;;) 199 { 200 /* The destruction test. */ 201 if (RT_UNLIKELY(pThis->u32Magic != RTSEMEVENT_MAGIC)) 202 rc = VERR_SEM_DESTROYED; 203 else 204 { 205 rtR0SemLnxWaitPrepare(&Wait); 206 207 /* Check the exit conditions. */ 208 if (RT_UNLIKELY(pThis->u32Magic != RTSEMEVENT_MAGIC)) 209 rc = VERR_SEM_DESTROYED; 210 else if (ASMAtomicCmpXchgU32(&pThis->fState, 0, 1)) 211 rc = VINF_SUCCESS; 212 else if (rtR0SemLnxWaitHasTimedOut(&Wait)) 213 rc = VERR_TIMEOUT; 214 else if (rtR0SemLnxWaitWasInterrupted(&Wait)) 215 rc = VERR_INTERRUPTED; 216 else 217 { 218 /* Do the wait and then recheck the conditions. */ 219 rtR0SemLnxWaitDoIt(&Wait); 220 continue; 221 } 222 } 223 break; 224 } 225 226 rtR0SemLnxWaitDelete(&Wait); 227 IPRT_DEBUG_SEMS_STATE_RC(pThis, 'E', rc); 178 228 } 179 229 } 180 230 181 finish_wait(&pThis->Head, &Wait); 182 IPRT_DEBUG_SEMS_STATE_RC(pThis, 'e', rc); 231 rtR0SemEventLnxRelease(pThis); 183 232 return rc; 184 233 } 185 234 186 235 187 RTDECL(int) RTSemEventWait(RTSEMEVENT hEventSem, RTMSINTERVAL cMillies) 188 { 189 PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)hEventSem; 190 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 191 AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE); 192 193 if (ASMAtomicCmpXchgU32(&pThis->fState, 0, 1)) 194 return VINF_SUCCESS; 195 return rtSemEventWait(pThis, cMillies, false /* fInterruptible */); 196 } 197 RT_EXPORT_SYMBOL(RTSemEventWait); 198 199 200 RTDECL(int) RTSemEventWaitNoResume(RTSEMEVENT hEventSem, RTMSINTERVAL cMillies) 201 { 202 PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)hEventSem; 203 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 204 AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE); 205 206 if (ASMAtomicCmpXchgU32(&pThis->fState, 0, 1)) 207 return VINF_SUCCESS; 208 return rtSemEventWait(pThis, cMillies, true /* fInterruptible */); 209 } 210 RT_EXPORT_SYMBOL(RTSemEventWaitNoResume); 211 236 #undef RTSemEventWaitEx 237 RTDECL(int) RTSemEventWaitEx(RTSEMEVENT hEventSem, uint32_t fFlags, uint64_t uTimeout) 238 { 239 #ifndef RTSEMEVENT_STRICT 240 return rtR0SemEventLnxWait(hEventSem, fFlags, uTimeout, NULL); 241 #else 242 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API(); 243 return rtR0SemEventLnxWait(hEventSem, fFlags, uTimeout, &SrcPos); 244 #endif 245 } 246 RT_EXPORT_SYMBOL(RTSemEventWaitEx); 247 248 249 RTDECL(int) RTSemEventWaitExDebug(RTSEMEVENT hEventSem, uint32_t fFlags, uint64_t uTimeout, 250 RTHCUINTPTR uId, RT_SRC_POS_DECL) 251 { 252 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API(); 253 return rtR0SemEventLnxWait(hEventSem, fFlags, uTimeout, &SrcPos); 254 } 255 RT_EXPORT_SYMBOL(RTSemEventWaitExDebug); 256 -
trunk/src/VBox/Runtime/r0drv/linux/semeventmulti-r0drv-linux.c
r33011 r33033 226 226 * @returns VBox status code. 227 227 * @param pThis The event semaphore. 228 * @param fFlags See RTSemEventMultiWaitEx. 229 * @param uTimeout See RTSemEventMultiWaitEx. 230 * @param pSrcPos The source code position of the wait. 228 231 */ 229 232 static int rtR0SemEventMultiLnxWait(PRTSEMEVENTMULTIINTERNAL pThis, uint32_t fFlags, uint64_t uTimeout,
Note:
See TracChangeset
for help on using the changeset viewer.