VirtualBox

Changeset 9839 in vbox for trunk/src/VBox/Runtime/r3/posix


Ignore:
Timestamp:
Jun 20, 2008 9:27:34 AM (17 years ago)
Author:
vboxsync
Message:

New implementation of RTTimer... using POSIX timers.

File:
1 edited

Legend:

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

    r9444 r9839  
    5757#endif
    5858
     59#define RT_TIMER_SIGNAL SIGUSR1
    5960
    6061/*******************************************************************************
     
    7475    /** Flag indicating that the timer has been destroyed. */
    7576    uint8_t volatile        fDestroyed;
     77#ifndef IPRT_WITH_POSIX_TIMERS
    7678    /** The timer thread. */
    7779    RTTHREAD                Thread;
    7880    /** Event semaphore on which the thread is blocked. */
    7981    RTSEMEVENT              Event;
     82#endif
    8083    /** User argument. */
    8184    void                   *pvUser;
     
    8487    /** The timer interval. 0 if one-shot. */
    8588    uint64_t                u64NanoInterval;
     89#ifndef IPRT_WITH_POSIX_TIMERS
    8690    /** The first shot interval. 0 if ASAP. */
    8791    uint64_t volatile       u64NanoFirst;
     92#endif /* !IPRT_WITH_POSIX_TIMERS */
    8893    /** The current timer tick. */
    8994    uint64_t volatile       iTick;
     95#ifndef IPRT_WITH_POSIX_TIMERS
    9096    /** The error/status of the timer.
    9197     * Initially -1, set to 0 when the timer have been successfully started, and
    9298     * to errno on failure in starting the timer. */
    9399    int volatile            iError;
     100#else /* !IPRT_WITH_POSIX_TIMERS */
     101    timer_t                 timer;
     102#endif /* !IPRT_WITH_POSIX_TIMERS */
    94103
    95104} RTTIMER;
    96105
     106#ifndef IPRT_WITH_POSIX_TIMERS
    97107
    98108/**
     
    282292    return VINF_SUCCESS;
    283293}
     294#else /* !IPRT_WITH_POSIX_TIMERS */
     295void rtSignalCallback(int sig, siginfo_t *sip, void *ucp)
     296{
     297    PRTTIMER pTimer = (PRTTIMER)sip->_sifields._timer.si_sigval.sival_ptr;
     298    pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pTimer->iTick);
     299}
     300#endif /* !IPRT_WITH_POSIX_TIMERS */
    284301
    285302
     
    292309        return VERR_NOT_SUPPORTED;
    293310
     311#ifndef IPRT_WITH_POSIX_TIMERS
    294312    /*
    295313     * Check if timer is busy.
     
    415433    else
    416434        rc = VERR_NO_MEMORY;
     435#else /* !IPRT_WITH_POSIX_TIMERS */
     436    /*
     437     * Create a new timer.
     438     */
     439    int rc, result;
     440    PRTTIMER pTimer = (PRTTIMER)RTMemAlloc(sizeof(*pTimer));
     441    if (pTimer)
     442    {
     443        struct sigevent  evt;
     444        struct sigaction action, old;
     445
     446        /* Initialize timer structure. */
     447        pTimer->u32Magic        = RTTIMER_MAGIC;
     448        pTimer->fSuspended      = true;
     449        pTimer->fDestroyed      = false;
     450        pTimer->pfnTimer        = pfnTimer;
     451        pTimer->pvUser          = pvUser;
     452        pTimer->u64NanoInterval = u64NanoInterval;
     453        pTimer->iTick           = 0;
     454
     455        /* Set up the signal handler. */
     456        sigemptyset(&action.sa_mask);
     457        action.sa_sigaction = rtSignalCallback;
     458        action.sa_flags     = SA_SIGINFO | SA_RESTART;
     459        rc = RTErrConvertFromErrno(sigaction(RT_TIMER_SIGNAL, &action, &old));
     460        if (RT_SUCCESS(rc))
     461        {
     462   
     463            /* Ask to deliver RT_TIMER_SIGNAL upon timer expiration. */
     464            evt.sigev_notify = SIGEV_SIGNAL;
     465            evt.sigev_signo  = RT_TIMER_SIGNAL;
     466            evt.sigev_value.sival_ptr = pTimer; /* sigev_value gets copied to siginfo. */
     467   
     468            rc = RTErrConvertFromErrno(timer_create(CLOCK_REALTIME, &evt, &pTimer->timer));
     469            if (RT_SUCCESS(rc))
     470            {
     471                *ppTimer = pTimer;
     472                return VINF_SUCCESS;
     473            }
     474            sigaction(RT_TIMER_SIGNAL, &old, NULL);
     475        }
     476        RTMemFree(pTimer);
     477    }
     478    else
     479        rc = VERR_NO_MEMORY;
     480
     481#endif /* !IPRT_WITH_POSIX_TIMERS */
    417482    return rc;
    418483}
     
    432497    AssertPtrReturn(pTimer, VERR_INVALID_POINTER);
    433498    AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_MAGIC);
     499#ifndef IPRT_WITH_POSIX_TIMERS
    434500    AssertReturn(pTimer->Thread != RTThreadSelf(), VERR_INTERNAL_ERROR);
    435501
     
    452518    RTSemEventDestroy(pTimer->Event);
    453519    pTimer->Event = NIL_RTSEMEVENT;
     520#else /* !IPRT_WITH_POSIX_TIMERS */
     521    if (ASMAtomicXchgU8(&pTimer->fDestroyed, true))
     522    {
     523        /* It is already being destroyed by another thread. */
     524        return VINF_SUCCESS;
     525    }
     526    rc = RTErrConvertFromErrno(timer_delete(pTimer->timer));
     527#endif /* !IPRT_WITH_POSIX_TIMERS */
    454528    if (RT_SUCCESS(rc))
    455529        RTMemFree(pTimer);
     
    465539    AssertPtrReturn(pTimer, VERR_INVALID_POINTER);
    466540    AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_MAGIC);
     541#ifndef IPRT_WITH_POSIX_TIMERS
    467542    AssertReturn(pTimer->Thread != RTThreadSelf(), VERR_INTERNAL_ERROR);
    468543
     
    491566    if (RT_FAILURE(rc))
    492567        ASMAtomicXchgU8(&pTimer->fSuspended, false);
     568#else /* !IPRT_WITH_POSIX_TIMERS */
     569    struct itimerspec ts;
     570
     571    if (!ASMAtomicXchgU8(&pTimer->fSuspended, false))
     572        return VERR_TIMER_ACTIVE;
     573
     574    ts.it_value.tv_sec     = u64First / 1000000000; /* nanosec => sec */
     575    ts.it_value.tv_nsec    = u64First ? u64First % 1000000000 : 1; /* 0 means disable, replace it with 1. */
     576    ts.it_interval.tv_sec  = pTimer->u64NanoInterval / 1000000000;
     577    ts.it_interval.tv_nsec = pTimer->u64NanoInterval % 1000000000;
     578    int rc = RTErrConvertFromErrno(timer_settime(pTimer->timer, 0, &ts, NULL));
     579#endif /* !IPRT_WITH_POSIX_TIMERS */
    493580
    494581    return rc;
     
    504591    AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_MAGIC);
    505592
     593#ifndef IPRT_WITH_POSIX_TIMERS
    506594    /*
    507595     * Already running?
     
    525613        RTThreadUserReset(pTimer->Thread);
    526614    }
     615#else /* !IPRT_WITH_POSIX_TIMERS */
     616    struct itimerspec ts;
     617
     618    if (ASMAtomicXchgU8(&pTimer->fSuspended, true))
     619        return VERR_TIMER_SUSPENDED;
     620
     621    ts.it_value.tv_sec     = 0;
     622    ts.it_value.tv_nsec    = 0;
     623    int rc = RTErrConvertFromErrno(timer_settime(pTimer->timer, 0, &ts, NULL));
     624#endif /* !IPRT_WITH_POSIX_TIMERS */
    527625
    528626    return rc;
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