Changeset 33011 in vbox
- Timestamp:
- Oct 8, 2010 3:42:24 PM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 66526
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/semaphore.h
r32946 r33011 350 350 * @param hEventMultiSem The multiple release event semaphore. 351 351 * @param cMillies Number of milliseconds to wait. 352 * @todo Rename to RTSemEventMultiWaitIntr since it is mainly for 353 * ring-0 consumption. 352 354 */ 353 355 RTDECL(int) RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies); -
trunk/src/VBox/Additions/common/VBoxGuest/linux/Makefile
r32183 r33011 119 119 generic/RTLogWriteStdErr-stub-generic.o \ 120 120 generic/RTLogWriteStdOut-stub-generic.o \ 121 generic/RTSemEventMultiWait-2-ex-generic.o \ 122 generic/RTSemEventMultiWaitNoResume-2-ex-generic.o \ 121 123 VBox/log-vbox.o \ 122 124 VBox/logbackdoor.o -
trunk/src/VBox/Additions/common/VBoxGuest/linux/files_vboxguest
r32449 r33011 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/RTSemEventMultiWait-2-ex-generic.cpp=>generic/RTSemEventMultiWait-2-ex-generic.c \ 126 ${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp=>generic/RTSemEventMultiWaitNoResume-2-ex-generic.c \ 125 127 ${PATH_ROOT}/src/VBox/Runtime/r0drv/alloc-r0drv.cpp=>r0drv/alloc-r0drv.c \ 126 128 ${PATH_ROOT}/src/VBox/Runtime/r0drv/alloc-r0drv.h=>r0drv/alloc-r0drv.h \ … … 147 149 ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/thread-r0drv-linux.c=>r0drv/linux/thread-r0drv-linux.c \ 148 150 ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/time-r0drv-linux.c=>r0drv/linux/time-r0drv-linux.c \ 151 ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/waitqueue-r0drv-linux.h=>r0drv/linux/waitqueue-r0drv-linux.h \ 149 152 ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/RTLogWriteDebugger-r0drv-linux.c=>r0drv/linux/RTLogWriteDebugger-r0drv-linux.c \ 150 153 ${PATH_ROOT}/src/VBox/Runtime/r0drv/generic/semspinmutex-r0drv-generic.c=>r0drv/generic/semspinmutex-r0drv-generic.c \ -
trunk/src/VBox/HostDrivers/Support/linux/Makefile
r32572 r33011 131 131 generic/RTLogWriteUser-generic.o \ 132 132 generic/RTMpGetArraySize-generic.o \ 133 generic/RTSemEventMultiWait-2-ex-generic.o \ 134 generic/RTSemEventMultiWaitNoResume-2-ex-generic.o \ 133 135 generic/RTTimerCreate-generic.o \ 134 136 generic/uuid-generic.o \ -
trunk/src/VBox/HostDrivers/Support/linux/files_vboxdrv
r32572 r33011 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/RTSemEventMultiWait-2-ex-generic.cpp=>generic/RTSemEventMultiWait-2-ex-generic.c \ 132 ${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp=>generic/RTSemEventMultiWaitNoResume-2-ex-generic.c \ 131 133 ${PATH_ROOT}/src/VBox/Runtime/generic/RTTimerCreate-generic.cpp=>generic/RTTimerCreate-generic.c \ 132 134 ${PATH_ROOT}/src/VBox/Runtime/generic/uuid-generic.cpp=>generic/uuid-generic.c \ … … 158 160 ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/time-r0drv-linux.c=>r0drv/linux/time-r0drv-linux.c \ 159 161 ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/timer-r0drv-linux.c=>r0drv/linux/timer-r0drv-linux.c \ 162 ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/waitqueue-r0drv-linux.h=>r0drv/linux/waitqueue-r0drv-linux.h \ 160 163 ${PATH_ROOT}/src/VBox/Runtime/r0drv/generic/semspinmutex-r0drv-generic.c=>r0drv/generic/semspinmutex-r0drv-generic.c \ 161 164 ${PATH_ROOT}/src/VBox/Runtime/r0drv/memobj-r0drv.cpp=>r0drv/memobj-r0drv.c \ -
trunk/src/VBox/HostDrivers/Support/testcase/tstSupSem.cpp
r32431 r33011 111 111 RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS); 112 112 RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 0), VERR_TIMEOUT); 113 RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 1), VERR_TIMEOUT); 114 RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 2), VERR_TIMEOUT); 115 RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 8), VERR_TIMEOUT); 113 116 RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent,20), VERR_TIMEOUT); 114 117 RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent), VINF_SUCCESS); 115 118 RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 0), VINF_SUCCESS); 116 119 RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent), VINF_SUCCESS); 117 RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent,20), VINF_SUCCESS); 120 RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 1), VINF_SUCCESS); 121 RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent), VINF_SUCCESS); 122 RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 2), VINF_SUCCESS); 123 RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent), VINF_SUCCESS); 124 RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 8), VINF_SUCCESS); 125 RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent), VINF_SUCCESS); 126 RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 20), VINF_SUCCESS); 127 RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent), VINF_SUCCESS); 128 RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent,1000),VINF_SUCCESS); 118 129 RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent), VINF_SUCCESS); 119 130 RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent), VINF_SUCCESS); 120 131 RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 0), VINF_SUCCESS); 121 132 RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 0), VERR_TIMEOUT); 133 RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 1), VERR_TIMEOUT); 134 RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 2), VERR_TIMEOUT); 135 RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 8), VERR_TIMEOUT); 122 136 RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent,20), VERR_TIMEOUT); 123 137 RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED); … … 129 143 RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEventMulti), VINF_SUCCESS); 130 144 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0), VERR_TIMEOUT); 145 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 1), VERR_TIMEOUT); 146 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 2), VERR_TIMEOUT); 147 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 8), VERR_TIMEOUT); 131 148 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,20), VERR_TIMEOUT); 132 149 RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEventMulti), VINF_SUCCESS); … … 134 151 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0), VINF_SUCCESS); 135 152 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0), VINF_SUCCESS); 153 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 1), VINF_SUCCESS); 154 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 2), VINF_SUCCESS); 155 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 8), VINF_SUCCESS); 156 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,20), VINF_SUCCESS); 157 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,1000), VINF_SUCCESS); 136 158 RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEventMulti), VINF_SUCCESS); 137 159 RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEventMulti), VINF_SUCCESS); … … 139 161 RTTESTI_CHECK_RC(SUPSemEventMultiReset(pSession, hEventMulti), VINF_SUCCESS); 140 162 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0), VERR_TIMEOUT); 163 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 1), VERR_TIMEOUT); 164 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 2), VERR_TIMEOUT); 165 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 8), VERR_TIMEOUT); 141 166 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,20), VERR_TIMEOUT); 142 167 RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEventMulti), VINF_SUCCESS); 143 168 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0), VINF_SUCCESS); 169 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 1), VINF_SUCCESS); 170 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 2), VINF_SUCCESS); 171 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 8), VINF_SUCCESS); 172 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 20), VINF_SUCCESS); 173 RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,1000), VINF_SUCCESS); 144 174 RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEventMulti), VINF_OBJECT_DESTROYED); 145 175 RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEventMulti), VERR_INVALID_HANDLE); -
trunk/src/VBox/Runtime/Makefile.kmk
r32997 r33011 1430 1430 generic/RTAssertShouldPanic-generic.cpp \ 1431 1431 generic/RTLogWriteStdOut-stub-generic.cpp \ 1432 generic/RTSemEventMultiWait-2-ex-generic.cpp \ 1433 generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp \ 1432 1434 generic/mppresent-generic.cpp \ 1433 1435 r0drv/linux/alloc-r0drv-linux.c \ -
trunk/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c
r33006 r33011 175 175 * @param enmType The object type. 176 176 * @param cb The number of bytes to allocate. 177 * @param uAlignment The alignment of the phy iscal memory.177 * @param uAlignment The alignment of the physical memory. 178 178 * Only valid if fContiguous == true, ignored otherwise. 179 179 * @param fFlagsLnx The page allocation flags (GPFs). -
trunk/src/VBox/Runtime/r0drv/linux/semeventmulti-r0drv-linux.c
r29661 r33011 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 35 #include <iprt/assert.h> 36 36 #include <iprt/asm.h> 37 37 #include <iprt/err.h> 38 38 #include <iprt/mem.h> 39 #include <iprt/lockvalidator.h> 40 41 #include "waitqueue-r0drv-linux.h" 39 42 #include "internal/magics.h" 40 43 44 45 /******************************************************************************* 46 * Defined Constants And Macros * 47 *******************************************************************************/ 48 /** @name fStateAndGen values 49 * @{ */ 50 /** The state bit number. */ 51 #define RTSEMEVENTMULTILNX_STATE_BIT 0 52 /** The state mask. */ 53 #define RTSEMEVENTMULTILNX_STATE_MASK RT_BIT_32(RTSEMEVENTMULTILNX_STATE_BIT) 54 /** The generation mask. */ 55 #define RTSEMEVENTMULTILNX_GEN_MASK ~RTSEMEVENTMULTILNX_STATE_MASK 56 /** The generation shift. */ 57 #define RTSEMEVENTMULTILNX_GEN_SHIFT 1 58 /** The initial variable value. */ 59 #define RTSEMEVENTMULTILNX_STATE_GEN_INIT UINT32_C(0xfffffffc) 60 /** @} */ 41 61 42 62 /******************************************************************************* … … 50 70 /** Magic value (RTSEMEVENTMULTI_MAGIC). */ 51 71 uint32_t volatile u32Magic; 52 /** The object status - !0 when signaled and 0 when reset. */ 53 uint32_t volatile fState; 72 /** The object state bit and generation counter. 73 * The generation counter is incremented every time the object is */ 74 uint32_t volatile fStateAndGen; 75 /** Reference counter. */ 76 uint32_t volatile cRefs; 54 77 /** The wait queue. */ 55 78 wait_queue_head_t Head; 56 79 } RTSEMEVENTMULTIINTERNAL, *PRTSEMEVENTMULTIINTERNAL; 80 81 57 82 58 83 … … 73 98 if (pThis) 74 99 { 75 pThis->u32Magic = RTSEMEVENTMULTI_MAGIC; 76 pThis->fState = 0; 100 pThis->u32Magic = RTSEMEVENTMULTI_MAGIC; 101 pThis->fStateAndGen = RTSEMEVENTMULTILNX_STATE_GEN_INIT; 102 pThis->cRefs = 1; 77 103 init_waitqueue_head(&pThis->Head); 78 104 … … 83 109 } 84 110 RT_EXPORT_SYMBOL(RTSemEventMultiCreate); 111 112 113 /** 114 * Retain a reference to the semaphore. 115 * 116 * @param pThis The semaphore. 117 */ 118 DECLINLINE(void) rtR0SemEventMultiLnxRetain(PRTSEMEVENTMULTIINTERNAL pThis) 119 { 120 uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs); 121 Assert(cRefs && cRefs < 100000); 122 } 123 124 125 /** 126 * Release a reference, destroy the thing if necessary. 127 * 128 * @param pThis The semaphore. 129 */ 130 DECLINLINE(void) rtR0SemEventMultiLnxRelease(PRTSEMEVENTMULTIINTERNAL pThis) 131 { 132 if (RT_UNLIKELY(ASMAtomicDecU32(&pThis->cRefs) == 0)) 133 { 134 Assert(pThis->u32Magic != RTSEMEVENTMULTI_MAGIC); 135 RTMemFree(pThis); 136 } 137 } 85 138 86 139 … … 95 148 AssertPtrReturn(pThis, VERR_INVALID_PARAMETER); 96 149 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER); 150 Assert(pThis->cRefs > 0); 97 151 98 152 /* … … 100 154 */ 101 155 ASMAtomicWriteU32(&pThis->u32Magic, ~RTSEMEVENTMULTI_MAGIC); 102 ASMAtomic XchgU32(&pThis->fState, 0);156 ASMAtomicAndU32(&pThis->fStateAndGen, RTSEMEVENTMULTILNX_GEN_MASK); 103 157 Assert(!waitqueue_active(&pThis->Head)); 104 158 wake_up_all(&pThis->Head); 105 RTMemFree(pThis);106 159 return VINF_SUCCESS; 107 160 } … … 111 164 RTDECL(int) RTSemEventMultiSignal(RTSEMEVENTMULTI hEventMultiSem) 112 165 { 166 uint32_t fNew; 167 uint32_t fOld; 168 113 169 /* 114 170 * Validate input. … … 119 175 AssertPtrReturn(pThis, VERR_INVALID_PARAMETER); 120 176 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER); 121 122 /* 123 * Signal the event object. 124 */ 125 ASMAtomicXchgU32(&pThis->fState, 1); 177 rtR0SemEventMultiLnxRetain(pThis); 178 179 /* 180 * Signal the event object. The cause of the parnoia here is racing to try 181 * deal with racing RTSemEventMultiSignal calls (should probably be 182 * forbidden, but it's relatively easy to handle). 183 */ 184 do 185 { 186 fNew = fOld = ASMAtomicUoReadU32(&pThis->fStateAndGen); 187 fNew += 1 << RTSEMEVENTMULTILNX_GEN_SHIFT; 188 fNew |= RTSEMEVENTMULTILNX_STATE_MASK; 189 } 190 while (!ASMAtomicCmpXchgU32(&pThis->fStateAndGen, fNew, fOld)); 191 126 192 wake_up_all(&pThis->Head); 193 194 rtR0SemEventMultiLnxRelease(pThis); 127 195 return VINF_SUCCESS; 128 196 } … … 140 208 AssertPtrReturn(pThis, VERR_INVALID_PARAMETER); 141 209 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER); 210 rtR0SemEventMultiLnxRetain(pThis); 142 211 143 212 /* 144 213 * Reset it. 145 214 */ 146 ASMAtomicXchgU32(&pThis->fState, 0); 215 ASMAtomicAndU32(&pThis->fStateAndGen, ~RTSEMEVENTMULTILNX_STATE_MASK); 216 217 rtR0SemEventMultiLnxRelease(pThis); 147 218 return VINF_SUCCESS; 148 219 } … … 151 222 152 223 /** 153 * Worker for RTSemEventMulti and RTSemEventMultiNoResume.224 * Worker for RTSemEventMultiWaitEx and RTSemEventMultiWaitExDebug. 154 225 * 155 226 * @returns VBox status code. 156 227 * @param pThis The event semaphore. 157 * @param cMillies The number of milliseconds to wait. 158 * @param fInterruptible Whether it's an interruptible wait or not. 159 */ 160 static int rtSemEventMultiWait(PRTSEMEVENTMULTIINTERNAL pThis, RTMSINTERVAL cMillies, bool fInterruptible) 161 { 162 /* 163 * Ok wait for it. 164 */ 165 DEFINE_WAIT(Wait); 166 int rc = VINF_SUCCESS; 167 long lTimeout = cMillies == RT_INDEFINITE_WAIT ? MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(cMillies); 168 IPRT_DEBUG_SEMS_STATE(pThis, 'E'); 169 for (;;) 228 */ 229 static int rtR0SemEventMultiLnxWait(PRTSEMEVENTMULTIINTERNAL pThis, uint32_t fFlags, uint64_t uTimeout, 230 PCRTLOCKVALSRCPOS pSrcPos) 231 { 232 uint32_t fOrgStateAndGen; 233 int rc; 234 235 /* 236 * Validate the input. 237 */ 238 AssertPtrReturn(pThis, VERR_INVALID_PARAMETER); 239 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER); 240 rtR0SemEventMultiLnxRetain(pThis); 241 242 /* 243 * Is the event already signalled or do we have to wait? 244 */ 245 fOrgStateAndGen = ASMAtomicUoReadU32(&pThis->fStateAndGen); 246 if (fOrgStateAndGen & RTSEMEVENTMULTILNX_STATE_MASK) 247 rc = VINF_SUCCESS; 248 else 170 249 { 171 /* make everything thru schedule() atomic scheduling wise. */ 172 prepare_to_wait(&pThis->Head, &Wait, fInterruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); 173 174 /* check the condition. */ 175 if (pThis->fState) 176 break; 177 178 /* check for pending signals. */ 179 if (fInterruptible && signal_pending(current)) 250 /* 251 * We have to wait. 252 */ 253 RTR0SEMLNXWAIT Wait; 254 rc = rtR0SemLnxWaitInit(&Wait, fFlags, uTimeout, &pThis->Head); 255 if (RT_SUCCESS(rc)) 180 256 { 181 rc = VERR_INTERRUPTED; 182 break; 183 } 184 185 /* wait */ 186 lTimeout = schedule_timeout(lTimeout); 187 188 after_wait(&Wait); 189 190 /* Check if someone destroyed the semaphore while we were waiting. */ 191 if (pThis->u32Magic != RTSEMEVENTMULTI_MAGIC) 192 { 193 rc = VERR_SEM_DESTROYED; 194 break; 195 } 196 197 /* check for timeout. */ 198 if (!lTimeout) 199 { 200 rc = VERR_TIMEOUT; 201 break; 257 IPRT_DEBUG_SEMS_STATE(pThis, 'E'); 258 for (;;) 259 { 260 /* The destruction test. */ 261 if (RT_UNLIKELY(pThis->u32Magic != RTSEMEVENTMULTI_MAGIC)) 262 rc = VERR_SEM_DESTROYED; 263 else 264 { 265 rtR0SemLnxWaitPrepare(&Wait); 266 267 /* Check the exit conditions. */ 268 if (RT_UNLIKELY(pThis->u32Magic != RTSEMEVENTMULTI_MAGIC)) 269 rc = VERR_SEM_DESTROYED; 270 else if (ASMAtomicUoReadU32(&pThis->fStateAndGen) != fOrgStateAndGen) 271 rc = VINF_SUCCESS; 272 else if (rtR0SemLnxWaitHasTimedOut(&Wait)) 273 rc = VERR_TIMEOUT; 274 else if (rtR0SemLnxWaitWasInterrupted(&Wait)) 275 rc = VERR_INTERRUPTED; 276 else 277 { 278 /* Do the wait and then recheck the conditions. */ 279 rtR0SemLnxWaitDoIt(&Wait); 280 continue; 281 } 282 } 283 break; 284 } 285 286 rtR0SemLnxWaitDelete(&Wait); 287 IPRT_DEBUG_SEMS_STATE_RC(pThis, 'E', rc); 202 288 } 203 289 } 204 290 205 finish_wait(&pThis->Head, &Wait); 206 IPRT_DEBUG_SEMS_STATE_RC(pThis, 'E', rc); 291 rtR0SemEventMultiLnxRelease(pThis); 207 292 return rc; 208 293 } 209 294 210 295 211 RTDECL(int) RTSemEventMultiWait(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies) 212 { 213 PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem; 214 if (!pThis) 215 return VERR_INVALID_PARAMETER; 216 AssertPtrReturn(pThis, VERR_INVALID_PARAMETER); 217 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER); 218 219 if (pThis->fState) 220 return VINF_SUCCESS; 221 return rtSemEventMultiWait(pThis, cMillies, false /* fInterruptible */); 222 } 223 RT_EXPORT_SYMBOL(RTSemEventMultiWait); 224 225 226 RTDECL(int) RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies) 227 { 228 PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem; 229 if (!pThis) 230 return VERR_INVALID_PARAMETER; 231 AssertPtrReturn(pThis, VERR_INVALID_PARAMETER); 232 AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER); 233 234 if (pThis->fState) 235 return VINF_SUCCESS; 236 return rtSemEventMultiWait(pThis, cMillies, true /* fInterruptible */); 237 } 238 RT_EXPORT_SYMBOL(RTSemEventMultiWaitNoResume); 239 296 #undef RTSemEventMultiWaitEx 297 RTDECL(int) RTSemEventMultiWaitEx(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout) 298 { 299 #ifndef RTSEMEVENT_STRICT 300 return rtR0SemEventMultiLnxWait(hEventMultiSem, fFlags, uTimeout, NULL); 301 #else 302 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API(); 303 return rtR0SemEventMultiLnxWait(hEventMultiSem, fFlags, uTimeout, &SrcPos); 304 #endif 305 } 306 RT_EXPORT_SYMBOL(RTSemEventMultiWaitEx); 307 308 309 RTDECL(int) RTSemEventMultiWaitExDebug(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout, 310 RTHCUINTPTR uId, RT_SRC_POS_DECL) 311 { 312 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API(); 313 return rtR0SemEventMultiLnxWait(hEventMultiSem, fFlags, uTimeout, &SrcPos); 314 } 315 RT_EXPORT_SYMBOL(RTSemEventMultiWaitExDebug); 316 -
trunk/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
r29648 r33011 347 347 #endif 348 348 349 #endif 350 349 /* 350 * Some global indicator macros. 351 */ 352 /** @def IPRT_LINUX_HAS_HRTIMER 353 * Whether the kernel support high resolution timers (Linux kernel versions 354 * 2.6.28 and later (hrtimer_add_expires_ns() & schedule_hrtimeout). */ 355 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) 356 # define IPRT_LINUX_HAS_HRTIMER 357 #endif 358 359 360 #endif 361 -
trunk/src/VBox/Runtime/r0drv/linux/timer-r0drv-linux.c
r32757 r33011 44 44 #include "internal/magics.h" 45 45 46 /** @def RTTIMER_LINUX_HAVE_HRTIMER47 * Whether the kernel support high resolution timers (Linux kernel versions48 * 2.6.28 and later (hrtimer_add_expires_ns()). */49 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)50 # define RTTIMER_LINUX_HAVE_HRTIMER51 #endif52 53 46 /** @def RTTIMER_LINUX_WITH_HRTIMER 54 47 * Whether to use high resolution timers. */ 55 48 #if !defined(RTTIMER_LINUX_WITH_HRTIMER) \ 56 && defined( RTTIMER_LINUX_HAVE_HRTIMER)49 && defined(IPRT_LINUX_HAS_HRTIMER) 57 50 # define RTTIMER_LINUX_WITH_HRTIMER 58 51 #endif
Note:
See TracChangeset
for help on using the changeset viewer.