VirtualBox

Changeset 25618 in vbox


Ignore:
Timestamp:
Jan 2, 2010 12:00:33 PM (15 years ago)
Author:
vboxsync
Message:

IPRT,pdmcritsect: More lock validator hacking.

Location:
trunk
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/lockvalidator.h

    r25617 r25618  
    434434
    435435/**
    436  * Do deadlock detection before blocking on exclusive access to a lock.
    437  *
    438  * @retval  VINF_SUCCESS
     436 * Do deadlock detection before blocking on exclusive access to a lock and
     437 * change the thread state.
     438 *
     439 * @retval  VINF_SUCCESS - thread is in the specified sleep state.
    439440 * @retval  VERR_SEM_LV_DEADLOCK if blocking would deadlock.  Gone thru the
    440441 *          motions.
     
    450451 * @param   pSrcPos             The source position of the lock operation.
    451452 * @param   fRecursiveOk        Whether it's ok to recurse.
     453 * @param   enmSleepState       The sleep state to enter on successful return.
    452454 */
    453455RTDECL(int) RTLockValidatorRecExclCheckBlocking(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
    454                                                 PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk);
     456                                                PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk,
     457                                                RTTHREADSTATE enmSleepState);
    455458
    456459/**
     
    463466 * @param   pSrcPos             The source position of the lock operation.
    464467 * @param   fRecursiveOk        Whether it's ok to recurse.
     468 * @param   enmSleepState       The sleep state to enter on successful return.
    465469 */
    466470RTDECL(int) RTLockValidatorRecExclCheckOrderAndBlocking(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
    467                                                         PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk);
     471                                                        PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk,
     472                                                        RTTHREADSTATE enmSleepState);
    468473
    469474/**
     
    509514
    510515/**
    511  * Do deadlock detection before blocking on shared access to a lock.
    512  *
    513  * @retval  VINF_SUCCESS
     516 * Do deadlock detection before blocking on shared access to a lock and change
     517 * the thread state.
     518 *
     519 * @retval  VINF_SUCCESS - thread is in the specified sleep state.
    514520 * @retval  VERR_SEM_LV_DEADLOCK if blocking would deadlock.  Gone thru the
    515521 *          motions.
     
    525531 * @param   pSrcPos             The source position of the lock operation.
    526532 * @param   fRecursiveOk        Whether it's ok to recurse.
     533 * @param   enmSleepState       The sleep state to enter on successful return.
    527534 */
    528535RTDECL(int) RTLockValidatorRecSharedCheckBlocking(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf,
    529                                                   PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk);
     536                                                  PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk,
     537                                                  RTTHREADSTATE enmSleepState);
    530538
    531539/**
     
    540548 */
    541549RTDECL(int) RTLockValidatorRecSharedCheckOrderAndBlocking(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf,
    542                                                           PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk);
     550                                                          PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk,
     551                                                          RTTHREADSTATE enmSleepState);
    543552
    544553/**
  • trunk/src/VBox/Runtime/common/misc/lockvalidator.cpp

    r25617 r25618  
    11331133
    11341134RTDECL(int) RTLockValidatorRecExclCheckBlocking(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
    1135                                                 PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk)
     1135                                                PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk,
     1136                                                RTTHREADSTATE enmSleepState)
    11361137{
    11371138    /*
     
    11491150    Assert(pThreadSelf == RTThreadSelf());
    11501151
     1152    AssertReturn(RTTHREAD_IS_SLEEPING(enmSleepState), VERR_SEM_LV_INVALID_PARAMETER);
     1153
    11511154    RTTHREADSTATE enmThreadState = rtThreadGetState(pThreadSelf);
    1152     AssertReturn(   enmThreadState == RTTHREADSTATE_RUNNING
    1153                  || enmThreadState == RTTHREADSTATE_TERMINATED   /* rtThreadRemove uses locks too */
    1154                  || enmThreadState == RTTHREADSTATE_INITIALIZING /* rtThreadInsert uses locks too */
    1155                  , VERR_SEM_LV_INVALID_PARAMETER);
     1155    if (RT_UNLIKELY(enmThreadState != RTTHREADSTATE_RUNNING))
     1156    {
     1157        AssertReturn(   enmThreadState == RTTHREADSTATE_TERMINATED   /* rtThreadRemove uses locks too */
     1158                     || enmThreadState == RTTHREADSTATE_INITIALIZING /* rtThreadInsert uses locks too */
     1159                     , VERR_SEM_LV_INVALID_PARAMETER);
     1160        enmSleepState = enmThreadState;
     1161    }
    11561162
    11571163    /*
     
    11601166    rtLockValidatorWriteRecUnionPtr(&pThreadSelf->LockValidator.pRec, pRecU);
    11611167    rtLockValidatorCopySrcPos(&pThreadSelf->LockValidator.SrcPos, pSrcPos);
     1168    rtThreadSetState(pThreadSelf, enmSleepState);
    11621169
    11631170    /*
     
    11731180        rtLockValidatorComplainFirst("Recursion not allowed", pSrcPos, pThreadSelf, pRecU);
    11741181        rtLockValidatorComplainPanic();
     1182        rtThreadSetState(pThreadSelf, enmThreadState);
    11751183        return VERR_SEM_LV_NESTED;
    11761184    }
     
    11791187     * Perform deadlock detection.
    11801188     */
    1181     if (rtLockValidatorIsSimpleNoDeadlockCase(pRecU))
    1182         return VINF_SUCCESS;
    1183     return rtLockValidatorDeadlockDetection(pRecU, pThreadSelf, pSrcPos);
     1189    int rc = VINF_SUCCESS;
     1190    if (!rtLockValidatorIsSimpleNoDeadlockCase(pRecU))
     1191    {
     1192        rc = rtLockValidatorDeadlockDetection(pRecU, pThreadSelf, pSrcPos);
     1193        if (RT_FAILURE(rc))
     1194            rtThreadSetState(pThreadSelf, enmThreadState);
     1195    }
     1196    return rc;
    11841197}
    11851198RT_EXPORT_SYMBOL(RTLockValidatorRecExclCheckBlocking);
     
    11871200
    11881201RTDECL(int) RTLockValidatorRecExclCheckOrderAndBlocking(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
    1189                                                         PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk)
     1202                                                        PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk,
     1203                                                        RTTHREADSTATE enmSleepState)
    11901204{
    11911205    int rc = RTLockValidatorRecExclCheckOrder(pRec, hThreadSelf, pSrcPos);
    11921206    if (RT_SUCCESS(rc))
    1193         rc = RTLockValidatorRecExclCheckBlocking(pRec, hThreadSelf, pSrcPos, fRecursiveOk);
     1207        rc = RTLockValidatorRecExclCheckBlocking(pRec, hThreadSelf, pSrcPos, fRecursiveOk, enmSleepState);
    11941208    return rc;
    11951209}
     
    13181332
    13191333RTDECL(int) RTLockValidatorRecSharedCheckBlocking(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf,
    1320                                                   PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk)
     1334                                                  PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk,
     1335                                                  RTTHREADSTATE enmSleepState)
    13211336{
    13221337    /*
     
    13341349    Assert(pThreadSelf == RTThreadSelf());
    13351350
     1351    AssertReturn(RTTHREAD_IS_SLEEPING(enmSleepState), VERR_SEM_LV_INVALID_PARAMETER);
     1352
    13361353    RTTHREADSTATE enmThreadState = rtThreadGetState(pThreadSelf);
    1337     AssertReturn(   enmThreadState == RTTHREADSTATE_RUNNING
    1338                  || enmThreadState == RTTHREADSTATE_TERMINATED   /* rtThreadRemove uses locks too */
    1339                  || enmThreadState == RTTHREADSTATE_INITIALIZING /* rtThreadInsert uses locks too */
    1340                  , VERR_SEM_LV_INVALID_PARAMETER);
     1354    if (RT_UNLIKELY(enmThreadState != RTTHREADSTATE_RUNNING))
     1355    {
     1356        AssertReturn(   enmThreadState == RTTHREADSTATE_TERMINATED   /* rtThreadRemove uses locks too */
     1357                     || enmThreadState == RTTHREADSTATE_INITIALIZING /* rtThreadInsert uses locks too */
     1358                     , VERR_SEM_LV_INVALID_PARAMETER);
     1359        enmSleepState = enmThreadState;
     1360    }
    13411361
    13421362    /*
     
    13451365    rtLockValidatorWriteRecUnionPtr(&pThreadSelf->LockValidator.pRec, pRecU);
    13461366    rtLockValidatorCopySrcPos(&pThreadSelf->LockValidator.SrcPos, pSrcPos);
     1367    rtThreadSetState(pThreadSelf, enmSleepState);
    13471368
    13481369    /*
     
    13561377        rtLockValidatorComplainFirst("Recursion not allowed", pSrcPos, pThreadSelf, pRecU);
    13571378        rtLockValidatorComplainPanic();
     1379        rtThreadSetState(pThreadSelf, enmThreadState);
    13581380        return VERR_SEM_LV_NESTED;
    13591381    }
     
    13621384     * Perform deadlock detection.
    13631385     */
    1364     if (rtLockValidatorIsSimpleNoDeadlockCase(pRecU))
    1365         return VINF_SUCCESS;
    1366     return rtLockValidatorDeadlockDetection(pRecU, pThreadSelf, pSrcPos);
     1386    int rc = VINF_SUCCESS;
     1387    if (!rtLockValidatorIsSimpleNoDeadlockCase(pRecU))
     1388    {
     1389        rc = rtLockValidatorDeadlockDetection(pRecU, pThreadSelf, pSrcPos);
     1390        if (RT_FAILURE(rc))
     1391            rtThreadSetState(pThreadSelf, enmThreadState);
     1392    }
     1393    return rc;
    13671394}
    13681395RT_EXPORT_SYMBOL(RTLockValidatorRecSharedCheckBlocking);
    13691396
    13701397
    1371 RTDECL(int) RTLockValidatorRecSharedCheckOrderAndBlocking(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf, PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk)
     1398RTDECL(int) RTLockValidatorRecSharedCheckOrderAndBlocking(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf,
     1399                                                          PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk,
     1400                                                          RTTHREADSTATE enmSleepState)
    13721401{
    13731402    int rc = RTLockValidatorRecSharedCheckOrder(pRec, hThreadSelf, pSrcPos);
    13741403    if (RT_SUCCESS(rc))
    1375         rc = RTLockValidatorRecSharedCheckBlocking(pRec, hThreadSelf, pSrcPos, fRecursiveOk);
     1404        rc = RTLockValidatorRecSharedCheckBlocking(pRec, hThreadSelf, pSrcPos, fRecursiveOk, enmSleepState);
    13761405    return rc;
    13771406}
  • trunk/src/VBox/Runtime/common/misc/thread.cpp

    r25611 r25618  
    196196}
    197197
    198 
    199 /**
    200  * Sets the thread state.
    201  *
    202  * @param   pThread             The thread.
    203  * @param   enmNewState         The new thread state.
    204  */
    205 DECLINLINE(void) rtThreadSetState(PRTTHREADINT pThread, RTTHREADSTATE enmNewState)
    206 {
    207     AssertCompile(sizeof(pThread->enmState) == sizeof(uint32_t));
    208     ASMAtomicWriteU32((uint32_t volatile *)&pThread->enmState, enmNewState);
    209 }
    210198
    211199#ifdef IN_RING3
  • trunk/src/VBox/Runtime/generic/critsect-generic.cpp

    r25614 r25618  
    209209#ifdef RTCRITSECT_STRICT
    210210            int rc9 = RTLockValidatorRecExclCheckBlocking(pCritSect->pValidatorRec, hThreadSelf, pSrcPos,
    211                                                           !(pCritSect->fFlags & RTCRITSECT_FLAGS_NO_NESTING));
     211                                                          !(pCritSect->fFlags & RTCRITSECT_FLAGS_NO_NESTING),
     212                                                          RTTHREADSTATE_CRITSECT);
    212213            if (RT_FAILURE(rc9))
    213214            {
     
    215216                return rc9;
    216217            }
    217 #endif
    218 
     218#else
    219219            RTThreadBlocking(hThreadSelf, RTTHREADSTATE_CRITSECT);
     220#endif
    220221            int rc = RTSemEventWait(pCritSect->EventSem, RT_INDEFINITE_WAIT);
    221222            RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_CRITSECT);
  • trunk/src/VBox/Runtime/generic/semrw-generic.cpp

    r25616 r25618  
    320320        }
    321321#ifdef RTSEMRW_STRICT
    322         rc = RTLockValidatorRecSharedCheckBlocking(&pThis->ValidatorRead, hThreadSelf, pSrcPos, true);
     322        rc = RTLockValidatorRecSharedCheckBlocking(&pThis->ValidatorRead, hThreadSelf, pSrcPos, true, RTTHREADSTATE_RW_READ);
    323323        if (RT_FAILURE(rc))
    324324            break;
    325 #endif
     325#else
    326326        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_READ);
    327 
     327#endif
    328328        int rcWait = rc = RTSemEventMultiWait(pThis->ReadEvent, cMillies);
    329329        RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_RW_READ);
     
    572572            }
    573573        }
    574 #ifdef RTSEMRW_STRICT
    575         rc = RTLockValidatorRecExclCheckBlocking(&pThis->ValidatorWrite, hThreadSelf, pSrcPos, true);
     574
     575#ifdef RTSEMRW_STRICT
     576        rc = RTLockValidatorRecExclCheckBlocking(&pThis->ValidatorWrite, hThreadSelf, pSrcPos, true, RTTHREADSTATE_RW_WRITE);
    576577        if (RT_FAILURE(rc))
    577578            break;
    578 #endif
     579#else
    579580        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_WRITE);
     581#endif
    580582        int rcWait = rc = RTSemEventWait(pThis->WriteEvent, cMillies);
    581583        RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_RW_WRITE);
  • trunk/src/VBox/Runtime/include/internal/thread.h

    r25611 r25618  
    196196#endif
    197197
     198#ifdef ___iprt_asm_h
     199
    198200/**
    199201 * Gets the thread state.
     
    207209}
    208210
     211/**
     212 * Sets the thread state.
     213 *
     214 * @param   pThread             The thread.
     215 * @param   enmNewState         The new thread state.
     216 */
     217DECLINLINE(void) rtThreadSetState(PRTTHREADINT pThread, RTTHREADSTATE enmNewState)
     218{
     219    AssertCompile(sizeof(pThread->enmState) == sizeof(uint32_t));
     220    ASMAtomicWriteU32((uint32_t volatile *)&pThread->enmState, enmNewState);
     221}
     222
     223#endif
     224
    209225RT_C_DECLS_END
    210226
  • trunk/src/VBox/Runtime/r3/linux/semmutex-linux.cpp

    r25614 r25618  
    240240            {
    241241#ifdef RTSEMMUTEX_STRICT
    242                 int rc9 = RTLockValidatorRecExclCheckBlocking(&pThis->ValidatorRec, hThreadSelf, pSrcPos, true);
     242                int rc9 = RTLockValidatorRecExclCheckBlocking(&pThis->ValidatorRec, hThreadSelf, pSrcPos, true, RTTHREADSTATE_MUTEX);
    243243                if (RT_FAILURE(rc9))
    244244                    return rc9;
    245 #endif
     245#else
    246246                RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX);
     247#endif
    247248            }
    248249
  • trunk/src/VBox/Runtime/r3/posix/semmutex-posix.cpp

    r25614 r25618  
    188188#ifdef RTSEMMUTEX_STRICT
    189189        hThreadSelf = RTThreadSelfAutoAdopt();
    190         int rc9 = RTLockValidatorRecExclCheckOrderAndBlocking(&pThis->ValidatorRec, hThreadSelf, pSrcPos, true);
     190        int rc9 = RTLockValidatorRecExclCheckOrderAndBlocking(&pThis->ValidatorRec, hThreadSelf, pSrcPos, true, RTTHREADSTATE_MUTEX);
    191191        if (RT_FAILURE(rc9))
    192192            return rc9;
    193193#else
    194194        hThreadSelf = RTThreadSelf();
    195 #endif
    196195        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX);
     196#endif
    197197    }
    198198
  • trunk/src/VBox/Runtime/r3/posix/semrw-posix.cpp

    r25616 r25618  
    219219#ifdef RTSEMRW_STRICT
    220220        hThreadSelf = RTThreadSelfAutoAdopt();
    221         int rc9 = RTLockValidatorRecSharedCheckOrderAndBlocking(&pThis->ValidatorRead, hThreadSelf, pSrcPos, true);
     221        int rc9 = RTLockValidatorRecSharedCheckOrderAndBlocking(&pThis->ValidatorRead, hThreadSelf, pSrcPos, true, RTTHREADSTATE_RW_READ);
    222222        if (RT_FAILURE(rc9))
    223223            return rc9;
    224224#else
    225225        hThreadSelf = RTThreadSelf();
    226 #endif
    227226        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_READ);
     227#endif
    228228    }
    229229
     
    381381#ifdef RTSEMRW_STRICT
    382382        hThreadSelf = RTThreadSelfAutoAdopt();
    383         int rc9 = RTLockValidatorRecExclCheckOrderAndBlocking(&pThis->ValidatorWrite, hThreadSelf, pSrcPos, true);
     383        int rc9 = RTLockValidatorRecExclCheckOrderAndBlocking(&pThis->ValidatorWrite, hThreadSelf, pSrcPos, true, RTTHREADSTATE_RW_WRITE);
    384384        if (RT_FAILURE(rc9))
    385385            return rc9;
    386386#else
    387387        hThreadSelf = RTThreadSelf();
    388 #endif
    389388        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_WRITE);
     389#endif
    390390    }
    391391
  • trunk/src/VBox/Runtime/r3/win/semmutex-win.cpp

    r25614 r25618  
    159159#ifdef RTSEMMUTEX_STRICT
    160160        hThreadSelf = RTThreadSelfAutoAdopt();
    161         int rc9 = RTLockValidatorRecExclCheckOrderAndBlocking(&pThis->ValidatorRec, hThreadSelf, pSrcPos, true);
     161        int rc9 = RTLockValidatorRecExclCheckOrderAndBlocking(&pThis->ValidatorRec, hThreadSelf, pSrcPos, true, RTTHREADSTATE_MUTEX);
    162162        if (RT_FAILURE(rc9))
    163163            return rc9;
    164164#else
    165165        hThreadSelf = RTThreadSelf();
    166 #endif
    167166        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX);
     167#endif
    168168    }
    169169    int rc = WaitForSingleObjectEx(pThis->hMtx,
  • trunk/src/VBox/Runtime/testcase/tstRTLockValidator.cpp

    r25617 r25618  
    4141#include <iprt/test.h>
    4242#include <iprt/thread.h>
     43#include <iprt/time.h>
    4344
    4445
     
    4748*******************************************************************************/
    4849/** The testcase handle. */
    49 static RTTEST       g_hTest;
     50static RTTEST               g_hTest;
    5051/** Flip this in the debugger to get some peace to single step wild code. */
    51 bool volatile       g_fDoNotSpin = false;
     52bool volatile               g_fDoNotSpin = false;
    5253
    5354static uint32_t             g_cThreads;
     
    5657static RTCRITSECT           g_aCritSects[32];
    5758static RTSEMRW              g_ahSemRWs[32];
     59
     60/** When to stop testing. */
     61static uint64_t             g_NanoTSStop;
     62/** The number of deadlocks. */
     63static uint32_t volatile    g_cDeadlocks;
     64/** The number of loops. */
     65static uint32_t volatile    g_cLoops;
    5866
    5967
     
    281289
    282290
    283 static void testIt(uint32_t cThreads, uint32_t cPasses, PFNRTTHREAD pfnThread, const char *pszName)
     291static DECLCALLBACK(int) test3Thread(RTTHREAD ThreadSelf, void *pvUser)
     292{
     293    uintptr_t       i     = (uintptr_t)pvUser;
     294    RTSEMRW         hMine = g_ahSemRWs[i];
     295    RTSEMRW         hNext = g_ahSemRWs[(i + 1) % g_cThreads];
     296    int             rc;
     297
     298    if (i & 1)
     299        RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestWrite(hMine, RT_INDEFINITE_WAIT), VINF_SUCCESS, rcCheck);
     300    else
     301        RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestRead(hMine, RT_INDEFINITE_WAIT), VINF_SUCCESS, rcCheck);
     302    if (testWaitForSemRWToBeOwned(hNext))
     303    {
     304        do
     305        {
     306            rc = RTSemRWRequestWrite(hNext, 60*1000);
     307            if (rc != VINF_SUCCESS && rc != VERR_SEM_LV_DEADLOCK && rc != VERR_SEM_LV_ILLEGAL_UPGRADE)
     308            {
     309                RTTestFailed(g_hTest, "#%u: RTSemRWRequestWrite -> %Rrc\n", i, rc);
     310                break;
     311            }
     312            if (RT_SUCCESS(rc))
     313            {
     314                RTTEST_CHECK_RC(g_hTest, rc = RTSemRWReleaseWrite(hNext), VINF_SUCCESS);
     315                if (RT_FAILURE(rc))
     316                    break;
     317            }
     318            else
     319                ASMAtomicIncU32(&g_cDeadlocks);
     320            ASMAtomicIncU32(&g_cLoops);
     321        } while (RTTimeNanoTS() < g_NanoTSStop);
     322    }
     323    if (i & 1)
     324        RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(hMine), VINF_SUCCESS);
     325    else
     326        RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseRead(hMine), VINF_SUCCESS);
     327    RTTEST_CHECK(g_hTest, RTThreadGetState(RTThreadSelf()) == RTTHREADSTATE_RUNNING);
     328    return VINF_SUCCESS;
     329}
     330
     331
     332static void testIt(uint32_t cThreads, uint32_t cPasses, uint64_t cNanoSecs, PFNRTTHREAD pfnThread, const char *pszName)
    284333{
    285334    RTTestSubF(g_hTest, "%s, %u threads, %u passes", pszName, cThreads, cPasses);
     
    297346    }
    298347
    299     uint32_t cErrors = RTTestErrorCount(g_hTest);
     348    uint32_t cLoops     = 0;
     349    uint32_t cDeadlocks = 0;
     350    uint32_t cErrors    = RTTestErrorCount(g_hTest);
    300351    for (uint32_t iPass = 0; iPass < cPasses && RTTestErrorCount(g_hTest) == cErrors; iPass++)
    301352    {
     
    303354        g_iDeadlockThread = (cThreads - 1 + iPass) % cThreads;
    304355#endif
     356        g_cLoops = 0;
     357        g_cDeadlocks = 0;
     358        g_NanoTSStop = cNanoSecs ? RTTimeNanoTS() + cNanoSecs : 0;
     359
    305360        int rc = testStartThreads(cThreads, pfnThread);
    306361        if (RT_SUCCESS(rc))
    307             testWaitForThreads(30*1000, true);
     362            testWaitForThreads(30*1000 + cNanoSecs / 1000000, true);
     363
     364        RTTEST_CHECK(g_hTest, !cNanoSecs || g_cLoops > 0);
     365        cLoops += g_cLoops;
     366        RTTEST_CHECK(g_hTest, !cNanoSecs || g_cDeadlocks > 0);
     367        cDeadlocks += g_cDeadlocks;
    308368    }
    309369
     
    314374    }
    315375    testWaitForThreads(10*1000, false);
     376
     377    if (cNanoSecs)
     378        RTTestPrintf(g_hTest,  RTTESTLVL_ALWAYS, "cLoops=%u cDeadlocks=%u (%u%%)\n",
     379                     cLoops, cDeadlocks, cLoops ? cDeadlocks * 100 / cLoops : 0);
    316380}
    317381
     
    319383static void test1(uint32_t cThreads, uint32_t cPasses)
    320384{
    321     testIt(cThreads, cPasses, test1Thread, "critsect");
     385    testIt(cThreads, cPasses, 0, test1Thread, "critsect");
    322386}
    323387
     
    325389static void test2(uint32_t cThreads, uint32_t cPasses)
    326390{
    327     testIt(cThreads, cPasses, test2Thread, "read-write");
     391    testIt(cThreads, cPasses, 0, test2Thread, "read-write");
     392}
     393
     394
     395static void test3(uint32_t cThreads, uint32_t cPasses, uint64_t cNanoSecs)
     396{
     397    testIt(cThreads, cPasses, cNanoSecs, test3Thread, "read-write race");
    328398}
    329399
     
    383453     */
    384454    RTLockValidatorSetQuiet(true);
    385 
     455#if 0
    386456    test1( 2, 1024);
    387457    test1( 3, 1024);
     
    398468    test2(15,  512);
    399469    test2(30,  384);
    400 
     470#endif
     471
     472    test3( 2,  2,  5*UINT64_C(1000000000));
     473    test3(10,  1,  5*UINT64_C(1000000000));
    401474
    402475    return RTTestSummaryAndDestroy(g_hTest);
  • trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp

    r25614 r25618  
    139139# ifdef PDMCRITSECT_STRICT
    140140        int rc9 = RTLockValidatorRecExclCheckBlocking(pCritSect->s.Core.pValidatorRec, hThreadSelf, pSrcPos,
    141                                                       !(pCritSect->s.Core.fFlags & RTCRITSECT_FLAGS_NO_NESTING));
     141                                                      !(pCritSect->s.Core.fFlags & RTCRITSECT_FLAGS_NO_NESTING),
     142                                                      RTTHREADSTATE_CRITSECT);
    142143        if (RT_FAILURE(rc9))
    143144            return rc9;
    144 # endif
    145 
     145# else
    146146        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_CRITSECT);
     147# endif
    147148        int rc = SUPSemEventWaitNoResume(pSession, hEvent, RT_INDEFINITE_WAIT);
    148149        RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_CRITSECT);
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