VirtualBox

Changeset 25710 in vbox


Ignore:
Timestamp:
Jan 11, 2010 10:46:24 AM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
56447
Message:

iprt: SemRW lock order bugfixes.

Location:
trunk/src/VBox/Runtime
Files:
5 edited

Legend:

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

    r25707 r25710  
    30463046        return VINF_SUCCESS;
    30473047    AssertReturn(pRecU->Excl.hThread != NIL_RTTHREAD, VERR_SEM_LV_INVALID_PARAMETER);
     3048    Assert(pRecU->Excl.hThread == RTThreadSelf());
    30483049    AssertReturn(pRecU->Excl.cRecursion > 1, VERR_SEM_LV_INVALID_PARAMETER);
    30493050
     3051    /*
     3052     * Check the release order.
     3053     */
     3054    if (   pRecU->Excl.hClass != NIL_RTLOCKVALCLASS
     3055        && pRecU->Excl.hClass->fStrictReleaseOrder
     3056        && pRecU->Excl.hClass->cMsMinOrder != RT_INDEFINITE_WAIT
     3057       )
     3058    {
     3059        int rc = rtLockValidatorStackCheckReleaseOrder(pRecU->Excl.hThread, pRecU);
     3060        if (RT_FAILURE(rc))
     3061            return rc;
     3062    }
     3063
     3064    /*
     3065     * Perform the unwind.
     3066     */
    30503067    pRecU->Excl.cRecursion--;
    30513068    rtLockValidatorStackPopRecursion(pRecU->Excl.hThread, pRecU);
     
    30643081    if (!pRecU->Excl.fEnabled)
    30653082        return VINF_SUCCESS;
     3083    Assert(pRecU->Excl.hThread == RTThreadSelf());
    30663084    AssertReturn(pRecU->Excl.hThread != NIL_RTTHREAD, VERR_SEM_LV_INVALID_PARAMETER);
    30673085    AssertReturn(pRecU->Excl.cRecursion > 0, VERR_SEM_LV_INVALID_PARAMETER);
     
    30943112    if (!pRecU->Excl.fEnabled)
    30953113        return VINF_SUCCESS;
     3114    Assert(pRecU->Excl.hThread == RTThreadSelf());
    30963115    AssertReturn(pRecU->Excl.hThread != NIL_RTTHREAD, VERR_SEM_LV_INVALID_PARAMETER);
    30973116    AssertReturn(pRecU->Excl.cRecursion > 1, VERR_SEM_LV_INVALID_PARAMETER);
    30983117
     3118    /*
     3119     * Check the release order.
     3120     */
     3121    if (   pRecU->Excl.hClass != NIL_RTLOCKVALCLASS
     3122        && pRecU->Excl.hClass->fStrictReleaseOrder
     3123        && pRecU->Excl.hClass->cMsMinOrder != RT_INDEFINITE_WAIT
     3124       )
     3125    {
     3126        int rc = rtLockValidatorStackCheckReleaseOrder(pRecU->Excl.hThread, pRecU);
     3127        if (RT_FAILURE(rc))
     3128            return rc;
     3129    }
     3130
     3131    /*
     3132     * Perform the unwind.
     3133     */
    30993134    pRecU->Excl.cRecursion--;
    31003135    rtLockValidatorStackPopRecursion(pRecU->Excl.hThread, pRecU);
  • trunk/src/VBox/Runtime/generic/semrw-generic.cpp

    r25707 r25710  
    121121            if (RT_SUCCESS(rc))
    122122            {
    123                 rc = RTCritSectInit(&pThis->CritSect);
     123                rc = RTCritSectInitEx(&pThis->CritSect, RTCRITSECT_FLAGS_NO_LOCK_VAL, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, NULL);
    124124                if (RT_SUCCESS(rc))
    125125                {
     
    142142                        va_list va;
    143143                        va_start(va, pszNameFmt);
    144                         RTLockValidatorRecExclInit(&pThis->ValidatorWrite, hClass, uSubClass, pThis, fLVEnabled, pszNameFmt);
     144                        RTLockValidatorRecExclInitV(&pThis->ValidatorWrite, hClass, uSubClass, pThis, fLVEnabled, pszNameFmt, va);
    145145                        va_end(va);
    146146                        va_start(va, pszNameFmt);
    147                         RTLockValidatorRecSharedInit(&pThis->ValidatorRead, hClass, uSubClass, pThis, false /*fSignaller*/,
    148                                                      fLVEnabled, pszNameFmt);
     147                        RTLockValidatorRecSharedInitV(&pThis->ValidatorRead, hClass, uSubClass, pThis, false /*fSignaller*/,
     148                                                      fLVEnabled, pszNameFmt, va);
    149149                        va_end(va);
    150150                        RTLockValidatorRecMakeSiblings(&pThis->ValidatorWrite.Core, &pThis->ValidatorRead.Core);
     
    271271    if (cMillies > 0)
    272272    {
    273         int rc9 = RTLockValidatorRecSharedCheckOrder(&pThis->ValidatorRead, hThreadSelf, pSrcPos, cMillies);
     273        int rc9;
     274        if (pThis->hWriter != NIL_RTTHREAD && pThis->hWriter == RTThreadNativeSelf())
     275            rc9 = RTLockValidatorRecExclCheckOrder(&pThis->ValidatorWrite, hThreadSelf, pSrcPos, cMillies);
     276        else
     277            rc9 = RTLockValidatorRecSharedCheckOrder(&pThis->ValidatorRead, hThreadSelf, pSrcPos, cMillies);
    274278        if (RT_FAILURE(rc9))
    275279            return rc9;
  • trunk/src/VBox/Runtime/generic/semrw-lockless-generic.cpp

    r25707 r25710  
    147147            va_list va;
    148148            va_start(va, pszNameFmt);
    149             RTLockValidatorRecExclInit(&pThis->ValidatorWrite, hClass, uSubClass, pThis, fLVEnabled, pszNameFmt);
     149            RTLockValidatorRecExclInitV(&pThis->ValidatorWrite, hClass, uSubClass, pThis, fLVEnabled, pszNameFmt, va);
    150150            va_end(va);
    151151            va_start(va, pszNameFmt);
    152             RTLockValidatorRecSharedInit(&pThis->ValidatorRead, hClass, uSubClass, pThis, false /*fSignaller*/,
    153                                          fLVEnabled, pszNameFmt);
     152            RTLockValidatorRecSharedInitV(&pThis->ValidatorRead, hClass, uSubClass, pThis, false /*fSignaller*/,
     153                                          fLVEnabled, pszNameFmt, va);
    154154            va_end(va);
    155155            RTLockValidatorRecMakeSiblings(&pThis->ValidatorWrite.Core, &pThis->ValidatorRead.Core);
     
    237237    if (cMillies > 0)
    238238    {
    239         int rc9 = RTLockValidatorRecSharedCheckOrder(&pThis->ValidatorRead, hThreadSelf, pSrcPos, cMillies);
     239        int            rc9;
     240        RTNATIVETHREAD hNativeWriter;
     241        ASMAtomicUoReadHandle(&pThis->hNativeWriter, &hNativeWriter);
     242        if (hNativeWriter != NIL_RTTHREAD && hNativeWriter == RTThreadNativeSelf())
     243            rc9 = RTLockValidatorRecExclCheckOrder(&pThis->ValidatorWrite, hThreadSelf, pSrcPos, cMillies);
     244        else
     245            rc9 = RTLockValidatorRecSharedCheckOrder(&pThis->ValidatorRead, hThreadSelf, pSrcPos, cMillies);
    240246        if (RT_FAILURE(rc9))
    241247            return rc9;
  • trunk/src/VBox/Runtime/r3/posix/semrw-posix.cpp

    r25707 r25710  
    132132                va_list va;
    133133                va_start(va, pszNameFmt);
    134                 RTLockValidatorRecExclInit(&pThis->ValidatorWrite, hClass, uSubClass, pThis, fLVEnabled, pszNameFmt);
     134                RTLockValidatorRecExclInitV(&pThis->ValidatorWrite, hClass, uSubClass, pThis, fLVEnabled, pszNameFmt, va);
    135135                va_end(va);
    136136                va_start(va, pszNameFmt);
    137                 RTLockValidatorRecSharedInit(&pThis->ValidatorRead, hClass, uSubClass, pThis, false /*fSignaller*/,
    138                                              fLVEnabled, pszNameFmt);
     137                RTLockValidatorRecSharedInitV(&pThis->ValidatorRead, hClass, uSubClass, pThis, false /*fSignaller*/,
     138                                              fLVEnabled, pszNameFmt, va);
    139139                va_end(va);
    140140                RTLockValidatorRecMakeSiblings(&pThis->ValidatorWrite.Core, &pThis->ValidatorRead.Core);
     
    581581        return VINF_SUCCESS;
    582582    }
    583     pThis->cWrites--;
    584583
    585584    /*
     
    592591#endif
    593592
     593    pThis->cWrites--;
    594594    ATOMIC_SET_PTHREAD_T(&pThis->Writer, (pthread_t)-1);
    595595    int rc = pthread_rwlock_unlock(&pThis->RWLock);
  • trunk/src/VBox/Runtime/testcase/tstRTLockValidator.cpp

    r25707 r25710  
    10451045       this as a valid lock order.  */
    10461046    RTTEST_CHECK_RC(g_hTest, RTSemRWRequestWrite(g_ahSemRWs[0], RT_INDEFINITE_WAIT), VINF_SUCCESS);
    1047     RTTEST_CHECK_RC(g_hTest, RTSemRWRequestWrite(g_ahSemRWs[1], RT_INDEFINITE_WAIT), VINF_SUCCESS);
     1047    RTTEST_CHECK_RC(g_hTest, RTSemRWRequestRead( g_ahSemRWs[1], RT_INDEFINITE_WAIT), VINF_SUCCESS);
    10481048    RTTEST_CHECK_RC(g_hTest, RTSemRWRequestRead( g_ahSemRWs[2], RT_INDEFINITE_WAIT), VINF_SUCCESS);
    10491049    RTTEST_CHECK_RC(g_hTest, RTSemRWRequestWrite(g_ahSemRWs[3], RT_INDEFINITE_WAIT), VINF_SUCCESS);
     
    10551055    int rc;
    10561056    RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(g_ahSemRWs[0]), VINF_SUCCESS);
    1057     RTTEST_CHECK_RC(g_hTest, rc = RTSemRWReleaseWrite(g_ahSemRWs[0]), VERR_SEM_LV_WRONG_ORDER);
     1057    RTTEST_CHECK_RC(g_hTest, rc = RTSemRWRequestWrite(g_ahSemRWs[0], RT_INDEFINITE_WAIT), VERR_SEM_LV_WRONG_ORDER);
    10581058    if (RT_SUCCESS(rc))
    10591059        RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(g_ahSemRWs[0]), VINF_SUCCESS);
    10601060
     1061    RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseRead(g_ahSemRWs[1]), VINF_SUCCESS);
     1062    RTTEST_CHECK_RC(g_hTest, rc = RTSemRWRequestRead(g_ahSemRWs[1], RT_INDEFINITE_WAIT), VERR_SEM_LV_WRONG_ORDER);
     1063    if (RT_SUCCESS(rc))
     1064        RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseRead(g_ahSemRWs[1]), VINF_SUCCESS);
     1065
    10611066    /* Check that recursion isn't subject to order checks. */
    1062     RTTEST_CHECK_RC(g_hTest, rc = RTSemRWReleaseWrite(g_ahSemRWs[1]), VINF_SUCCESS);
    1063     if (RT_SUCCESS(rc))
    1064         RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(g_ahSemRWs[1]), VINF_SUCCESS);
     1067    RTTEST_CHECK_RC(g_hTest, rc = RTSemRWRequestRead(g_ahSemRWs[2], RT_INDEFINITE_WAIT), VINF_SUCCESS);
     1068    if (RT_SUCCESS(rc))
     1069        RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseRead(g_ahSemRWs[2]), VINF_SUCCESS);
     1070    RTTEST_CHECK(g_hTest, RTSemRWGetReadCount(g_ahSemRWs[2]) == 1);
     1071
     1072    RTTEST_CHECK_RC(g_hTest, rc = RTSemRWRequestWrite(g_ahSemRWs[3], RT_INDEFINITE_WAIT), VINF_SUCCESS);
     1073    if (RT_SUCCESS(rc))
     1074        RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(g_ahSemRWs[3]), VINF_SUCCESS);
     1075    RTTEST_CHECK(g_hTest, RTSemRWGetWriteRecursion(g_ahSemRWs[3]) == 1);
    10651076
    10661077    /* Enable strict release order for class 2 and 3, then check that violations
     
    10681079    RTTEST_CHECK_RC(g_hTest, RTLockValidatorClassEnforceStrictReleaseOrder(g_ahClasses[2], true), VINF_SUCCESS);
    10691080    RTTEST_CHECK_RC(g_hTest, RTLockValidatorClassEnforceStrictReleaseOrder(g_ahClasses[3], true), VINF_SUCCESS);
    1070     RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseRead(g_ahSemRWs[2]), VINF_SUCCESS);                      /* start recursion */
    1071     RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(g_ahSemRWs[3]), VINF_SUCCESS);
    1072     RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(g_ahSemRWs[4]), VINF_SUCCESS);
     1081
     1082    RTTEST_CHECK_RC(g_hTest, RTSemRWRequestRead( g_ahSemRWs[2], RT_INDEFINITE_WAIT), VINF_SUCCESS);  /* start recursion */
     1083    RTTEST_CHECK(   g_hTest, RTSemRWGetReadCount(g_ahSemRWs[2]) == 2);
     1084    RTTEST_CHECK_RC(g_hTest, RTSemRWRequestWrite(g_ahSemRWs[3], RT_INDEFINITE_WAIT), VINF_SUCCESS);
     1085    RTTEST_CHECK(   g_hTest, RTSemRWGetWriteRecursion(g_ahSemRWs[3]) == 2);
     1086    RTTEST_CHECK_RC(g_hTest, RTSemRWRequestRead( g_ahSemRWs[4], RT_INDEFINITE_WAIT), VINF_SUCCESS);  /* (mixed) */
     1087
    10731088    RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseRead( g_ahSemRWs[2]), VERR_SEM_LV_WRONG_RELEASE_ORDER);
    10741089    RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(g_ahSemRWs[3]), VERR_SEM_LV_WRONG_RELEASE_ORDER);
     1090    RTTEST_CHECK(   g_hTest, RTSemRWGetWriteRecursion(g_ahSemRWs[3]) == 2);
     1091    RTTEST_CHECK(   g_hTest, RTSemRWGetReadCount(g_ahSemRWs[2]) == 2);
     1092    RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseRead( g_ahSemRWs[4]), VINF_SUCCESS);
     1093    RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(g_ahSemRWs[3]), VINF_SUCCESS);
     1094    RTTEST_CHECK(   g_hTest, RTSemRWGetWriteRecursion(g_ahSemRWs[3]) == 1);
     1095    RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseRead( g_ahSemRWs[2]), VINF_SUCCESS);                      /* end recursion */
     1096    RTTEST_CHECK(   g_hTest, RTSemRWGetReadCount(g_ahSemRWs[2]) == 1);
     1097
     1098    RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseRead( g_ahSemRWs[2]), VERR_SEM_LV_WRONG_RELEASE_ORDER);
     1099    RTTEST_CHECK(g_hTest, RTSemRWGetReadCount(g_ahSemRWs[2]) == 1);
     1100    RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(g_ahSemRWs[3]), VERR_SEM_LV_WRONG_RELEASE_ORDER);
     1101    RTTEST_CHECK(g_hTest, RTSemRWGetWriteRecursion(g_ahSemRWs[3]) == 1);
     1102    RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(g_ahSemRWs[5]), VINF_SUCCESS);
    10751103    RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(g_ahSemRWs[4]), VINF_SUCCESS);
    10761104    RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(g_ahSemRWs[3]), VINF_SUCCESS);
    1077     RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseRead( g_ahSemRWs[2]), VINF_SUCCESS);                      /* end recursion */
    1078     RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseRead( g_ahSemRWs[2]), VERR_SEM_LV_WRONG_RELEASE_ORDER);
    1079     RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseRead( g_ahSemRWs[3]), VERR_SEM_LV_WRONG_RELEASE_ORDER);
    1080     RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(g_ahSemRWs[1]), VINF_SUCCESS);
    1081     RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(g_ahSemRWs[4]), VINF_SUCCESS);
    1082     RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(g_ahSemRWs[5]), VINF_SUCCESS);
    1083     RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseRead( g_ahSemRWs[3]), VINF_SUCCESS);
    10841105    RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseRead( g_ahSemRWs[2]), VINF_SUCCESS);
    10851106
     
    11871208        testLo1();
    11881209        testLo2();
     1210        testLo3();
    11891211    }
    11901212
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