VirtualBox

Changeset 25513 in vbox for trunk/src/VBox/Runtime/generic


Ignore:
Timestamp:
Dec 20, 2009 12:56:55 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
56186
Message:

semrw-generic.cpp: Don't reset ReadEvent unless it's necessary as it involves a kernel call on Windows (and OS/2). Avoid calling RTTimeNanoTS when cMillies==0 as it also involves a kernel call on some systems.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/generic/semrw-generic.cpp

    r25438 r25513  
    7979    /** The handle of the event object on which the waiting writers block. (automatic reset). */
    8080    RTSEMEVENT          WriteEvent;
     81    /** Need to reset ReadEvent. */
     82    bool                fNeedResetReadEvent;
    8183};
    8284
    83 
    84 /**
    85  * Validate a read-write semaphore handle passed to one of the interface.
    86  *
    87  * @returns true if valid.
    88  * @returns false if invalid.
    89  * @param   pThis   Pointer to the read-write semaphore to validate.
    90  */
    91 inline bool rtsemRWValid(struct RTSEMRWINTERNAL *pThis)
    92 {
    93     if (!VALID_PTR(pThis))
    94         return false;
    95 
    96     if (pThis->u32Magic != RTSEMRW_MAGIC)
    97         return false;
    98     return true;
    99 }
    10085
    10186
     
    128113                    if (RT_SUCCESS(rc))
    129114                    {
    130                         pThis->u32Padding       = 0xa5a55a5a;
    131                         pThis->cReads           = 0;
    132                         pThis->cWrites          = 0;
    133                         pThis->cWriterReads     = 0;
    134                         pThis->cWritesWaiting   = 0;
    135                         pThis->Writer           = NIL_RTTHREAD;
    136                         pThis->u32Magic         = RTSEMRW_MAGIC;
     115                        pThis->u32Padding           = UINT32_C(0xa5a55a5a);
     116                        pThis->cReads               = 0;
     117                        pThis->cWrites              = 0;
     118                        pThis->cWriterReads         = 0;
     119                        pThis->cWritesWaiting       = 0;
     120                        pThis->Writer               = NIL_RTTHREAD;
     121                        pThis->fNeedResetReadEvent  = true;
     122                        pThis->u32Magic             = RTSEMRW_MAGIC;
    137123                        *pRWSem = pThis;
    138124                        return VINF_SUCCESS;
     
    157143{
    158144    struct RTSEMRWINTERNAL *pThis = RWSem;
    159     /*
    160      * Validate handle.
    161      */
    162     if (!rtsemRWValid(pThis))
    163     {
    164         AssertMsgFailed(("Invalid handle %p!\n", RWSem));
    165         return VERR_INVALID_HANDLE;
    166     }
     145
     146    /*
     147     * Validate handle.
     148     */
     149    if (pThis == NIL_RTSEMRW)
     150        return VINF_SUCCESS;
     151    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     152    AssertReturn(pThis->u32Magic == RTSEMRW_MAGIC, VERR_INVALID_HANDLE);
    167153
    168154    /*
     
    177163             * Make it invalid and unusable.
    178164             */
    179             pThis->u32Magic = ~RTSEMRW_MAGIC;
     165            ASMAtomicWriteU32(&pThis->u32Magic, ~RTSEMRW_MAGIC);
    180166            pThis->cReads = ~0;
    181167
     
    184170             */
    185171            rc = RTSemEventMultiDestroy(pThis->ReadEvent);
    186             AssertMsgRC(rc, ("RTSemEventMultiDestroy failed! rc=%d\n", rc));
     172            AssertMsgRC(rc, ("RTSemEventMultiDestroy failed! rc=%Rrc\n", rc));
    187173            pThis->ReadEvent = NIL_RTSEMEVENTMULTI;
    188174
    189175            rc = RTSemEventDestroy(pThis->WriteEvent);
    190             AssertMsgRC(rc, ("RTSemEventDestroy failed! rc=%d\n", rc));
     176            AssertMsgRC(rc, ("RTSemEventDestroy failed! rc=%Rrc\n", rc));
    191177            pThis->WriteEvent = NIL_RTSEMEVENT;
    192178
    193179            RTCritSectLeave(&pThis->CritSect);
    194180            rc = RTCritSectDelete(&pThis->CritSect);
    195             AssertMsgRC(rc, ("RTCritSectDelete failed! rc=%d\n", rc));
     181            AssertMsgRC(rc, ("RTCritSectDelete failed! rc=%Rrc\n", rc));
    196182
    197183            RTMemFree(pThis);
     
    206192    else
    207193    {
    208         AssertMsgRC(rc, ("RTCritSectTryEnter failed! rc=%d\n", rc));
     194        AssertMsgRC(rc, ("RTCritSectTryEnter failed! rc=%Rrc\n", rc));
    209195        rc = VERR_SEM_BUSY;
    210196    }
     
    218204{
    219205    struct RTSEMRWINTERNAL *pThis = RWSem;
    220     /*
    221      * Validate handle.
    222      */
    223     if (!rtsemRWValid(pThis))
    224     {
    225         AssertMsgFailed(("Invalid handle %p!\n", RWSem));
    226         return VERR_INVALID_HANDLE;
    227     }
     206
     207    /*
     208     * Validate handle.
     209     */
     210    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     211    AssertReturn(pThis->u32Magic == RTSEMRW_MAGIC, VERR_INVALID_HANDLE);
    228212
    229213    RTTHREAD    Self = (RTTHREAD)RTThreadNativeSelf();
     
    239223    if (RT_FAILURE(rc))
    240224    {
    241         AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=%d\n", RWSem, rc));
     225        AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=%Rrc\n", RWSem, rc));
    242226        return rc;
    243227    }
     
    250234         * that will break/deadlock reader recursion.
    251235         */
    252         if (!pThis->cWrites)
     236        if (!pThis->cWrites
     237            /** @todo && (   pThis->cReads
     238             *            || !pThis->cWritesWaiting) ?? - making sure not to race waiting
     239             *        writers.  */
     240           )
    253241        {
    254242            pThis->cReads++;
     
    257245            return VINF_SUCCESS;
    258246        }
    259         else if (pThis->Writer == Self)
     247
     248        if (pThis->Writer == Self)
    260249        {
    261250            pThis->cWriterReads++;
     
    283272        if (RT_FAILURE(rc) && rc != VERR_TIMEOUT)
    284273        {
    285             AssertMsgRC(rc, ("RTSemEventMultiWait failed on rwsem %p, rc=%d\n", RWSem, rc));
     274            AssertMsgRC(rc, ("RTSemEventMultiWait failed on rwsem %p, rc=%Rrc\n", RWSem, rc));
    286275            break;
    287276        }
     
    299288        if (RT_FAILURE(rc))
    300289        {
    301             AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=%d\n", RWSem, rc));
     290            AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=%Rrc\n", RWSem, rc));
    302291            break;
    303292        }
     
    319308{
    320309    struct RTSEMRWINTERNAL *pThis = RWSem;
    321     /*
    322      * Validate handle.
    323      */
    324     if (!rtsemRWValid(pThis))
    325     {
    326         AssertMsgFailed(("Invalid handle %p!\n", RWSem));
    327         return VERR_INVALID_HANDLE;
    328     }
     310
     311    /*
     312     * Validate handle.
     313     */
     314    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     315    AssertReturn(pThis->u32Magic == RTSEMRW_MAGIC, VERR_INVALID_HANDLE);
    329316
    330317    RTTHREAD Self = (RTTHREAD)RTThreadNativeSelf();
     
    350337            {
    351338                rc = RTSemEventSignal(pThis->WriteEvent);
    352                 AssertMsgRC(rc, ("Failed to signal writers on rwsem %p, rc=%d\n", RWSem, rc));
     339                AssertMsgRC(rc, ("Failed to signal writers on rwsem %p, rc=%Rrc\n", RWSem, rc));
    353340            }
    354341        }
     
    358345    }
    359346    else
    360         AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=%d\n", RWSem, rc));
     347        AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=%Rrc\n", RWSem, rc));
    361348
    362349    return rc;
     
    368355{
    369356    struct RTSEMRWINTERNAL *pThis = RWSem;
    370     /*
    371      * Validate handle.
    372      */
    373     if (!rtsemRWValid(pThis))
    374     {
    375         AssertMsgFailed(("Invalid handle %p!\n", RWSem));
    376         return VERR_INVALID_HANDLE;
    377     }
     357
     358    /*
     359     * Validate handle.
     360     */
     361    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     362    AssertReturn(pThis->u32Magic == RTSEMRW_MAGIC, VERR_INVALID_HANDLE);
    378363
    379364    RTTHREAD    Self = (RTTHREAD)RTThreadNativeSelf();
    380365    unsigned    cMilliesInitial = cMillies;
    381366    uint64_t    tsStart = 0;
    382     if (cMillies != RT_INDEFINITE_WAIT)
     367    if (cMillies != RT_INDEFINITE_WAIT && cMillies != 0)
    383368        tsStart = RTTimeNanoTS();
    384369
     
    389374    if (RT_FAILURE(rc))
    390375    {
    391         AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=%d\n", RWSem, rc));
     376        AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=%Rrc\n", RWSem, rc));
    392377        return rc;
    393378    }
     
    406391        {
    407392            /*
    408              * Reset the reader event semaphore. For write recursion this
    409              * is redundant, but does not hurt.
     393             * Reset the reader event semaphore if necessary.
    410394             */
    411             rc = RTSemEventMultiReset(pThis->ReadEvent);
    412             AssertMsgRC(rc, ("Failed to reset readers, rwsem %p, rc=%d.\n", RWSem, rc));
     395            if (pThis->fNeedResetReadEvent)
     396            {
     397                pThis->fNeedResetReadEvent = false;
     398                rc = RTSemEventMultiReset(pThis->ReadEvent);
     399                AssertMsgRC(rc, ("Failed to reset readers, rwsem %p, rc=%Rrc.\n", RWSem, rc));
     400            }
    413401
    414402            pThis->cWrites++;
     
    425413         * Wait till it's ready for writing.
    426414         */
    427         if (cMillies != RT_INDEFINITE_WAIT)
     415        if (cMillies != RT_INDEFINITE_WAIT && cMillies != 0)
    428416        {
    429417            int64_t tsDelta = RTTimeNanoTS() - tsStart;
     
    436424        }
    437425        rc = RTSemEventWait(pThis->WriteEvent, cMillies);
    438         if (RT_FAILURE(rc) && rc != VERR_TIMEOUT)
    439         {
    440             AssertMsgRC(rc, ("RTSemEventWait failed on rwsem %p, rc=%d\n", RWSem, rc));
     426        if (RT_UNLIKELY(RT_FAILURE_NP(rc) && rc != VERR_TIMEOUT))
     427        {
     428            AssertMsgRC(rc, ("RTSemEventWait failed on rwsem %p, rc=%Rrc\n", RWSem, rc));
    441429            break;
    442430        }
    443431
    444         if (pThis->u32Magic != RTSEMRW_MAGIC)
     432        if (RT_UNLIKELY(pThis->u32Magic != RTSEMRW_MAGIC))
    445433        {
    446434            rc = VERR_SEM_DESTROYED;
     
    454442        if (RT_FAILURE(rc))
    455443        {
    456             AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=%d\n", RWSem, rc));
     444            AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=%Rrc\n", RWSem, rc));
    457445            break;
    458446        }
     
    485473{
    486474    struct RTSEMRWINTERNAL *pThis = RWSem;
    487     /*
    488      * Validate handle.
    489      */
    490     if (!rtsemRWValid(pThis))
    491     {
    492         AssertMsgFailed(("Invalid handle %p!\n", RWSem));
    493         return VERR_INVALID_HANDLE;
    494     }
     475
     476    /*
     477     * Validate handle.
     478     */
     479    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     480    AssertReturn(pThis->u32Magic == RTSEMRW_MAGIC, VERR_INVALID_HANDLE);
    495481
    496482    RTTHREAD Self = (RTTHREAD)RTThreadNativeSelf();
     
    502488    if (RT_FAILURE(rc))
    503489    {
    504         AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=%d\n", RWSem, rc));
     490        AssertMsgFailed(("RTCritSectEnter failed on rwsem %p, rc=%Rrc\n", RWSem, rc));
    505491        return rc;
    506492    }
     
    530516    {
    531517        rc = RTSemEventMultiSignal(pThis->ReadEvent);
    532         AssertMsgRC(rc, ("RTSemEventMultiSignal failed for rwsem %p, rc=%d.\n", RWSem, rc));
     518        AssertMsgRC(rc, ("RTSemEventMultiSignal failed for rwsem %p, rc=%Rrc.\n", RWSem, rc));
     519        pThis->fNeedResetReadEvent = true;
    533520    }
    534521    else
    535522    {
    536523        rc = RTSemEventSignal(pThis->WriteEvent);
    537         AssertMsgRC(rc, ("Failed to signal writers on rwsem %p, rc=%d\n", RWSem, rc));
     524        AssertMsgRC(rc, ("Failed to signal writers on rwsem %p, rc=%Rrc\n", RWSem, rc));
    538525    }
    539526    RTCritSectLeave(&pThis->CritSect);
     
    547534{
    548535    struct RTSEMRWINTERNAL *pThis = RWSem;
    549     /*
    550      * Validate handle.
    551      */
    552     if (!rtsemRWValid(pThis))
    553     {
    554         AssertMsgFailed(("Invalid handle %p!\n", RWSem));
    555         return false;
    556     }
     536
     537    /*
     538     * Validate handle.
     539     */
     540    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     541    AssertReturn(pThis->u32Magic == RTSEMRW_MAGIC, VERR_INVALID_HANDLE);
    557542
    558543    /*
     
    570555{
    571556    struct RTSEMRWINTERNAL *pThis = RWSem;
    572     /*
    573      * Validate handle.
    574      */
    575     if (!rtsemRWValid(pThis))
    576     {
    577         AssertMsgFailed(("Invalid handle %p!\n", RWSem));
    578         return 0;
    579     }
     557
     558    /*
     559     * Validate handle.
     560     */
     561    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     562    AssertReturn(pThis->u32Magic == RTSEMRW_MAGIC, VERR_INVALID_HANDLE);
    580563
    581564    /*
     
    590573{
    591574    struct RTSEMRWINTERNAL *pThis = RWSem;
    592     /*
    593      * Validate handle.
    594      */
    595     if (!rtsemRWValid(pThis))
    596     {
    597         AssertMsgFailed(("Invalid handle %p!\n", RWSem));
    598         return 0;
    599     }
     575
     576    /*
     577     * Validate handle.
     578     */
     579    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     580    AssertReturn(pThis->u32Magic == RTSEMRW_MAGIC, VERR_INVALID_HANDLE);
    600581
    601582    /*
Note: See TracChangeset for help on using the changeset viewer.

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