VirtualBox

Ignore:
Timestamp:
Jul 7, 2010 3:54:20 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
63476
Message:

Runtime/r0drv/Solaris: SemEvent fixes.

Location:
trunk/src/VBox/Runtime/r0drv/solaris
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r0drv/solaris/semevent-r0drv-solaris.c

    r30472 r30711  
    5555    /** Magic value (RTSEMEVENT_MAGIC). */
    5656    uint32_t volatile   u32Magic;
    57     /** The number of waiting threads. */
    58     uint32_t volatile   cWaiters;
    59     /** The number of signalled threads. */
    60     uint32_t volatile   cWakeUp;
    6157    /** The number of threads referencing this object. */
    6258    uint32_t volatile   cRefs;
     59    /** Set if the object is signalled when there are no waiters. */
     60    bool                fSignaled;
     61    /** Object generation.
     62     * This is incremented every time the object is signalled and used to
     63     * check for spurious wake-ups. */
     64    uint32_t            uSignalGen;
     65    /** The number of waiting threads. */
     66    uint32_t            cWaiters;
     67    /** The number of signalled threads. */
     68    uint32_t            cWakeUp;
    6369    /** The Solaris mutex protecting this structure and pairing up the with the cv. */
    6470    kmutex_t            Mtx;
     
    8793
    8894    pThis->u32Magic       = RTSEMEVENT_MAGIC;
     95    pThis->cRefs          = 1;
     96    pThis->fSignaled      = false;
     97    pThis->uSignalGen     = 0;
    8998    pThis->cWaiters       = 0;
    9099    pThis->cWakeUp        = 0;
    91     pThis->cRefs          = 1;
    92100    mutex_init(&pThis->Mtx, "IPRT Event Semaphore", MUTEX_DRIVER, (void *)ipltospl(DISP_LEVEL));
    93101    cv_init(&pThis->Cnd, "IPRT CV", CV_DRIVER, NULL);
     
    111119    ASMAtomicDecU32(&pThis->cRefs);
    112120
    113     ASMAtomicIncU32(&pThis->u32Magic); /* make the handle invalid */
     121    pThis->u32Magic = RTSEMEVENT_MAGIC_DEAD; /* make the handle invalid */
    114122    if (pThis->cWaiters > 0)
    115123    {
     
    175183    }
    176184
    177     ASMAtomicIncU32(&pThis->cWakeUp);
     185    pThis->cWakeUp++;
    178186    if (pThis->cWakeUp <= pThis->cWaiters)
    179187    {
     
    184192         */
    185193        cv_signal(&pThis->Cnd);
    186     }
     194        pThis->uSignalGen++;
     195    }
     196    else
     197        pThis->fSignaled = true;
    187198
    188199    mutex_exit(&pThis->Mtx);
     
    237248    ASMAtomicIncU32(&pThis->cRefs);
    238249
    239     if (pThis->cWakeUp > 0)
     250    if (pThis->fSignaled)
    240251    {
    241252        /*
     
    244255         */
    245256        Assert(!pThis->cWaiters);
    246         ASMAtomicWriteU32((uint32_t volatile *)&pThis->cWakeUp, 0);
     257        pThis->fSignaled = false;
     258        pThis->cWakeUp = 0;
    247259        rc = VINF_SUCCESS;
    248260    }
     
    251263    else
    252264    {
    253         uint32_t cWakeUp = ASMAtomicUoReadU32((uint32_t volatile *)&pThis->cWakeUp);
    254         ASMAtomicIncU32(&pThis->cWaiters);
     265        pThis->cWaiters++;
     266        /* This loop is only for continuing after a spurious wake-up. */
    255267        for (;;)
    256268        {
     269            uint32_t const uSignalGenBeforeWait = pThis->uSignalGen;
    257270            rc = rtSemEventWaitWorker(pThis, cMillies, fInterruptible);
    258271            if (rc > 0)
    259272            {
    260                 if (pThis->u32Magic != RTSEMEVENT_MAGIC)
     273                if (pThis->u32Magic == RTSEMEVENT_MAGIC)
    261274                {
    262                     /*
    263                      * We're being destroyed.
    264                      */
    265                     ASMAtomicDecU32(&pThis->cWaiters);
    266                     rc = VERR_SEM_DESTROYED;
    267                     break;
     275                    if (pThis->uSignalGen != uSignalGenBeforeWait)
     276                    {
     277                        /* We've been signaled by cv_signal(), consume the wake up. */
     278                        --pThis->cWakeUp;
     279                        rc = VINF_SUCCESS;
     280                    }
     281                    else
     282                        /* Spurious wakeup due to some signal, go back to waiting. */
     283                        continue;
    268284                }
    269285                else
    270                 {
    271                     uint32_t cWakeUpNow = ASMAtomicUoReadU32((uint32_t volatile *)&pThis->cWakeUp);
    272                     if (cWakeUpNow > cWakeUp)
    273                     {
    274                         /*
    275                          * We've been signaled by RTSemEventSignal(), consume the wake up.
    276                          */
    277                         ASMAtomicDecU32(&pThis->cWaiters);
    278                         ASMAtomicDecU32(&pThis->cWakeUp);
    279                         rc = VINF_SUCCESS;
    280                         break;
    281                     }
    282                     else
    283                     {
    284                         /*
    285                          * Premature wakeup due to some signal, go back to waiting.
    286                          */
    287                         continue;
    288                     }
    289                 }
     286                    /* We're being destroyed. */
     287                    rc = VERR_SEM_DESTROYED;
    290288            }
    291289            else if (rc == -1)
    292             {
    293                 /*
    294                  * Timeout reached.
    295                  */
    296                 ASMAtomicDecU32(&pThis->cWaiters);
     290                /* Timeout reached. */
    297291                rc = VERR_TIMEOUT;
    298                 break;
    299             }
    300292            else
    301             {
    302293                /* Returned due to pending signal */
    303                 ASMAtomicDecU32(&pThis->cWaiters);
    304294                rc = VERR_INTERRUPTED;
    305                 break;
    306             }
     295
     296            --pThis->cWaiters;
     297            break;
    307298        }
    308299    }
  • trunk/src/VBox/Runtime/r0drv/solaris/semeventmulti-r0drv-solaris.c

    r30579 r30711  
    284284    else
    285285    {
    286 
    287286        /* This loop is only for continuing after a spurious wake-up. */
    288287        for (;;)
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