VirtualBox

Ignore:
Timestamp:
Mar 15, 2011 3:07:35 PM (14 years ago)
Author:
vboxsync
Message:

Runtime/r0drv/solaris: Fix for PIL changes while spinning across calls to timeout_generic in RTSemEventWait/RTSemEventMultiWait.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r0drv/solaris/semeventwait-r0drv-solaris.h

    r36261 r36287  
    238238 * @param   pMtx                The mutex related to the condition variable.
    239239 *                              The caller has entered this.
     240 *
     241 * @remarks This must be call with the object mutex (spinlock) held.
    240242 */
    241243DECLINLINE(void) rtR0SemSolWaitDoIt(PRTR0SEMSOLWAIT pWait, kcondvar_t *pCnd, kmutex_t *pMtx)
     
    264266                 * High resolution timeout - arm a high resolution timeout callback
    265267                 * for waking up the thread at the desired time.
     268                 *
     269                 * Release and reacquire the mutex across calls to timeout_generic(), @bugref{5595}.
    266270                 */
    267                 int OldPrioLevel = getpil();
     271                mutex_exit(pMtx);
    268272                u.idCo = g_pfnrtR0Sol_timeout_generic(CALLOUT_REALTIME, rtR0SemSolWaitTimeout, pWait,
    269273                                                      pWait->uNsAbsTimeout, RTR0SEMSOLWAIT_RESOLUTION,
    270274                                                      CALLOUT_FLAG_ABSOLUTE);
    271                 int NewPrioLevel = getpil();
    272                 AssertReleaseMsg(NewPrioLevel >= OldPrioLevel, ("Unexpected lowering of PIL (Old=%d New=%d)\n", OldPrioLevel, NewPrioLevel));
     275                mutex_enter(pMtx);
    273276            }
    274277#if 0 /* @bugref{5342} */
     
    300303             * We're better off with our own callback like on the timeout man page,
    301304             * than calling cv_timedwait[_sig]().
     305             *
     306             * Release and reacquire the mutex across calls to realtime_timeout(), @bugref{5595}.
    302307             */
     308            mutex_exit(pMtx);
    303309            u.idTom = realtime_timeout(rtR0SemSolWaitTimeout, pWait, pWait->u.lTimeout);
     310            mutex_enter(pMtx);
    304311        }
    305312    }
    306313
    307314    /*
    308      * Do the waiting.
    309      * (rc > 0 - normal wake-up; rc == 0 - interruption; rc == -1 - timeout)
     315     * Check if the timeout has already fired in the time when the mutex was released.
     316     * Required since we release/reacquire the mutex, @bugref{5595}.
    310317     */
    311     if (pWait->fInterruptible)
    312     {
    313         int rc = cv_wait_sig(pCnd, pMtx);
    314         if (RT_UNLIKELY(rc <= 0))
    315         {
    316             if (RT_LIKELY(rc == 0))
    317                 pWait->fInterrupted = true;
    318             else
    319                 AssertMsgFailed(("rc=%d\n", rc)); /* no timeouts, see above! */
    320         }
    321     }
    322     else
    323         cv_wait(pCnd, pMtx);
     318    if (ASMAtomicReadBool(&pWait->fTimedOut) == false)
     319    {
     320        /*
     321         * Do the waiting.
     322         * (rc > 0 - normal wake-up; rc == 0 - interruption; rc == -1 - timeout)
     323         */
     324        if (pWait->fInterruptible)
     325        {
     326            int rc = cv_wait_sig(pCnd, pMtx);
     327            if (RT_UNLIKELY(rc <= 0))
     328            {
     329                if (RT_LIKELY(rc == 0))
     330                    pWait->fInterrupted = true;
     331                else
     332                    AssertMsgFailed(("rc=%d\n", rc)); /* no timeouts, see above! */
     333            }
     334        }
     335        else
     336            cv_wait(pCnd, pMtx);
     337    }
    324338
    325339    /*
     
    330344    if (fHasTimeout)
    331345    {
     346        /*
     347         * Invalidate the mutex pointer here so that if the timer fires just after we
     348         * exit the mutex or has already fired and the callback is waiting on the mutex,
     349         * we can simply ignore it in the callback as we've completed waiting.
     350         */
    332351        ASMAtomicWritePtr(&pWait->pvMtx, NULL);
    333352        mutex_exit(pMtx);
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