VirtualBox

Changeset 92818 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Dec 8, 2021 2:05:45 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
148738
Message:

IPRT/semeventmulti-nt: Converted semeventmulti-r0drv-nt.cpp into something that works both in ring-3 and ring-0. bugref:10138

Location:
trunk/src/VBox/Runtime
Files:
2 edited
1 copied
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/Makefile.kmk

    r92794 r92818  
    937937        generic/RTRandAdvCreateSystemFaster-generic.cpp \
    938938        generic/RTRandAdvCreateSystemTruer-generic.cpp \
     939        generic/RTSemEventWait-2-ex-generic.cpp \
     940        generic/RTSemEventWaitNoResume-2-ex-generic.cpp \
    939941        generic/RTSemEventMultiWait-2-ex-generic.cpp \
    940942        generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp \
     
    965967        nt/semevent-nt.cpp \
    966968        nt/RTSemEventGetResolution-nt.cpp \
     969        nt/semeventmulti-nt.cpp \
     970        nt/RTSemEventMultiGetResolution-nt.cpp \
    967971        r3/win/env-win.cpp \
    968972        r3/win/RTCrStoreCreateSnapshotById-win.cpp \
     
    9961000        r3/win/rtProcInitExePath-win.cpp \
    9971001        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 \
    10011002        r3/win/semmutex-win.cpp \
    10021003        r3/win/serialport-win.cpp \
     
    20442045        generic/RTRandAdvCreateSystemFaster-generic.cpp \
    20452046        generic/RTRandAdvCreateSystemTruer-generic.cpp \
     2047        generic/RTSemEventWait-2-ex-generic.cpp \
     2048        generic/RTSemEventWaitNoResume-2-ex-generic.cpp \
    20462049        generic/RTSemEventMultiWait-2-ex-generic.cpp \
    20472050        generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp \
    2048         generic/RTSemEventWait-generic.cpp \
    20492051        generic/RTSemMutexRequest-generic.cpp \
    20502052        generic/RTSemMutexRequestDebug-generic.cpp \
     
    20542056        nt/RTErrConvertFromNtStatus.cpp \
    20552057        nt/semevent-nt.cpp \
     2058        nt/semeventmulti-nt.cpp \
    20562059        r3/nt/direnum-r3-nt.cpp \
    20572060        r3/nt/dirrel-r3-nt.cpp \
     
    20802083        r3/win/RTUuidCreate-win.cpp \
    20812084        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 \
    20852085        r3/win/semmutex-win.cpp \
    20862086        r3/win/symlink-win.cpp \
     
    32203220        nt/semevent-nt.cpp \
    32213221        nt/RTSemEventGetResolution-nt.cpp \
     3222        nt/semeventmulti-nt.cpp \
     3223        nt/RTSemEventMultiGetResolution-nt.cpp \
    32223224        r0drv/generic/threadctxhooks-r0drv-generic.cpp \
    32233225        r0drv/alloc-ef-r0drv.cpp \
     
    32343236        r0drv/nt/process-r0drv-nt.cpp \
    32353237        r0drv/nt/RTLogWriteDebugger-r0drv-nt.cpp \
    3236         r0drv/nt/semeventmulti-r0drv-nt.cpp \
    32373238        r0drv/nt/semfastmutex-r0drv-nt.cpp \
    32383239        r0drv/nt/semmutex-r0drv-nt.cpp \
  • trunk/src/VBox/Runtime/nt/RTSemEventMultiGetResolution-nt.cpp

    r92802 r92818  
    11/* $Id$ */
    22/** @file
    3  * IPRT -  Single Release Event Semaphores, RTSemEventGetResolution.
     3 * IPRT -  Single Release Event Semaphores, RTSemEventMultiGetResolution.
    44 */
    55
     
    4444
    4545
    46 RTDECL(uint32_t) RTSemEventGetResolution(void)
     46RTDECL(uint32_t) RTSemEventMultiGetResolution(void)
    4747{
    4848    /*
  • trunk/src/VBox/Runtime/nt/semevent-nt.cpp

    r92794 r92818  
    4343#include <iprt/mem.h>
    4444#include <iprt/time.h>
     45
    4546#include "internal/magics.h"
    4647
  • trunk/src/VBox/Runtime/nt/semeventmulti-nt.cpp

    r92817 r92818  
    3030*********************************************************************************************************************************/
    3131#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
    3337#include <iprt/semaphore.h>
    3438
     
    5660    /** Reference counter. */
    5761    uint32_t volatile   cRefs;
    58     /** The NT Event object. */
     62#ifdef IN_RING0
     63    /** The NT event object. */
    5964    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
    6075} RTSEMEVENTMULTIINTERNAL, *PRTSEMEVENTMULTIINTERNAL;
    6176
     
    7994        pThis->u32Magic = RTSEMEVENTMULTI_MAGIC;
    8095        pThis->cRefs    = 1;
     96#ifdef IN_RING0
    8197        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
    85133    }
    86134    return VERR_NO_MEMORY;
     
    108156{
    109157    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
    110167        RTMemFree(pThis);
     168    }
    111169}
    112170
     
    127185     */
    128186    ASMAtomicIncU32(&pThis->u32Magic);
     187#ifdef IN_RING0
    129188    KeSetEvent(&pThis->Event, 0xfff, FALSE);
     189#else
     190    NtSetEvent(pThis->hEvent, NULL);
     191#endif
     192
    130193    rtR0SemEventMultiNtRelease(pThis);
    131194    return VINF_SUCCESS;
     
    145208    rtR0SemEventMultiNtRetain(pThis);
    146209
     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
    147219    /*
    148220     * Signal the event object.
    149221     */
     222#ifdef IN_RING0
    150223    KeSetEvent(&pThis->Event, 1, FALSE);
     224#else
     225    NTSTATUS rcNt = NtSetEvent(pThis->hEvent, NULL);
     226#endif
    151227
    152228    rtR0SemEventMultiNtRelease(pThis);
     229#ifdef IN_RING3
     230    AssertMsgReturn(NT_SUCCESS(rcNt), ("Signaling hEventMultiSem %p failed: %#x\n", pThis, rcNt), RTErrConvertFromNtStatus(rcNt));
     231#endif
    153232    return VINF_SUCCESS;
    154233}
     
    170249     * Reset the event object.
    171250     */
     251#ifdef IN_RING0
    172252    KeResetEvent(&pThis->Event);
     253#else
     254    NTSTATUS rcNt = NtResetEvent(pThis->hEvent, NULL);
     255#endif
    173256
    174257    rtR0SemEventMultiNtRelease(pThis);
     258#ifdef IN_RING3
     259    AssertMsgReturn(NT_SUCCESS(rcNt), ("Resetting hEventMultiSem %p failed: %#x\n", pThis, rcNt), RTErrConvertFromNtStatus(rcNt));
     260#endif
    175261    return VINF_SUCCESS;
    176262}
     
    202288
    203289    /*
     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    /*
    204310     * Convert the timeout to a relative one because KeWaitForSingleObject
    205311     * takes system time instead of interrupt time as input for absolute
     
    208314     * Lazy bird converts uTimeout to relative nanoseconds and then to Nt time.
    209315     */
     316#ifdef IN_RING3
     317    uint64_t nsStartNow = 0;
     318#endif
    210319    if (!(fFlags & RTSEMWAIT_FLAGS_INDEFINITE))
    211320    {
    212321        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
    215324                     : UINT64_MAX;
    216325        if (uTimeout == UINT64_MAX)
     
    218327        else
    219328        {
     329#ifdef IN_RING3
     330            if (fFlags & (RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_ABSOLUTE))
     331                nsStartNow = RTTimeSystemNanoTS();
     332#endif
    220333            if (fFlags & RTSEMWAIT_FLAGS_ABSOLUTE)
    221334            {
    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
    225340                         : 0;
    226341            }
     
    232347     * We're assuming interruptible waits should happen at UserMode level.
    233348     */
    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
    240353    {
    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
    244432    }
    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     else
    270         rc = VERR_SEM_DESTROYED;
    271433
    272434    rtR0SemEventMultiNtRelease(pThis);
     
    294456
    295457
    296 RTDECL(uint32_t) RTSemEventMultiGetResolution(void)
    297 {
    298     return RTTimerGetSystemGranularity();
    299 }
    300 
    301 
     458#ifdef IN_RING0
    302459RTR0DECL(bool) RTSemEventMultiIsSignalSafe(void)
    303460{
    304461    return KeGetCurrentIrql() <= DISPATCH_LEVEL;
    305462}
    306 
     463#endif
     464
     465#ifdef IN_RING3
     466
     467RTDECL(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
     482RTDECL(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
     497RTDECL(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.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette