VirtualBox

Changeset 25373 in vbox for trunk/src


Ignore:
Timestamp:
Dec 14, 2009 7:20:27 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
55992
Message:

IPRT,PDMCritSect: More validation changes. Validate posix and linux mutexes. Always update the thread state with critsects.

Location:
trunk/src/VBox
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/misc/lockvalidator.cpp

    r25369 r25373  
    133133
    134134
    135 RTDECL(void) RTLockValidatorSetOwner(PRTLOCKVALIDATORREC pRec, RTTHREAD hThread, RTHCUINTPTR uId, RT_SRC_POS_DECL)
     135RTDECL(RTTHREAD) RTLockValidatorSetOwner(PRTLOCKVALIDATORREC pRec, RTTHREAD hThread, RTHCUINTPTR uId, RT_SRC_POS_DECL)
    136136{
    137     AssertReturnVoid(pRec->u32Magic == RTLOCKVALIDATORREC_MAGIC);
     137    AssertReturn(pRec->u32Magic == RTLOCKVALIDATORREC_MAGIC, NIL_RTTHREAD);
    138138    Assert(pRec->hThread == NIL_RTTHREAD);
    139139
     
    147147
    148148    if (hThread == NIL_RTTHREAD)
    149     {
     149#ifdef IN_RING3
     150        hThread = RTThreadSelfAutoAdopt();
     151#else
    150152        hThread = RTThreadSelf();
    151 #ifdef IN_RING3
    152         if (RT_UNLIKELY(hThread == NIL_RTTHREAD))
    153             RTThreadAdopt(RTTHREADTYPE_DEFAULT, 0, NULL, &hThread);
    154153#endif
    155     }
    156154    ASMAtomicWriteHandle(&pRec->hThread, hThread);
    157155
     
    160158     */
    161159    /** @todo push it onto the per-thread lock stack. */
     160
     161    return hThread;
    162162}
    163163
    164164
    165 RTDECL(void) RTLockValidatorUnsetOwner(PRTLOCKVALIDATORREC pRec)
     165RTDECL(RTTHREAD) RTLockValidatorUnsetOwner(PRTLOCKVALIDATORREC pRec)
    166166{
    167     AssertReturnVoid(pRec->u32Magic == RTLOCKVALIDATORREC_MAGIC);
    168     Assert(pRec->hThread != NIL_RTTHREAD);
     167    AssertReturn(pRec->u32Magic == RTLOCKVALIDATORREC_MAGIC, NIL_RTTHREAD);
     168    RTTHREAD hThread = pRec->hThread;
     169    AssertReturn(hThread != NIL_RTTHREAD, hThread);
    169170
    170171    /*
     
    177178     */
    178179    ASMAtomicWriteHandle(&pRec->hThread, NIL_RTTHREAD);
     180
     181    return hThread;
    179182}
    180183
  • trunk/src/VBox/Runtime/common/misc/thread.cpp

    r25368 r25373  
    332332}
    333333RT_EXPORT_SYMBOL(RTThreadAdopt);
     334
     335
     336/**
     337 * Get the thread handle of the current thread, automatically adopting alien
     338 * threads.
     339 *
     340 * @returns Thread handle.
     341 */
     342RTDECL(RTTHREAD) RTThreadSelfAutoAdopt(void)
     343{
     344    RTTHREAD hSelf = RTThreadSelf();
     345    if (RT_UNLIKELY(hSelf == NIL_RTTHREAD))
     346        RTThreadAdopt(RTTHREADTYPE_DEFAULT, 0, NULL, &hSelf);
     347    return hSelf;
     348}
     349RT_EXPORT_SYMBOL(RTThreadSelfAutoAdopt);
    334350
    335351
     
    12371253{
    12381254    PRTTHREADINT pThread = rtThreadGet(Thread);
    1239     Assert(pThread);
     1255    AssertReturnVoid(pThread);
    12401256    ASMAtomicIncS32(&pThread->cWriteLocks);
    12411257    rtThreadRelease(pThread);
     
    12521268{
    12531269    PRTTHREADINT pThread = rtThreadGet(Thread);
    1254     Assert(pThread);
     1270    AssertReturnVoid(pThread);
    12551271    ASMAtomicDecS32(&pThread->cWriteLocks);
    12561272    rtThreadRelease(pThread);
     
    15431559
    15441560{
     1561    Assert(RTTHREAD_IS_SLEEPING(enmState));
     1562
     1563    /*
     1564     * Fend off wild life.
     1565     */
    15451566    PRTTHREADINT pThread = hThread;
    1546     Assert(RTTHREAD_IS_SLEEPING(enmState));
    1547     if (pThread && rtThreadGetState(pThread) == RTTHREADSTATE_RUNNING)
    1548     {
     1567    if (!pThread)
     1568        return;
     1569    if (rtThreadGetState(pThread) != RTTHREADSTATE_RUNNING)
     1570        return;
     1571
     1572    if (!pValidatorRec)
     1573        /*
     1574         * If no validator record, just update the thread state.
     1575         */
     1576        rtThreadSetState(pThread, enmState);
     1577    else
     1578    {
     1579        /*
     1580         * Record the location and everything before changing the state and
     1581         * performing deadlock detection.
     1582         */
    15491583        /** @todo This has to be serialized! The deadlock detection isn't 100% safe!!! */
    15501584        pThread->Block.pRec         = pValidatorRec;
  • trunk/src/VBox/Runtime/generic/critsect-generic.cpp

    r25368 r25373  
    244244    ASMAtomicWriteHandle(&pCritSect->NativeThreadOwner, NativeThreadSelf);
    245245#ifdef RTCRITSECT_STRICT
    246     RTLockValidatorSetOwner(pCritSect->pValidatorRec, ThreadSelf, uId, RT_SRC_POS_ARGS);
     246    RTThreadWriteLockInc(RTLockValidatorSetOwner(pCritSect->pValidatorRec, ThreadSelf, uId, RT_SRC_POS_ARGS));
    247247#endif
    248248
     
    283283    RTNATIVETHREAD  NativeThreadSelf = RTThreadNativeSelf();
    284284#ifdef RTCRITSECT_STRICT
    285     RTTHREAD        ThreadSelf = RTThreadSelf();
    286     if (ThreadSelf == NIL_RTTHREAD)
    287         RTThreadAdopt(RTTHREADTYPE_DEFAULT, 0, NULL, &ThreadSelf);
    288     RTLockValidatorCheckOrder(pCritSect->pValidatorRec, ThreadSelf, uId, RT_SRC_POS_ARGS);
     285    RTTHREAD        hThreadSelf = RTThreadSelfAutoAdopt();
     286    RTLockValidatorCheckOrder(pCritSect->pValidatorRec, hThreadSelf, uId, RT_SRC_POS_ARGS);
    289287#endif
    290288
     
    315313        }
    316314
     315        /*
     316         * Wait for the current owner to release it.
     317         */
     318#ifndef RTCRITSECT_STRICT
     319        RTTHREAD hThreadSelf = RTThreadSelf();
     320#endif
    317321        for (;;)
    318322        {
    319 #ifdef RTCRITSECT_STRICT
    320             RTThreadBlocking(ThreadSelf, RTTHREADSTATE_CRITSECT, pCritSect->pValidatorRec, uId, RT_SRC_POS_ARGS);
    321 #endif
     323            RTThreadBlocking(hThreadSelf, RTTHREADSTATE_CRITSECT, RTCRITSECT_STRICT_BLOCK_ARGS(pCritSect->pValidatorRec));
    322324            int rc = RTSemEventWait(pCritSect->EventSem, RT_INDEFINITE_WAIT);
    323 #ifdef RTCRITSECT_STRICT
    324             RTThreadUnblocked(ThreadSelf, RTTHREADSTATE_CRITSECT);
    325 #endif
     325            RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_CRITSECT);
    326326            if (pCritSect->u32Magic != RTCRITSECT_MAGIC)
    327327                return VERR_SEM_DESTROYED;
     
    339339    ASMAtomicWriteHandle(&pCritSect->NativeThreadOwner, NativeThreadSelf);
    340340#ifdef RTCRITSECT_STRICT
    341     RTLockValidatorSetOwner(pCritSect->pValidatorRec, ThreadSelf, uId, RT_SRC_POS_ARGS);
    342     RTThreadWriteLockInc(ThreadSelf);
     341    RTThreadWriteLockInc(RTLockValidatorSetOwner(pCritSect->pValidatorRec, hThreadSelf, uId, RT_SRC_POS_ARGS));
    343342#endif
    344343
     
    393392         */
    394393#ifdef RTCRITSECT_STRICT
    395         RTLockValidatorUnsetOwner(pCritSect->pValidatorRec);
     394        RTThreadWriteLockInc(RTLockValidatorUnsetOwner(pCritSect->pValidatorRec));
    396395#endif
    397396        ASMAtomicWriteHandle(&pCritSect->NativeThreadOwner, NIL_RTNATIVETHREAD);
  • trunk/src/VBox/Runtime/generic/semnoint-generic.cpp

    r21337 r25373  
    126126RT_EXPORT_SYMBOL(RTSemMutexRequest);
    127127
     128
     129RTDECL(int) RTSemMutexRequestDebug(RTSEMMUTEX Mutex, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
     130{
     131    int rc;
     132    if (cMillies == RT_INDEFINITE_WAIT)
     133    {
     134        do rc = RTSemMutexRequestNoResumeDebug(Mutex, cMillies, uId, RT_SRC_POS_ARGS);
     135        while (rc == VERR_INTERRUPTED);
     136    }
     137    else
     138    {
     139        const uint64_t u64Start = RTTimeMilliTS();
     140        rc = RTSemMutexRequestNoResumeDebug(Mutex, cMillies, uId, RT_SRC_POS_ARGS);
     141        if (rc == VERR_INTERRUPTED)
     142        {
     143            do
     144            {
     145                uint64_t u64Elapsed = RTTimeMilliTS() - u64Start;
     146                if (u64Elapsed >= cMillies)
     147                    return VERR_TIMEOUT;
     148                rc = RTSemMutexRequestNoResumeDebug(Mutex, cMillies - (unsigned)u64Elapsed, uId, RT_SRC_POS_ARGS);
     149            } while (rc == VERR_INTERRUPTED);
     150        }
     151    }
     152    return rc;
     153}
     154RT_EXPORT_SYMBOL(RTSemMutexRequestDebug);
     155
  • trunk/src/VBox/Runtime/include/internal/strict.h

    r8651 r25373  
    4242#endif
    4343
     44#ifdef RTCRITSECT_STRICT
     45# define RTCRITSECT_STRICT_POS_DECL         RTHCUINTPTR uId, RT_SRC_POS_DECL
     46# define RTCRITSECT_STRICT_POS_ARGS         uId, RT_SRC_POS_ARGS
     47# define RTCRITSECT_STRICT_BLOCK_ARGS(pRec) pRec,     uId, RT_SRC_POS_ARGS
     48#else
     49# define RTCRITSECT_STRICT_POS_DECL         int iDummy
     50# define RTCRITSECT_STRICT_POS_ARGS         0
     51# define RTCRITSECT_STRICT_BLOCK_ARGS(pRec) NULL, 0, NULL, 0, NULL
     52#endif
     53
     54
    4455/** @def RTSEMMUTEX_STRICT
    4556 * Enables strictness checks and lock accounting of the RTSemMutex API.
     
    4859# define RTSEMMUTEX_STRICT
    4960#endif
     61
     62#ifdef RTSEMMUTEX_STRICT
     63# define RTSEMMUTEX_STRICT_POS_DECL         RTHCUINTPTR uId, RT_SRC_POS_DECL
     64# define RTSEMMUTEX_STRICT_POS_ARGS         uId, RT_SRC_POS_ARGS
     65# define RTSEMMUTEX_STRICT_BLOCK_ARGS(pRec) pRec,     uId, RT_SRC_POS_ARGS
     66#else
     67# define RTSEMMUTEX_STRICT_POS_DECL         int iDummy
     68# define RTSEMMUTEX_STRICT_POS_ARGS         0
     69# define RTSEMMUTEX_STRICT_BLOCK_ARGS(pRec) NULL, 0, NULL, 0, NULL
     70#endif
     71
    5072
    5173/** @def RTSEMRW_STRICT
     
    5678#endif
    5779
     80#ifdef RTSEMRW_STRICT
     81# define RTSEMRW_STRICT_POS_DECL            RTHCUINTPTR uId, RT_SRC_POS_DECL
     82# define RTSEMRW_STRICT_POS_ARGS            uId, RT_SRC_POS_ARGS
     83# define RTSEMRW_STRICT_BLOCK_ARGS(pRec)    pRec, uId, RT_SRC_POS_ARGS
     84#else
     85# define RTSEMRW_STRICT_POS_DECL            int iDummy
     86# define RTSEMRW_STRICT_POS_ARGS            0
     87# define RTSEMRW_STRICT_BLOCK_ARGS(pRec)    NULL, 0, NULL, 0, NULL
     88#endif
     89
     90
    5891
    5992/** @} */
  • trunk/src/VBox/Runtime/r0drv/nt/semmutex-r0drv-nt.cpp

    r8245 r25373  
    160160
    161161
     162RTDECL(int)  RTSemMutexRequestDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
     163{
     164    return RTSemMutexRequest(MutexSem, cMillies);
     165}
     166
     167/** @todo implement the NoResume versions */
     168
    162169RTDECL(int)  RTSemMutexRelease(RTSEMMUTEX MutexSem)
    163170{
  • trunk/src/VBox/Runtime/r3/linux/semmutex-linux.cpp

    r22959 r25373  
    3333*******************************************************************************/
    3434#include <iprt/semaphore.h>
     35#include "internal/iprt.h"
     36
     37#include <iprt/alloc.h>
     38#include <iprt/asm.h>
    3539#include <iprt/assert.h>
    36 #include <iprt/alloc.h>
     40#include <iprt/err.h>
     41#include <iprt/lockvalidator.h>
    3742#include <iprt/thread.h>
    38 #include <iprt/asm.h>
    39 #include <iprt/err.h>
    4043#include <iprt/time.h>
    4144#include "internal/magics.h"
     
    7477    /** The owner of the mutex. */
    7578    pthread_t volatile  Owner;
    76     /** Magic value. */
    77     intptr_t volatile   iMagic;
     79    /** Magic value (RTSEMMUTEX_MAGIC). */
     80    uint32_t  volatile  u32Magic;
     81#ifdef RTSEMMUTEX_STRICT
     82    /** Lock validator record associated with this mutex. */
     83    RTLOCKVALIDATORREC  ValidatorRec;
     84#endif
    7885};
    7986
     
    103110    if (pThis)
    104111    {
    105         pThis->iMagic  = RTSEMMUTEX_MAGIC;
     112        pThis->u32Magic = RTSEMMUTEX_MAGIC;
    106113        pThis->iState   = 0;
    107114        pThis->Owner    = (pthread_t)~0;
    108115        pThis->cNesting = 0;
     116#ifdef RTSEMMUTEX_STRICT
     117        RTLockValidatorInit(&pThis->ValidatorRec, NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, NULL, pThis);
     118#endif
    109119
    110120        *pMutexSem = pThis;
     
    122132     */
    123133    if (MutexSem == NIL_RTSEMMUTEX)
    124         return VERR_INVALID_HANDLE;
     134        return VINF_SUCCESS;
    125135    struct RTSEMMUTEXINTERNAL *pThis = MutexSem;
    126136    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    127     AssertMsgReturn(pThis->iMagic == RTSEMMUTEX_MAGIC,
    128                     ("MutexSem=%p iMagic=%#x\n", pThis, pThis->iMagic),
     137    AssertMsgReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC,
     138                    ("MutexSem=%p u32Magic=%#x\n", pThis, pThis->u32Magic),
    129139                    VERR_INVALID_HANDLE);
    130140
     
    132142     * Invalidate the semaphore and wake up anyone waiting on it.
    133143     */
    134     ASMAtomicXchgSize(&pThis->iMagic, RTSEMMUTEX_MAGIC + 1);
     144    ASMAtomicWriteU32(&pThis->u32Magic, RTSEMMUTEX_MAGIC_DEAD);
    135145    if (ASMAtomicXchgS32(&pThis->iState, 0) > 0)
    136146    {
     
    140150    pThis->Owner    = (pthread_t)~0;
    141151    pThis->cNesting = 0;
     152#ifdef RTSEMMUTEX_STRICT
     153    RTLockValidatorDelete(&pThis->ValidatorRec);
     154#endif
    142155
    143156    /*
     
    149162
    150163
    151 static int rtsemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies, bool fAutoResume)
     164DECL_FORCE_INLINE(int) rtSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies, bool fAutoResume, RTSEMMUTEX_STRICT_POS_DECL)
    152165{
    153166    /*
     
    155168     */
    156169    struct RTSEMMUTEXINTERNAL *pThis = MutexSem;
    157     AssertReturn(VALID_PTR(pThis) && pThis->iMagic == RTSEMMUTEX_MAGIC,
    158                  VERR_INVALID_HANDLE);
     170    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     171    AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
     172
     173#ifdef RTSEMMUTEX_STRICT
     174    RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
     175    RTLockValidatorCheckOrder(&pThis->ValidatorRec, hThreadSelf, RTSEMMUTEX_STRICT_POS_ARGS);
     176#endif
    159177
    160178    /*
     
    165183        &&  pThis->cNesting > 0)
    166184    {
    167         pThis->cNesting++;
     185        ASMAtomicIncU32(&pThis->cNesting);
    168186        return VINF_SUCCESS;
    169187    }
     188#ifndef RTSEMMUTEX_STRICT
     189    RTTHREAD hThreadSelf = RTThreadSelf();
     190#endif
    170191
    171192    /*
     
    202223             * Go to sleep.
    203224             */
     225            if (pTimeout && ( pTimeout->tv_sec || pTimeout->tv_nsec ))
     226                RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX, RTSEMMUTEX_STRICT_BLOCK_ARGS(&pThis->ValidatorRec));
    204227            long rc = sys_futex(&pThis->iState, FUTEX_WAIT, 2, pTimeout, NULL, 0);
    205             if (RT_UNLIKELY(pThis->iMagic != RTSEMMUTEX_MAGIC))
     228            RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_MUTEX);
     229            if (RT_UNLIKELY(pThis->u32Magic != RTSEMMUTEX_MAGIC))
    206230                return VERR_SEM_DESTROYED;
    207231
     
    258282     */
    259283    pThis->Owner = Self;
    260     ASMAtomicXchgU32(&pThis->cNesting, 1);
    261 #ifdef RTSEMMUTEX_STRICT
    262     RTTHREAD Thread = RTThreadSelf();
    263     if (Thread != NIL_RTTHREAD)
    264         RTThreadWriteLockInc(Thread);
     284    ASMAtomicWriteU32(&pThis->cNesting, 1);
     285#ifdef RTSEMMUTEX_STRICT
     286    RTThreadWriteLockInc(RTLockValidatorSetOwner(&pThis->ValidatorRec, hThreadSelf, RTSEMMUTEX_STRICT_POS_ARGS));
    265287#endif
    266288    return VINF_SUCCESS;
     
    268290
    269291
    270 RTDECL(int)  RTSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies)
    271 {
    272     int rc = rtsemMutexRequest(MutexSem, cMillies, true);
     292RTDECL(int) RTSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies)
     293{
     294#ifndef RTSEMMUTEX_STRICT
     295    int rc = rtSemMutexRequest(MutexSem, cMillies, true, RTSEMMUTEX_STRICT_POS_ARGS);
    273296    Assert(rc != VERR_INTERRUPTED);
    274297    return rc;
    275 }
    276 
    277 
    278 RTDECL(int)  RTSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies)
    279 {
    280     return rtsemMutexRequest(MutexSem, cMillies, false);
    281 }
    282 
    283 
    284 RTDECL(int)  RTSemMutexRelease(RTSEMMUTEX MutexSem)
     298#else
     299    return RTSemMutexRequestDebug(MutexSem, cMillies, (uintptr_t)ASMReturnAddress(), RT_SRC_POS);
     300#endif
     301}
     302
     303
     304RTDECL(int) RTSemMutexRequestDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
     305{
     306#ifdef RTSEMMUTEX_STRICT
     307    int rc = rtSemMutexRequest(MutexSem, cMillies, true, RTSEMMUTEX_STRICT_POS_ARGS);
     308    Assert(rc != VERR_INTERRUPTED);
     309    return rc;
     310#else
     311    return RTSemMutexRequest(MutexSem, cMillies);
     312#endif
     313}
     314
     315
     316RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies)
     317{
     318#ifndef RTSEMMUTEX_STRICT
     319    return rtSemMutexRequest(MutexSem, cMillies, false, RTSEMMUTEX_STRICT_POS_ARGS);
     320#else
     321    return RTSemMutexRequestNoResumeDebug(MutexSem, cMillies, (uintptr_t)ASMReturnAddress(), RT_SRC_POS);
     322#endif
     323}
     324
     325
     326RTDECL(int) RTSemMutexRequestNoResumeDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
     327{
     328#ifdef RTSEMMUTEX_STRICT
     329    return rtSemMutexRequest(MutexSem, cMillies, false, RTSEMMUTEX_STRICT_POS_ARGS);
     330#else
     331    return RTSemMutexRequest(MutexSem, cMillies);
     332#endif
     333}
     334
     335
     336RTDECL(int) RTSemMutexRelease(RTSEMMUTEX MutexSem)
    285337{
    286338    /*
     
    288340     */
    289341    struct RTSEMMUTEXINTERNAL *pThis = MutexSem;
    290     AssertReturn(VALID_PTR(pThis) && pThis->iMagic == RTSEMMUTEX_MAGIC,
    291                 VERR_INVALID_HANDLE);
     342    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     343    AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
    292344
    293345    /*
     
    308360    if (pThis->cNesting > 1)
    309361    {
    310         pThis->cNesting--;
     362        ASMAtomicDecU32(&pThis->cNesting);
    311363        return VINF_SUCCESS;
    312364    }
     
    316368     */
    317369#ifdef RTSEMMUTEX_STRICT
    318     RTTHREAD Thread = RTThreadSelf();
    319     if (Thread != NIL_RTTHREAD)
    320         RTThreadWriteLockDec(Thread);
     370    RTThreadWriteLockDec(RTLockValidatorUnsetOwner(&pThis->ValidatorRec));
    321371#endif
    322372    pThis->Owner = (pthread_t)~0;
    323     ASMAtomicXchgU32(&pThis->cNesting, 0);
     373    ASMAtomicWriteU32(&pThis->cNesting, 0);
    324374
    325375    /*
  • trunk/src/VBox/Runtime/r3/posix/semmutex-posix.cpp

    r8651 r25373  
    3333*******************************************************************************/
    3434#include <iprt/semaphore.h>
     35#include "internal/iprt.h"
     36
     37#include <iprt/alloc.h>
     38#include <iprt/asm.h>
    3539#include <iprt/assert.h>
    36 #include <iprt/alloc.h>
     40#include <iprt/err.h>
     41#include <iprt/lockvalidator.h>
    3742#include <iprt/thread.h>
    38 #include <iprt/asm.h>
    39 #include <iprt/err.h>
     43#include "internal/magics.h"
    4044#include "internal/strict.h"
    4145
     
    5862    /** Nesting count. */
    5963    volatile uint32_t   cNesting;
     64    /** Magic value (RTSEMMUTEX_MAGIC). */
     65    uint32_t            u32Magic;
     66#ifdef RTSEMMUTEX_STRICT
     67    /** Lock validator record associated with this mutex. */
     68    RTLOCKVALIDATORREC  ValidatorRec;
     69#endif
    6070};
    6171
    6272
    6373
    64 /**
    65  * Validate a Mutex semaphore handle passed to one of the interface.
    66  *
    67  * @returns true if valid.
    68  * @returns false if invalid.
    69  * @param   pIntMutexSem    Pointer to the mutex semaphore to validate.
    70  */
    71 DECLINLINE(bool) rtsemMutexValid(struct RTSEMMUTEXINTERNAL *pIntMutexSem)
    72 {
    73     if ((uintptr_t)pIntMutexSem < 0x10000)
    74         return false;
    75 
    76     if (pIntMutexSem->cNesting == (uint32_t)~0)
    77         return false;
    78 
    79     return true;
    80 }
    81 
    82 
    8374RTDECL(int)  RTSemMutexCreate(PRTSEMMUTEX pMutexSem)
    8475{
     
    8879     * Allocate semaphore handle.
    8980     */
    90     struct RTSEMMUTEXINTERNAL *pIntMutexSem = (struct RTSEMMUTEXINTERNAL *)RTMemAlloc(sizeof(struct RTSEMMUTEXINTERNAL));
    91     if (pIntMutexSem)
     81    struct RTSEMMUTEXINTERNAL *pThis = (struct RTSEMMUTEXINTERNAL *)RTMemAlloc(sizeof(struct RTSEMMUTEXINTERNAL));
     82    if (pThis)
    9283    {
    9384        /*
     
    9889        if (!rc)
    9990        {
    100             rc = pthread_mutex_init(&pIntMutexSem->Mutex, &MutexAttr);
     91            rc = pthread_mutex_init(&pThis->Mutex, &MutexAttr);
    10192            if (!rc)
    10293            {
    10394                pthread_mutexattr_destroy(&MutexAttr);
    10495
    105                 pIntMutexSem->Owner    = (pthread_t)-1;
    106                 pIntMutexSem->cNesting = 0;
    107 
    108                 *pMutexSem = pIntMutexSem;
     96                pThis->Owner    = (pthread_t)-1;
     97                pThis->cNesting = 0;
     98                pThis->u32Magic = RTSEMMUTEX_MAGIC;
     99#ifdef RTSEMMUTEX_STRICT
     100                RTLockValidatorInit(&pThis->ValidatorRec, NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, NULL, pThis);
     101#endif
     102
     103                *pMutexSem = pThis;
    109104                return VINF_SUCCESS;
    110105            }
    111106            pthread_mutexattr_destroy(&MutexAttr);
    112107        }
    113         RTMemFree(pIntMutexSem);
     108        RTMemFree(pThis);
    114109    }
    115110    else
     
    125120     * Validate input.
    126121     */
    127     if (!rtsemMutexValid(MutexSem))
    128     {
    129         AssertMsgFailed(("Invalid handle %p!\n", MutexSem));
    130         return VERR_INVALID_HANDLE;
    131     }
     122    if (MutexSem == NIL_RTSEMMUTEX)
     123        return VINF_SUCCESS;
     124    struct RTSEMMUTEXINTERNAL *pThis = MutexSem;
     125    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     126    AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
    132127
    133128    /*
    134129     * Try destroy it.
    135130     */
    136     struct RTSEMMUTEXINTERNAL *pIntMutexSem = MutexSem;
    137     int rc = pthread_mutex_destroy(&pIntMutexSem->Mutex);
     131    int rc = pthread_mutex_destroy(&pThis->Mutex);
    138132    if (rc)
    139133    {
     
    145139     * Free the memory and be gone.
    146140     */
    147     pIntMutexSem->Owner    = (pthread_t)-1;
    148     pIntMutexSem->cNesting = ~0;
    149     RTMemTmpFree(pIntMutexSem);
     141    ASMAtomicWriteU32(&pThis->u32Magic, RTSEMMUTEX_MAGIC_DEAD);
     142    pThis->Owner    = (pthread_t)-1;
     143    pThis->cNesting = UINT32_MAX;
     144#ifdef RTSEMMUTEX_STRICT
     145    RTLockValidatorDelete(&pThis->ValidatorRec);
     146#endif
     147    RTMemTmpFree(pThis);
    150148
    151149    return VINF_SUCCESS;
     
    153151
    154152
    155 RTDECL(int)  RTSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies)
     153DECL_FORCE_INLINE(int) rtSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies, RTSEMMUTEX_STRICT_POS_DECL)
    156154{
    157155    /*
    158156     * Validate input.
    159157     */
    160     if (!rtsemMutexValid(MutexSem))
    161     {
    162         AssertMsgFailed(("Invalid handle %p!\n", MutexSem));
    163         return VERR_INVALID_HANDLE;
    164     }
     158    struct RTSEMMUTEXINTERNAL *pThis = MutexSem;
     159    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     160    AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
     161
     162#ifdef RTSEMMUTEX_STRICT
     163    RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
     164    RTLockValidatorCheckOrder(&pThis->ValidatorRec, hThreadSelf, RTSEMMUTEX_STRICT_POS_ARGS);
     165#endif
    165166
    166167    /*
    167168     * Check if nested request.
    168169     */
    169     pthread_t                     Self = pthread_self();
    170     struct RTSEMMUTEXINTERNAL    *pIntMutexSem = MutexSem;
    171     if (    pIntMutexSem->Owner == Self
    172         &&  pIntMutexSem->cNesting > 0)
    173     {
    174         pIntMutexSem->cNesting++;
     170    pthread_t Self = pthread_self();
     171    if (    pThis->Owner == Self
     172        &&  pThis->cNesting > 0)
     173    {
     174        ASMAtomicIncU32(&pThis->cNesting);
    175175        return VINF_SUCCESS;
    176176    }
     177#ifndef RTSEMMUTEX_STRICT
     178    RTTHREAD hThreadSelf = RTThreadSelf();
     179#endif
    177180
    178181    /*
     
    182185    {
    183186        /* take mutex */
    184         int rc = pthread_mutex_lock(&pIntMutexSem->Mutex);
     187        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX, RTSEMMUTEX_STRICT_BLOCK_ARGS(&pThis->ValidatorRec));
     188        int rc = pthread_mutex_lock(&pThis->Mutex);
     189        RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_MUTEX);
    185190        if (rc)
    186191        {
     
    209214                ts.tv_sec++;
    210215            }
     216            RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX, RTSEMMUTEX_STRICT_BLOCK_ARGS(&pThis->ValidatorRec));
    211217        }
    212218
    213219        /* take mutex */
    214         int rc = pthread_mutex_timedlock(&pIntMutexSem->Mutex, &ts);
     220        int rc = pthread_mutex_timedlock(&pThis->Mutex, &ts);
     221        RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_MUTEX);
    215222        if (rc)
    216223        {
     
    224231     * Set the owner and nesting.
    225232     */
    226     pIntMutexSem->Owner = Self;
    227     ASMAtomicXchgU32(&pIntMutexSem->cNesting, 1);
    228 #ifdef RTSEMMUTEX_STRICT
    229     RTTHREAD Thread = RTThreadSelf();
    230     if (Thread != NIL_RTTHREAD)
    231         RTThreadWriteLockInc(Thread);
     233    pThis->Owner = Self;
     234    ASMAtomicWriteU32(&pThis->cNesting, 1);
     235#ifdef RTSEMMUTEX_STRICT
     236    RTThreadWriteLockInc(RTLockValidatorSetOwner(&pThis->ValidatorRec, hThreadSelf, RTSEMMUTEX_STRICT_POS_ARGS));
    232237#endif
    233238
     
    236241
    237242
    238 RTDECL(int)  RTSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies)
     243RTDECL(int) RTSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies)
     244{
     245#ifndef RTSEMMUTEX_STRICT
     246    return rtSemMutexRequest(MutexSem, cMillies, RTSEMMUTEX_STRICT_POS_ARGS);
     247#else
     248    return RTSemMutexRequestDebug(MutexSem, cMillies, (uintptr_t)ASMReturnAddress(), RT_SRC_POS);
     249#endif
     250}
     251
     252
     253RTDECL(int) RTSemMutexRequestDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
     254{
     255#ifdef RTSEMMUTEX_STRICT
     256    return rtSemMutexRequest(MutexSem, cMillies, RTSEMMUTEX_STRICT_POS_ARGS);
     257#else
     258    return RTSemMutexRequest(MutexSem, cMillies);
     259#endif
     260}
     261
     262
     263RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies)
    239264{
    240265    /* EINTR isn't returned by the wait functions we're using. */
     266#ifndef RTSEMMUTEX_STRICT
    241267    return RTSemMutexRequest(MutexSem, cMillies);
     268#else
     269    return RTSemMutexRequestDebug(MutexSem, cMillies, (uintptr_t)ASMReturnAddress(), RT_SRC_POS);
     270#endif
     271}
     272
     273
     274RTDECL(int) RTSemMutexRequestNoResumeDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
     275{
     276    /* EINTR isn't returned by the wait functions we're using. */
     277#ifdef RTSEMMUTEX_STRICT
     278    return RTSemMutexRequestDebug(MutexSem, cMillies, RTSEMMUTEX_STRICT_POS_ARGS);
     279#else
     280    return RTSemMutexRequest(MutexSem, cMillies);
     281#endif
    242282}
    243283
     
    248288     * Validate input.
    249289     */
    250     if (!rtsemMutexValid(MutexSem))
    251     {
    252         AssertMsgFailed(("Invalid handle %p!\n", MutexSem));
    253         return VERR_INVALID_HANDLE;
    254     }
     290    struct RTSEMMUTEXINTERNAL *pThis = MutexSem;
     291    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     292    AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
    255293
    256294    /*
    257295     * Check if nested.
    258296     */
    259     pthread_t                     Self = pthread_self();
    260     struct RTSEMMUTEXINTERNAL    *pIntMutexSem = MutexSem;
    261     if (    pIntMutexSem->Owner != Self
    262         ||  pIntMutexSem->cNesting == (uint32_t)~0)
     297    pthread_t Self = pthread_self();
     298    if (RT_UNLIKELY(    pThis->Owner != Self
     299                    ||  pThis->cNesting == 0))
    263300    {
    264301        AssertMsgFailed(("Not owner of mutex %p!! Self=%08x Owner=%08x cNesting=%d\n",
    265                          pIntMutexSem, Self, pIntMutexSem->Owner, pIntMutexSem->cNesting));
     302                         pThis, Self, pThis->Owner, pThis->cNesting));
    266303        return VERR_NOT_OWNER;
    267304    }
     
    270307     * If nested we'll just pop a nesting.
    271308     */
    272     if (pIntMutexSem->cNesting > 1)
    273     {
    274         pIntMutexSem->cNesting--;
     309    if (pThis->cNesting > 1)
     310    {
     311        ASMAtomicDecU32(&pThis->cNesting);
    275312        return VINF_SUCCESS;
    276313    }
     
    280317     */
    281318#ifdef RTSEMMUTEX_STRICT
    282     RTTHREAD Thread = RTThreadSelf();
    283     if (Thread != NIL_RTTHREAD)
    284         RTThreadWriteLockDec(Thread);
    285 #endif
    286     pIntMutexSem->Owner    = (pthread_t)-1;
    287     ASMAtomicXchgU32(&pIntMutexSem->cNesting, 0);
     319    RTThreadWriteLockDec(RTLockValidatorUnsetOwner(&pThis->ValidatorRec));
     320#endif
     321    pThis->Owner = (pthread_t)-1;
     322    ASMAtomicXchgU32(&pThis->cNesting, 0);
    288323
    289324    /*
    290325     * Unlock mutex semaphore.
    291326     */
    292     int rc = pthread_mutex_unlock(&pIntMutexSem->Mutex);
    293     if (rc)
     327    int rc = pthread_mutex_unlock(&pThis->Mutex);
     328    if (RT_UNLIKELY(rc))
    294329    {
    295330        AssertMsgFailed(("Failed to unlock mutex sem %p, rc=%d.\n", MutexSem, rc)); NOREF(rc);
  • trunk/src/VBox/Runtime/r3/win/sems-win.cpp

    r10839 r25373  
    265265}
    266266
     267
     268RTDECL(int)  RTSemMutexRequestNoResumeDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
     269{
     270    return RTSemMutexRequestNoResume(MutexSem, cMillies);
     271}
     272
     273
    267274RTDECL(int)  RTSemMutexRelease(RTSEMMUTEX MutexSem)
    268275{
  • trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp

    r25368 r25373  
    104104
    105105# if defined(PDMCRITSECT_STRICT) && defined(IN_RING3)
    106     RTLockValidatorSetOwner(pCritSect->s.Core.pValidatorRec, NIL_RTTHREAD, PDMCRITSECT_STRICT_ARGS_PASS_ON);
    107     RTThreadWriteLockInc(pCritSect->s.Core.pValidatorRec->hThread);
     106    RTThreadWriteLockInc(RTLockValidatorSetOwner(pCritSect->s.Core.pValidatorRec, NIL_RTTHREAD, PDMCRITSECT_STRICT_ARGS_PASS_ON));
    108107# endif
    109108
     
    136135    SUPSEMEVENT     hEvent   = (SUPSEMEVENT)pCritSect->s.Core.EventSem;
    137136# ifdef PDMCRITSECT_STRICT
    138     RTTHREAD        hSelf    = RTThreadSelf();
    139     if (hSelf == NIL_RTTHREAD)
    140         RTThreadAdopt(RTTHREADTYPE_DEFAULT, 0, NULL, &hSelf);
     137    RTTHREAD        hSelf    = RTThreadSelfAutoAdopt();
    141138    RTLockValidatorCheckOrder(pCritSect->s.Core.pValidatorRec, hSelf, 0, NULL, 0, NULL);
    142139# endif
     
    380377#else
    381378    /* No need for a second code instance. */
    382     return PDMCritSectTryEnterDebug(pCritSect, (uintptr_t)ASMReturnAddress(), RT_SRC_POS);
     379    return PDMCritSectTryEnter(pCritSect);
    383380#endif
    384381}
     
    403400        &&  pCritSect->s.Core.pValidatorRec
    404401        &&  pCritSect->s.Core.pValidatorRec->hThread != NIL_RTTHREAD)
    405     {
    406         RTThreadWriteLockDec(pCritSect->s.Core.pValidatorRec->hThread);
    407         RTLockValidatorUnsetOwner(pCritSect->s.Core.pValidatorRec);
    408     }
     402        RTThreadWriteLockDec(RTLockValidatorUnsetOwner(pCritSect->s.Core.pValidatorRec));
    409403    return rc;
    410404}
     
    452446#  if defined(PDMCRITSECT_STRICT)
    453447        if (pCritSect->s.Core.pValidatorRec->hThread != NIL_RTTHREAD)
    454         {
    455             RTThreadWriteLockDec(pCritSect->s.Core.pValidatorRec->hThread);
    456             RTLockValidatorUnsetOwner(pCritSect->s.Core.pValidatorRec);
    457         }
     448            RTThreadWriteLockDec(RTLockValidatorUnsetOwner(pCritSect->s.Core.pValidatorRec));
    458449#  endif
    459450# endif
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