VirtualBox

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


Ignore:
Timestamp:
Jan 6, 2010 2:33:18 AM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
56377
Message:

lockvalidator.cpp: Fixed a bug in rtLockValidatorDdDoDetection where we would end up spinning forever.

File:
1 edited

Legend:

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

    r25648 r25662  
    554554    PRTTHREADINT        pThread         = NIL_RTTHREAD;
    555555    RTTHREADSTATE       enmState        = RTTHREADSTATE_RUNNING;
    556     for (;;)
     556    for (uint32_t iLoop = 0; ; iLoop++)
    557557    {
    558558        /*
     
    561561        RTLOCKVAL_ASSERT_PTR_ALIGN(pRec);
    562562
    563         /* Find the next relevant owner thread. */
    564         PRTTHREADINT pNextThread;
     563        /* Find the next relevant owner thread and record. */
     564        PRTLOCKVALRECUNION  pNextRec     = NULL;
     565        RTTHREADSTATE       enmNextState = RTTHREADSTATE_RUNNING;
     566        PRTTHREADINT        pNextThread  = NIL_RTTHREAD;
    565567        switch (pRec->Core.u32Magic)
    566568        {
    567569            case RTLOCKVALRECEXCL_MAGIC:
    568570                Assert(iEntry == UINT32_MAX);
    569                 pNextThread = rtLockValidatorReadThreadHandle(&pRec->Excl.hThread);
    570                 if (    !pNextThread
    571                     ||  (   pNextThread != pThreadSelf
    572                          && (   pNextThread->u32Magic != RTTHREADINT_MAGIC
    573                              || !RTTHREAD_IS_SLEEPING(rtThreadGetState(pNextThread)) )
    574                         )
    575                    )
     571                for (;;)
     572                {
     573                    pNextThread = rtLockValidatorReadThreadHandle(&pRec->Excl.hThread);
     574                    if (   !pNextThread
     575                        || pNextThread->u32Magic != RTTHREADINT_MAGIC)
     576                        break;
     577                    enmNextState = rtThreadGetState(pNextThread);
     578                    if (    !RTTHREAD_IS_SLEEPING(enmNextState)
     579                        &&  pNextThread != pThreadSelf)
     580                        break;
     581                    pNextRec = rtLockValidatorReadRecUnionPtr(&pNextThread->LockValidator.pRec);
     582                    if (RT_LIKELY(   !pNextRec
     583                                  || enmNextState == rtThreadGetState(pNextThread)))
     584                        break;
     585                    pNextRec = NULL;
     586                }
     587                if (!pNextRec)
    576588                {
    577589                    pRec = pRec->Excl.pSibling;
     
    610622
    611623                /* Scan the owner table for blocked owners. */
    612                 pNextThread = NIL_RTTHREAD;
    613624                if (    ASMAtomicUoReadU32(&pRec->Shared.cEntries) > 0
    614625                    &&  (   !pRec->Shared.fSignaller
     
    623634                    {
    624635                        PRTLOCKVALRECSHRDOWN pEntry = rtLockValidatorUoReadSharedOwner(&papOwners[iEntry]);
    625                         if (   pEntry
    626                             && pEntry->Core.u32Magic == RTLOCKVALRECSHRDOWN_MAGIC)
     636                        if (pEntry)
    627637                        {
    628                             pNextThread = rtLockValidatorReadThreadHandle(&pEntry->hThread);
    629                             if (pNextThread)
     638                            for (;;)
    630639                            {
    631                                 if (   pNextThread->u32Magic == RTTHREADINT_MAGIC
    632                                     && (   RTTHREAD_IS_SLEEPING(rtThreadGetState(pNextThread))
    633                                         || pNextThread == pThreadSelf))
     640                                if (pEntry->Core.u32Magic != RTLOCKVALRECSHRDOWN_MAGIC)
    634641                                    break;
    635                                 pNextThread = NIL_RTTHREAD;
     642                                pNextThread = rtLockValidatorReadThreadHandle(&pEntry->hThread);
     643                                if (   !pNextThread
     644                                    || pNextThread->u32Magic != RTTHREADINT_MAGIC)
     645                                    break;
     646                                enmNextState = rtThreadGetState(pNextThread);
     647                                if (    !RTTHREAD_IS_SLEEPING(enmNextState)
     648                                    &&  pNextThread != pThreadSelf)
     649                                    break;
     650                                pNextRec = rtLockValidatorReadRecUnionPtr(&pNextThread->LockValidator.pRec);
     651                                if (RT_LIKELY(   !pNextRec
     652                                              || enmNextState == rtThreadGetState(pNextThread)))
     653                                    break;
     654                                pNextRec = NULL;
    636655                            }
     656                            if (pNextRec)
     657                                break;
    637658                        }
    638659                        else
    639660                            Assert(!pEntry || pEntry->Core.u32Magic == RTLOCKVALRECSHRDOWN_MAGIC_DEAD);
    640661                    }
    641                     if (pNextThread != NIL_RTTHREAD)
     662                    if (pNextRec)
    642663                        break;
     664                    pNextThread = NIL_RTTHREAD;
    643665                }
    644666
     
    651673                    continue;
    652674                }
    653                 Assert(pNextThread == NIL_RTTHREAD);
    654675                break;
    655676
    656677            case RTLOCKVALRECEXCL_MAGIC_DEAD:
    657678            case RTLOCKVALRECSHRD_MAGIC_DEAD:
    658                 pNextThread = NIL_RTTHREAD;
    659679                break;
    660680
     
    663683            default:
    664684                AssertMsgFailed(("%p: %#x\n", pRec, pRec->Core));
    665                 pNextThread = NIL_RTTHREAD;
    666685                break;
    667686        }
    668687
    669         /* If we found a thread, check if it is still waiting for something. */
    670         RTTHREADSTATE       enmNextState = RTTHREADSTATE_RUNNING;
    671         PRTLOCKVALRECUNION  pNextRec     = NULL;
    672         if (   pNextThread != NIL_RTTHREAD
    673             && RT_LIKELY(pNextThread->u32Magic == RTTHREADINT_MAGIC))
    674         {
    675             do
    676             {
    677                 enmNextState = rtThreadGetState(pNextThread);
    678                 if (    !RTTHREAD_IS_SLEEPING(enmNextState)
    679                     &&  pNextThread != pThreadSelf)
    680                     break;
    681                 pNextRec = rtLockValidatorReadRecUnionPtr(&pNextThread->LockValidator.pRec);
    682                 if (RT_LIKELY(   !pNextRec
    683                               || enmNextState == rtThreadGetState(pNextThread)))
    684                     break;
    685                 pNextRec = NULL;
    686             } while (pNextThread->u32Magic == RTTHREADINT_MAGIC);
    687         }
    688688        if (pNextRec)
    689689        {
     
    716716            pThread         = pNextThread;
    717717        }
    718         else if (RT_LIKELY(!pNextThread))
     718        else
    719719        {
    720720            /*
     
    763763            pStack->c       = i;
    764764        }
    765         /* else: see if there is another thread to check for this lock. */
     765
     766        Assert(iLoop != 1000000);
    766767    }
    767768}
Note: See TracChangeset for help on using the changeset viewer.

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