Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/fibril_synch.c

    rb72efe8 r7cf7ded  
    447447}
    448448
     449/** Timer fibril.
     450 *
     451 * @param arg   Timer
     452 */
     453static int fibril_timer_func(void *arg)
     454{
     455        fibril_timer_t *timer = (fibril_timer_t *) arg;
     456        int rc;
     457
     458        fibril_mutex_lock(&timer->lock);
     459
     460        while (true) {
     461                while (timer->state != fts_active &&
     462                    timer->state != fts_cleanup) {
     463
     464                        if (timer->state == fts_cleanup)
     465                                break;
     466
     467                        fibril_condvar_wait(&timer->cv, &timer->lock);
     468                }
     469
     470                if (timer->state == fts_cleanup)
     471                        break;
     472
     473                rc = fibril_condvar_wait_timeout(&timer->cv, &timer->lock,
     474                    timer->delay);
     475                if (rc == ETIMEOUT) {
     476                        timer->state = fts_fired;
     477                        fibril_mutex_unlock(&timer->lock);
     478                        timer->fun(timer->arg);
     479                        fibril_mutex_lock(&timer->lock);
     480                }
     481        }
     482
     483        fibril_mutex_unlock(&timer->lock);
     484        return 0;
     485}
     486
     487/** Create new timer.
     488 *
     489 * @return              New timer on success, @c NULL if out of memory.
     490 */
     491fibril_timer_t *fibril_timer_create(void)
     492{
     493        fid_t fid;
     494        fibril_timer_t *timer;
     495
     496        timer = calloc(1, sizeof(fibril_timer_t));
     497        if (timer == NULL)
     498                return NULL;
     499
     500        fid = fibril_create(fibril_timer_func, (void *) timer);
     501        if (fid == 0) {
     502                free(timer);
     503                return NULL;
     504        }
     505
     506        fibril_mutex_initialize(&timer->lock);
     507        fibril_condvar_initialize(&timer->cv);
     508
     509        timer->fibril = fid;
     510        timer->state = fts_not_set;
     511
     512        fibril_add_ready(fid);
     513
     514        return timer;
     515}
     516
     517/** Destroy timer.
     518 *
     519 * @param timer         Timer, must not be active or accessed by other threads.
     520 */
     521void fibril_timer_destroy(fibril_timer_t *timer)
     522{
     523        fibril_mutex_lock(&timer->lock);
     524        assert(timer->state != fts_active);
     525        timer->state = fts_cleanup;
     526        fibril_condvar_broadcast(&timer->cv);
     527        fibril_mutex_unlock(&timer->lock);
     528}
     529
     530/** Set timer.
     531 *
     532 * Set timer to execute a callback function after the specified
     533 * interval.
     534 *
     535 * @param timer         Timer
     536 * @param delay         Delay in microseconds
     537 * @param fun           Callback function
     538 * @param arg           Argument for @a fun
     539 */
     540void fibril_timer_set(fibril_timer_t *timer, suseconds_t delay,
     541    fibril_timer_fun_t fun, void *arg)
     542{
     543        fibril_mutex_lock(&timer->lock);
     544        timer->state = fts_active;
     545        timer->delay = delay;
     546        timer->fun = fun;
     547        timer->arg = arg;
     548        fibril_condvar_broadcast(&timer->cv);
     549        fibril_mutex_unlock(&timer->lock);
     550}
     551
     552/** Clear timer.
     553 *
     554 * Clears (cancels) timer and returns last state of the timer.
     555 * This can be one of:
     556 *    - fts_not_set     If the timer has not been set or has been cleared
     557 *    - fts_active      Timer was set but did not fire
     558 *    - fts_fired       Timer fired
     559 *
     560 * @param timer         Timer
     561 * @return              Last timer state
     562 */
     563fibril_timer_state_t fibril_timer_clear(fibril_timer_t *timer)
     564{
     565        fibril_timer_state_t old_state;
     566
     567        fibril_mutex_lock(&timer->lock);
     568        old_state = timer->state;
     569        timer->state = fts_not_set;
     570
     571        timer->delay = 0;
     572        timer->fun = NULL;
     573        timer->arg = NULL;
     574        fibril_condvar_broadcast(&timer->cv);
     575        fibril_mutex_unlock(&timer->lock);
     576
     577        return old_state;
     578}
     579
    449580/** @}
    450581 */
Note: See TracChangeset for help on using the changeset viewer.