VirtualBox

Changeset 823 in vbox


Ignore:
Timestamp:
Feb 10, 2007 8:00:14 AM (18 years ago)
Author:
vboxsync
Message:

Wonder if this compiles...

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/linux/sems-linux.cpp

    r822 r823  
    181181    {
    182182        int32_t iCur = pIntEventSem->cWaiters;
    183         if (iCur < 0)
    184             break; /* already signaled */
    185183        if (iCur == 0)
    186184        {
     
    188186                break; /* nobody is waiting */
    189187        }
    190         else if (ASMAtomicCmpXchgS32(&pIntEventSem->cWaiters, iCur - 1, iCur))
    191         {
    192             /* somebody is waiting, wake up one. */
     188        else if (iCur < 0)
     189            break; /* already signaled */
     190        else
     191        {
     192            /* somebody is waiting, try wake up one of them. */
    193193            long cWoken = sys_futex(&pIntEventSem->cWaiters, FUTEX_WAKE, 1, NULL, NULL, 0);
    194             if (cWoken == 1)
     194            if (RT_LIKELY(cWoken == 1))
     195            {
     196                ASMAtomicDecS32(&pIntEventSem->cWaiters);
    195197                break;
    196             ASMAtomicIncS32(&pIntEventSem->cWaiters);
     198            }
    197199            AssertMsg(cWoken == 0, ("%ld\n", cWoken));
    198200
    199201            /*
    200              * We're waiting for the threads to start executing, that's kind of
    201              * silly really. But for now, take care that we don't prevent them
    202              * from executing.
     202             * This path is taken in two situations:
     203             *      1) A waiting thread is returning from the sys_futex call with a
     204             *         non-zero return value.
     205             *      2) There are two threads signaling the event at the
     206             *         same time and only one thread waiting.
     207             *
     208             * At this point we know that nobody is activly waiting on the event but
     209             * at the same time, we are racing someone updating the state. The current
     210             * strategy is to spin till the thread racing us is done, this is kind of
     211             * brain dead and need fixing of course.
    203212             */
    204             if ((i % 128) == 127)
    205                 usleep(1000);
    206             else if ((i % 16) == 15)
    207                 pthread_yield();
    208             else
    209                 Assert(i < 1024);
     213            if (RT_UNLIKELY(i > 32))
     214            {
     215                if ((i % 128) == 127)
     216                    usleep(1000);
     217                else if (!(i % 4))
     218                    pthread_yield();
     219                else
     220                    AssertReleaseMsg(i < 4096, ("iCur=%#x pIntEventSem=%p\n", iCur, pIntEventSem));
     221            }
    210222        }
    211223    }
     
    260272            if (RT_UNLIKELY(pIntEventSem->iMagic != RTSEMEVENT_MAGIC))
    261273                return VERR_SEM_DESTROYED;
     274
     275            /* Did somebody wake us up us from RTSemEventSignal()? */
    262276            if (rc == 0)
    263277                return VINF_SUCCESS;
    264278
    265             /* don't count us among the waiters. */
     279            /* No, then the kernel woke us up or we failed going to sleep. Adjust the accounting. */
    266280            iNew = ASMAtomicDecS32(&pIntEventSem->cWaiters);
    267281            Assert(iNew >= 0);
     
    291305        else
    292306        {
    293             /*
    294              * Somebody is signaling the semaphore, let's try again.
    295              * But take care to yield and sleep after a while like always.
    296              * (Could probably change this to string only and return right away...)
    297              */
    298             ASMAtomicDecS32(&pIntEventSem->cWaiters);
    299             if ((i % 128) == 127)
    300                 usleep(1000);
    301             else if ((i % 16) == 15)
    302                 pthread_yield();
    303             else
    304                 AssertReleaseMsg(i < 4096, ("iNew=%d\n", iNew));
     307            /* this can't happen. */
    305308            if (RT_UNLIKELY(pIntEventSem->iMagic != RTSEMEVENT_MAGIC))
    306309                return VERR_SEM_DESTROYED;
     310            AssertReleaseMsgFailed(("iNew=%d\n", iNew));
    307311        }
    308312    }
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