VirtualBox

Changeset 63052 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Aug 5, 2016 3:25:39 PM (8 years ago)
Author:
vboxsync
Message:

IPRT/RTSemMutex: rewrite rtSemFallbackPthreadMutexTimedlock. Take
relative timeout directly since we need it for nanosleep anyway.
Handle interrupted sleep. Sleep in 1 sec increments.

Note that nothing in the code base seems to call RTSemMutexRequest()
with cMillies other than RT_INDEFINITE_WAIT, so this code is not
actully used at the moment.

Ok bird.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/posix/semmutex-posix.cpp

    r63029 r63052  
    6969#if defined(RT_OS_DARWIN) || defined(RT_OS_NETBSD)
    7070/**
    71  * This function emulate pthread_mutex_timedlock on Mac OS X
     71 * This function is a crude approximation of pthread_mutex_timedlock.
    7272 */
    73 static int rtSemFallbackPthreadMutexTimedlock(pthread_mutex_t * mutex, const struct timespec * pTsAbsTimeout)
    74 {
    75     int rc = 0;
    76     struct timeval tv;
    77     timespec ts = {0, 0};
    78     do
    79     {
     73int rtSemFallbackPthreadMutexTimedlock(pthread_mutex_t *mutex, RTMSINTERVAL cMillies)
     74{
     75    struct timespec ts;
     76    int rc;
     77
     78    rc = pthread_mutex_trylock(mutex);
     79    if (rc != EBUSY)
     80        return rc;
     81
     82    ts.tv_sec = cMillies / 1000;
     83    ts.tv_nsec = (cMillies % 1000) * 1000000;
     84
     85    while (ts.tv_sec > 0 || ts.tv_nsec > 0)
     86    {
     87        struct timespec delta, remaining;
     88
     89        if (ts.tv_sec > 0)
     90        {
     91            delta.tv_sec = 1;
     92            delta.tv_nsec = 0;
     93            ts.tv_sec--;
     94        }
     95        else
     96        {
     97            delta.tv_sec = 0;
     98            delta.tv_nsec = ts.tv_nsec;
     99            ts.tv_nsec = 0;
     100        }
     101       
     102        nanosleep(&delta, &remaining);
     103
    80104        rc = pthread_mutex_trylock(mutex);
    81         if (rc == EBUSY)
    82         {
    83             gettimeofday(&tv, NULL);
    84 
    85             ts.tv_sec = pTsAbsTimeout->tv_sec - tv.tv_sec;
    86             ts.tv_nsec = pTsAbsTimeout->tv_nsec - tv.tv_sec;
    87 
    88             if (ts.tv_nsec < 0)
     105        if (rc != EBUSY)
     106            return rc;
     107
     108        if (RT_UNLIKELY(remaining.tv_nsec > 0 || remaining.tv_sec > 0))
     109        {
     110            ts.tv_sec += remaining.tv_sec;
     111            ts.tv_nsec += remaining.tv_nsec;
     112            if (ts.tv_nsec >= 1000000000)
    89113            {
    90                 ts.tv_sec--;
    91                 ts.tv_nsec += 1000000000;
     114                ts.tv_nsec -= 1000000000;
     115                ts.tv_sec++;
    92116            }
    93 
    94             if (   ts.tv_sec > 0
    95                 && ts.tv_nsec > 0)
    96                 nanosleep(&ts, &ts);
    97         }
    98         else
    99             break;
    100     } while (   rc != 0
    101              || ts.tv_sec > 0);
    102     return rc;
     117        }
     118    }
     119
     120    return ETIMEDOUT;
    103121}
    104122#endif
     
    276294    else
    277295    {
     296        int rc;
     297#if !defined(RT_OS_DARWIN) && !defined(RT_OS_NETBSD)
    278298        struct timespec     ts = {0,0};
    279 #if defined(RT_OS_DARWIN) || defined(RT_OS_HAIKU)
    280 
     299# if defined(RT_OS_HAIKU)
    281300        struct timeval      tv = {0,0};
    282301        gettimeofday(&tv, NULL);
    283302        ts.tv_sec = tv.tv_sec;
    284303        ts.tv_nsec = tv.tv_usec * 1000;
    285 #else
     304# else
    286305        clock_gettime(CLOCK_REALTIME, &ts);
    287 #endif
     306# endif
    288307        if (cMillies != 0)
    289308        {
     
    298317
    299318        /* take mutex */
    300 #if !defined(RT_OS_DARWIN) && !defined(RT_OS_NETBSD)
    301         int rc = pthread_mutex_timedlock(&pThis->Mutex, &ts);
    302 #else
    303         int rc = rtSemFallbackPthreadMutexTimedlock(&pThis->Mutex, &ts);
     319        rc = pthread_mutex_timedlock(&pThis->Mutex, &ts);
     320#else
     321        /*
     322         * When there's no pthread_mutex_timedlock() use a crude sleep
     323         * and retry approximation.  Since the sleep interval is
     324         * relative, we don't need to convert to the absolute time
     325         * here only to convert back to relative in the fallback
     326         * function.
     327         */
     328        rc = rtSemFallbackPthreadMutexTimedlock(&pThis->Mutex, cMillies);
    304329#endif
    305330        RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_MUTEX);
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