VirtualBox

Changeset 25603 in vbox for trunk/src/VBox/Runtime/common


Ignore:
Timestamp:
Dec 31, 2009 2:11:27 AM (15 years ago)
Author:
vboxsync
Message:

iprt: More lock validation code.

File:
1 edited

Legend:

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

    r25602 r25603  
    11281128
    11291129/**
     1130 * Verifies the deadlock stack before calling it a deadlock.
     1131 *
     1132 * @retval  VERR_SEM_LV_DEADLOCK if it's a deadlock.
     1133 * @retval  VERR_TRY_AGAIN if something changed.
     1134 *
     1135 * @param   pStack              The deadlock detection stack.
     1136 */
     1137static int rtLockValidatorDdVerifyDeadlock(PRTLOCKVALIDATORDDSTACK pStack)
     1138{
     1139    uint32_t const c = pStack->c;
     1140    for (uint32_t iPass = 0; iPass < 3; iPass++)
     1141    {
     1142        for (uint32_t i = 1; i < c; i++)
     1143        {
     1144            PRTTHREADINT pThread = pStack->a[i].pThread;
     1145            if (pThread->u32Magic != RTTHREADINT_MAGIC)
     1146                return VERR_TRY_AGAIN;
     1147            if (rtThreadGetState(pThread) != pStack->a[i].enmState)
     1148                return VERR_TRY_AGAIN;
     1149            if (rtLockValidatorReadRecUnionPtr(&pThread->LockValidator.pRec) != pStack->a[i].pFirstSibling)
     1150                return VERR_TRY_AGAIN;
     1151        }
     1152        RTThreadYield();
     1153    }
     1154
     1155    return VERR_SEM_LV_DEADLOCK;
     1156}
     1157
     1158
     1159/**
    11301160 * Checks for stack cycles caused by another deadlock before returning.
    11311161 *
     
    11911221 * detection.
    11921222 *
    1193  * @returns Same as rtLockValidatorDeadlockDetection.
     1223 * @retval  VINF_SUCCESS
     1224 * @retval  VERR_SEM_LV_DEADLOCK
     1225 * @retval  VERR_SEM_LV_EXISTING_DEADLOCK
     1226 * @retval  VERR_TRY_AGAIN
     1227 *
    11941228 * @param   pStack          The stack to use.
    11951229 * @param   pOriginalRec    The original record.
     
    12131247         * Process the current record.
    12141248         */
    1215         /* Extract the (next) thread. */
     1249        /* Find the next relevan owner thread. */
    12161250        PRTTHREADINT pNextThread;
    12171251        switch (pRec->Core.u32Magic)
     
    12241258                    &&  pNextThread != pThreadSelf)
    12251259                    pNextThread = NIL_RTTHREAD;
     1260
    12261261                if (    pNextThread == NIL_RTTHREAD
    12271262                    &&  pRec->Excl.pSibling
     
    12681303                        {
    12691304                            pNextThread = rtLockValidatorReadThreadHandle(&pEntry->hThread);
    1270                             if (    pNextThread
    1271                                 &&  !RTTHREAD_IS_SLEEPING(pNextThread->enmState)
    1272                                 &&  pNextThread != pThreadSelf)
     1305                            if (pNextThread)
     1306                            {
     1307                                if (   pNextThread->u32Magic == RTTHREADINT_MAGIC
     1308                                    && RTTHREAD_IS_SLEEPING(pNextThread->enmState))
     1309                                    break;
    12731310                                pNextThread = NIL_RTTHREAD;
     1311                            }
    12741312                        }
    12751313                        else
    12761314                            Assert(!pEntry || pEntry->Core.u32Magic == RTLOCKVALIDATORSHAREDONE_MAGIC_DEAD);
    12771315                    }
     1316                    if (pNextThread == NIL_RTTHREAD)
     1317                        break;
    12781318                }
    12791319
    12801320                /* Advance to the next sibling, if any. */
    1281                 Assert(pNextThread == NIL_RTTHREAD);
    12821321                if (   pRec->Shared.pSibling != NULL
    12831322                    && pRec->Shared.pSibling != pFirstSibling)
     
    13021341        }
    13031342
    1304         /* Is that thread waiting for something? */
     1343        /* If we found a thread, check if it is still waiting for something. */
    13051344        RTTHREADSTATE               enmNextState = RTTHREADSTATE_RUNNING;
    13061345        PRTLOCKVALIDATORRECUNION    pNextRec     = NULL;
     
    13381377
    13391378            if (RT_UNLIKELY(pNextThread == pThreadSelf))
    1340                 return VERR_SEM_LV_DEADLOCK;
     1379                return rtLockValidatorDdVerifyDeadlock(pStack);
    13411380
    13421381            pRec            = pNextRec;
     
    14571496    RTLOCKVALIDATORDDSTACK Stack;
    14581497    int rc = rtLockValidatorDdDoDetection(&Stack, pRec, pThreadSelf);
    1459     if (RT_FAILURE(rc))
    1460         rcLockValidatorDoDeadlockComplaining(&Stack, pThreadSelf, pSrcPos, rc);
     1498    if (RT_SUCCESS(rc))
     1499        return VINF_SUCCESS;
     1500
     1501    if (rc == VERR_TRY_AGAIN)
     1502    {
     1503        for (uint32_t iLoop = 0; ; iLoop++)
     1504        {
     1505            rc = rtLockValidatorDdDoDetection(&Stack, pRec, pThreadSelf);
     1506            if (RT_SUCCESS_NP(rc))
     1507                return VINF_SUCCESS;
     1508            if (rc != VERR_TRY_AGAIN)
     1509                break;
     1510            RTThreadYield();
     1511            if (iLoop >= 3)
     1512                return VINF_SUCCESS;
     1513        }
     1514    }
     1515
     1516    rcLockValidatorDoDeadlockComplaining(&Stack, pThreadSelf, pSrcPos, rc);
    14611517    return rc;
    14621518#else
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