Changeset 92818 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Dec 8, 2021 2:05:45 PM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 148738
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 2 edited
- 1 copied
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/Makefile.kmk
r92794 r92818 937 937 generic/RTRandAdvCreateSystemFaster-generic.cpp \ 938 938 generic/RTRandAdvCreateSystemTruer-generic.cpp \ 939 generic/RTSemEventWait-2-ex-generic.cpp \ 940 generic/RTSemEventWaitNoResume-2-ex-generic.cpp \ 939 941 generic/RTSemEventMultiWait-2-ex-generic.cpp \ 940 942 generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp \ … … 965 967 nt/semevent-nt.cpp \ 966 968 nt/RTSemEventGetResolution-nt.cpp \ 969 nt/semeventmulti-nt.cpp \ 970 nt/RTSemEventMultiGetResolution-nt.cpp \ 967 971 r3/win/env-win.cpp \ 968 972 r3/win/RTCrStoreCreateSnapshotById-win.cpp \ … … 996 1000 r3/win/rtProcInitExePath-win.cpp \ 997 1001 r3/win/sched-win.cpp \ 998 generic/RTSemEventWait-2-ex-generic.cpp \999 generic/RTSemEventWaitNoResume-2-ex-generic.cpp \1000 r3/win/semeventmulti-win.cpp \1001 1002 r3/win/semmutex-win.cpp \ 1002 1003 r3/win/serialport-win.cpp \ … … 2044 2045 generic/RTRandAdvCreateSystemFaster-generic.cpp \ 2045 2046 generic/RTRandAdvCreateSystemTruer-generic.cpp \ 2047 generic/RTSemEventWait-2-ex-generic.cpp \ 2048 generic/RTSemEventWaitNoResume-2-ex-generic.cpp \ 2046 2049 generic/RTSemEventMultiWait-2-ex-generic.cpp \ 2047 2050 generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp \ 2048 generic/RTSemEventWait-generic.cpp \2049 2051 generic/RTSemMutexRequest-generic.cpp \ 2050 2052 generic/RTSemMutexRequestDebug-generic.cpp \ … … 2054 2056 nt/RTErrConvertFromNtStatus.cpp \ 2055 2057 nt/semevent-nt.cpp \ 2058 nt/semeventmulti-nt.cpp \ 2056 2059 r3/nt/direnum-r3-nt.cpp \ 2057 2060 r3/nt/dirrel-r3-nt.cpp \ … … 2080 2083 r3/win/RTUuidCreate-win.cpp \ 2081 2084 r3/win/sched-win.cpp \ 2082 generic/RTSemEventWait-2-ex-generic.cpp \2083 generic/RTSemEventWaitNoResume-2-ex-generic.cpp \2084 r3/win/semeventmulti-win.cpp \2085 2085 r3/win/semmutex-win.cpp \ 2086 2086 r3/win/symlink-win.cpp \ … … 3220 3220 nt/semevent-nt.cpp \ 3221 3221 nt/RTSemEventGetResolution-nt.cpp \ 3222 nt/semeventmulti-nt.cpp \ 3223 nt/RTSemEventMultiGetResolution-nt.cpp \ 3222 3224 r0drv/generic/threadctxhooks-r0drv-generic.cpp \ 3223 3225 r0drv/alloc-ef-r0drv.cpp \ … … 3234 3236 r0drv/nt/process-r0drv-nt.cpp \ 3235 3237 r0drv/nt/RTLogWriteDebugger-r0drv-nt.cpp \ 3236 r0drv/nt/semeventmulti-r0drv-nt.cpp \3237 3238 r0drv/nt/semfastmutex-r0drv-nt.cpp \ 3238 3239 r0drv/nt/semmutex-r0drv-nt.cpp \ -
trunk/src/VBox/Runtime/nt/RTSemEventMultiGetResolution-nt.cpp
r92802 r92818 1 1 /* $Id$ */ 2 2 /** @file 3 * IPRT - Single Release Event Semaphores, RTSemEvent GetResolution.3 * IPRT - Single Release Event Semaphores, RTSemEventMultiGetResolution. 4 4 */ 5 5 … … 44 44 45 45 46 RTDECL(uint32_t) RTSemEvent GetResolution(void)46 RTDECL(uint32_t) RTSemEventMultiGetResolution(void) 47 47 { 48 48 /* -
trunk/src/VBox/Runtime/nt/semevent-nt.cpp
r92794 r92818 43 43 #include <iprt/mem.h> 44 44 #include <iprt/time.h> 45 45 46 #include "internal/magics.h" 46 47 -
trunk/src/VBox/Runtime/nt/semeventmulti-nt.cpp
r92817 r92818 30 30 *********************************************************************************************************************************/ 31 31 #define RTSEMEVENTMULTI_WITHOUT_REMAPPING 32 #include "the-nt-kernel.h" 32 #ifdef IN_RING0 33 # include "../r0drv/nt/the-nt-kernel.h" 34 #else 35 # include <iprt/nt/nt.h> 36 #endif 33 37 #include <iprt/semaphore.h> 34 38 … … 56 60 /** Reference counter. */ 57 61 uint32_t volatile cRefs; 58 /** The NT Event object. */ 62 #ifdef IN_RING0 63 /** The NT event object. */ 59 64 KEVENT Event; 65 #elif defined(IN_RING3) 66 /** Handle to the NT event object. */ 67 HANDLE hEvent; 68 #endif 69 #if defined(RTSEMEVENT_STRICT) && defined(IN_RING3) 70 /** Signallers. */ 71 RTLOCKVALRECSHRD Signallers; 72 /** Indicates that lock validation should be performed. */ 73 bool volatile fEverHadSignallers; 74 #endif 60 75 } RTSEMEVENTMULTIINTERNAL, *PRTSEMEVENTMULTIINTERNAL; 61 76 … … 79 94 pThis->u32Magic = RTSEMEVENTMULTI_MAGIC; 80 95 pThis->cRefs = 1; 96 #ifdef IN_RING0 81 97 KeInitializeEvent(&pThis->Event, NotificationEvent, FALSE /* not signalled */); 82 83 *phEventMultiSem = pThis; 84 return VINF_SUCCESS; 98 #else 99 NTSTATUS rcNt = NtCreateEvent(&pThis->hEvent, EVENT_ALL_ACCESS, NULL /*pObjAttr*/, 100 NotificationEvent, FALSE /*not signalled*/); 101 if (NT_SUCCESS(rcNt)) 102 #endif 103 { 104 #if defined(RTSEMEVENT_STRICT) && defined(IN_RING3) 105 if (!pszNameFmt) 106 { 107 static uint32_t volatile s_iSemEventMultiAnon = 0; 108 RTLockValidatorRecSharedInit(&pThis->Signallers, hClass, RTLOCKVAL_SUB_CLASS_ANY, pThis, 109 true /*fSignaller*/, !(fFlags & RTSEMEVENTMULTI_FLAGS_NO_LOCK_VAL), 110 "RTSemEventMulti-%u", ASMAtomicIncU32(&s_iSemEventMultiAnon) - 1); 111 } 112 else 113 { 114 va_list va; 115 va_start(va, pszNameFmt); 116 RTLockValidatorRecSharedInitV(&pThis->Signallers, hClass, RTLOCKVAL_SUB_CLASS_ANY, pThis, 117 true /*fSignaller*/, !(fFlags & RTSEMEVENTMULTI_FLAGS_NO_LOCK_VAL), 118 pszNameFmt, va); 119 va_end(va); 120 } 121 pThis->fEverHadSignallers = false; 122 #else 123 RT_NOREF_PV(hClass); RT_NOREF_PV(pszNameFmt); 124 #endif 125 126 *phEventMultiSem = pThis; 127 return VINF_SUCCESS; 128 } 129 #ifdef IN_RING3 130 RTMemFree(pThis); 131 return RTErrConvertFromNtStatus(rcNt); 132 #endif 85 133 } 86 134 return VERR_NO_MEMORY; … … 108 156 { 109 157 if (ASMAtomicDecU32(&pThis->cRefs) == 0) 158 { 159 #ifdef IN_RING3 160 NTSTATUS rcNt = NtClose(pThis->hEvent); 161 AssertMsg(NT_SUCCESS(rcNt), ("%#x\n", rcNt)); RT_NOREF(rcNt); 162 pThis->hEvent = NULL; 163 #endif 164 #if defined(RTSEMEVENT_STRICT) && defined(IN_RING3) 165 RTLockValidatorRecSharedDelete(&pThis->Signallers); 166 #endif 110 167 RTMemFree(pThis); 168 } 111 169 } 112 170 … … 127 185 */ 128 186 ASMAtomicIncU32(&pThis->u32Magic); 187 #ifdef IN_RING0 129 188 KeSetEvent(&pThis->Event, 0xfff, FALSE); 189 #else 190 NtSetEvent(pThis->hEvent, NULL); 191 #endif 192 130 193 rtR0SemEventMultiNtRelease(pThis); 131 194 return VINF_SUCCESS; … … 145 208 rtR0SemEventMultiNtRetain(pThis); 146 209 210 #if defined(RTSEMEVENT_STRICT) && defined(IN_RING3) 211 if (pThis->fEverHadSignallers) 212 { 213 int rc9 = RTLockValidatorRecSharedCheckSignaller(&pThis->Signallers, NIL_RTTHREAD); 214 if (RT_FAILURE(rc9)) 215 return rc9; 216 } 217 #endif 218 147 219 /* 148 220 * Signal the event object. 149 221 */ 222 #ifdef IN_RING0 150 223 KeSetEvent(&pThis->Event, 1, FALSE); 224 #else 225 NTSTATUS rcNt = NtSetEvent(pThis->hEvent, NULL); 226 #endif 151 227 152 228 rtR0SemEventMultiNtRelease(pThis); 229 #ifdef IN_RING3 230 AssertMsgReturn(NT_SUCCESS(rcNt), ("Signaling hEventMultiSem %p failed: %#x\n", pThis, rcNt), RTErrConvertFromNtStatus(rcNt)); 231 #endif 153 232 return VINF_SUCCESS; 154 233 } … … 170 249 * Reset the event object. 171 250 */ 251 #ifdef IN_RING0 172 252 KeResetEvent(&pThis->Event); 253 #else 254 NTSTATUS rcNt = NtResetEvent(pThis->hEvent, NULL); 255 #endif 173 256 174 257 rtR0SemEventMultiNtRelease(pThis); 258 #ifdef IN_RING3 259 AssertMsgReturn(NT_SUCCESS(rcNt), ("Resetting hEventMultiSem %p failed: %#x\n", pThis, rcNt), RTErrConvertFromNtStatus(rcNt)); 260 #endif 175 261 return VINF_SUCCESS; 176 262 } … … 202 288 203 289 /* 290 * Lock validation needs to be done only when not polling. 291 */ 292 #if defined(RTSEMEVENT_STRICT) && defined(IN_RING3) 293 RTTHREAD const hThreadSelf = RTThreadSelfAutoAdopt(); 294 if ( pThis->fEverHadSignallers 295 && ( uTimeout != 0 296 || (fFlags & (RTSEMWAIT_FLAGS_INDEFINITE | RTSEMWAIT_FLAGS_ABSOLUTE))) ) 297 { 298 int rc9 = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, NULL /*pSrcPos*/, false, 299 fFlags & RTSEMWAIT_FLAGS_INDEFINITE 300 ? RT_INDEFINITE_WAIT : RT_MS_30SEC /*whatever*/, 301 RTTHREADSTATE_EVENT_MULTI, true); 302 if (RT_FAILURE(rc9)) 303 return rc9; 304 } 305 #elif defined(IN_RING3) 306 RTTHREAD const hThreadSelf = RTThreadSelf(); 307 #endif 308 309 /* 204 310 * Convert the timeout to a relative one because KeWaitForSingleObject 205 311 * takes system time instead of interrupt time as input for absolute … … 208 314 * Lazy bird converts uTimeout to relative nanoseconds and then to Nt time. 209 315 */ 316 #ifdef IN_RING3 317 uint64_t nsStartNow = 0; 318 #endif 210 319 if (!(fFlags & RTSEMWAIT_FLAGS_INDEFINITE)) 211 320 { 212 321 if (fFlags & RTSEMWAIT_FLAGS_MILLISECS) 213 uTimeout = uTimeout < UINT64_MAX / UINT32_C(1000000) * UINT32_C(1000000)214 ? uTimeout * UINT32_C(1000000)322 uTimeout = uTimeout < UINT64_MAX / RT_NS_1MS 323 ? uTimeout * RT_NS_1MS 215 324 : UINT64_MAX; 216 325 if (uTimeout == UINT64_MAX) … … 218 327 else 219 328 { 329 #ifdef IN_RING3 330 if (fFlags & (RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_ABSOLUTE)) 331 nsStartNow = RTTimeSystemNanoTS(); 332 #endif 220 333 if (fFlags & RTSEMWAIT_FLAGS_ABSOLUTE) 221 334 { 222 uint64_t u64Now = RTTimeSystemNanoTS(); 223 uTimeout = u64Now < uTimeout 224 ? uTimeout - u64Now 335 #ifdef IN_RING0 336 uint64_t const nsStartNow = RTTimeSystemNanoTS(); 337 #endif 338 uTimeout = nsStartNow < uTimeout 339 ? uTimeout - nsStartNow 225 340 : 0; 226 341 } … … 232 347 * We're assuming interruptible waits should happen at UserMode level. 233 348 */ 234 NTSTATUS rcNt; 235 BOOLEAN fInterruptible = !!(fFlags & RTSEMWAIT_FLAGS_INTERRUPTIBLE); 236 KPROCESSOR_MODE WaitMode = fInterruptible ? UserMode : KernelMode; 237 if (fFlags & RTSEMWAIT_FLAGS_INDEFINITE) 238 rcNt = KeWaitForSingleObject(&pThis->Event, Executive, WaitMode, fInterruptible, NULL); 239 else 349 int rc; 350 #ifdef IN_RING3 351 for (;;) 352 #endif 240 353 { 241 LARGE_INTEGER Timeout; 242 Timeout.QuadPart = -(int64_t)(uTimeout / 100); 243 rcNt = KeWaitForSingleObject(&pThis->Event, Executive, WaitMode, fInterruptible, &Timeout); 354 #ifdef IN_RING0 355 BOOLEAN fInterruptible = !!(fFlags & RTSEMWAIT_FLAGS_INTERRUPTIBLE); 356 KPROCESSOR_MODE WaitMode = fInterruptible ? UserMode : KernelMode; 357 #endif 358 NTSTATUS rcNt; 359 #ifdef IN_RING3 360 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT_MULTI, true); 361 #endif 362 if (fFlags & RTSEMWAIT_FLAGS_INDEFINITE) 363 #ifdef IN_RING0 364 rcNt = KeWaitForSingleObject(&pThis->Event, Executive, WaitMode, fInterruptible, NULL); 365 #else 366 rcNt = NtWaitForSingleObject(pThis->hEvent, TRUE /*Alertable*/, NULL); 367 #endif 368 else 369 { 370 LARGE_INTEGER Timeout; 371 Timeout.QuadPart = -(int64_t)(uTimeout / 100); 372 #ifdef IN_RING0 373 rcNt = KeWaitForSingleObject(&pThis->Event, Executive, WaitMode, fInterruptible, &Timeout); 374 #else 375 rcNt = NtWaitForSingleObject(pThis->hEvent, TRUE /*Alertable*/, &Timeout); 376 #endif 377 } 378 #ifdef IN_RING3 379 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT_MULTI); 380 #endif 381 if (pThis->u32Magic == RTSEMEVENTMULTI_MAGIC) 382 { 383 switch (rcNt) 384 { 385 case STATUS_SUCCESS: 386 rc = VINF_SUCCESS; 387 break; 388 389 case STATUS_TIMEOUT: 390 Assert(!(fFlags & RTSEMWAIT_FLAGS_INDEFINITE)); 391 rc = VERR_TIMEOUT; 392 break; 393 394 case STATUS_USER_APC: 395 case STATUS_ALERTED: 396 rc = VERR_INTERRUPTED; 397 #ifdef IN_RING3 398 /* Loop if when automatically resuming on interruption, adjusting the timeout. */ 399 if (fFlags & RTSEMWAIT_FLAGS_RESUME) 400 { 401 if (!(fFlags & RTSEMWAIT_FLAGS_INDEFINITE) && uTimeout > 0) 402 { 403 uint64_t const nsNewNow = RTTimeSystemNanoTS(); 404 uint64_t const cNsElapsed = nsNewNow - nsStartNow; 405 if (cNsElapsed < uTimeout) 406 uTimeout -= cNsElapsed; 407 else 408 uTimeout = 0; 409 nsStartNow = nsNewNow; 410 } 411 continue; 412 } 413 #endif 414 break; 415 416 #ifdef IN_RING3 417 case STATUS_ABANDONED_WAIT_0: 418 rc = VERR_SEM_OWNER_DIED; 419 break; 420 #endif 421 default: 422 AssertMsgFailed(("pThis->u32Magic=%RX32 pThis=%p: wait returned %x!\n", pThis->u32Magic, pThis, rcNt)); 423 rc = VERR_INTERNAL_ERROR_4; 424 break; 425 } 426 } 427 else 428 rc = VERR_SEM_DESTROYED; 429 #ifdef IN_RING3 430 break; 431 #endif 244 432 } 245 int rc;246 if (pThis->u32Magic == RTSEMEVENTMULTI_MAGIC)247 {248 switch (rcNt)249 {250 case STATUS_SUCCESS:251 rc = VINF_SUCCESS;252 break;253 case STATUS_ALERTED:254 rc = VERR_INTERRUPTED;255 break;256 case STATUS_USER_APC:257 rc = VERR_INTERRUPTED;258 break;259 case STATUS_TIMEOUT:260 rc = VERR_TIMEOUT;261 break;262 default:263 AssertMsgFailed(("pThis->u32Magic=%RX32 pThis=%p: wait returned %lx!\n",264 pThis->u32Magic, pThis, (long)rcNt));265 rc = VERR_INTERNAL_ERROR_4;266 break;267 }268 }269 else270 rc = VERR_SEM_DESTROYED;271 433 272 434 rtR0SemEventMultiNtRelease(pThis); … … 294 456 295 457 296 RTDECL(uint32_t) RTSemEventMultiGetResolution(void) 297 { 298 return RTTimerGetSystemGranularity(); 299 } 300 301 458 #ifdef IN_RING0 302 459 RTR0DECL(bool) RTSemEventMultiIsSignalSafe(void) 303 460 { 304 461 return KeGetCurrentIrql() <= DISPATCH_LEVEL; 305 462 } 306 463 #endif 464 465 #ifdef IN_RING3 466 467 RTDECL(void) RTSemEventMultiSetSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread) 468 { 469 # ifdef RTSEMEVENT_STRICT 470 struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem; 471 AssertPtrReturnVoid(pThis); 472 AssertReturnVoid(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC); 473 474 ASMAtomicWriteBool(&pThis->fEverHadSignallers, true); 475 RTLockValidatorRecSharedResetOwner(&pThis->Signallers, hThread, NULL); 476 # else 477 RT_NOREF_PV(hEventMultiSem); RT_NOREF_PV(hThread); 478 # endif 479 } 480 481 482 RTDECL(void) RTSemEventMultiAddSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread) 483 { 484 # ifdef RTSEMEVENT_STRICT 485 struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem; 486 AssertPtrReturnVoid(pThis); 487 AssertReturnVoid(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC); 488 489 ASMAtomicWriteBool(&pThis->fEverHadSignallers, true); 490 RTLockValidatorRecSharedAddOwner(&pThis->Signallers, hThread, NULL); 491 # else 492 RT_NOREF_PV(hEventMultiSem); RT_NOREF_PV(hThread); 493 # endif 494 } 495 496 497 RTDECL(void) RTSemEventMultiRemoveSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread) 498 { 499 # ifdef RTSEMEVENT_STRICT 500 struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem; 501 AssertPtrReturnVoid(pThis); 502 AssertReturnVoid(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC); 503 504 RTLockValidatorRecSharedRemoveOwner(&pThis->Signallers, hThread); 505 # else 506 RT_NOREF_PV(hEventMultiSem); RT_NOREF_PV(hThread); 507 # endif 508 } 509 510 #endif /* IN_RING3 */
Note:
See TracChangeset
for help on using the changeset viewer.