Ignore:
File:
1 edited

Legend:

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

    r7cf7ded rb72efe8  
    447447}
    448448
    449 /** Timer fibril.
    450  *
    451  * @param arg   Timer
    452  */
    453 static 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  */
    491 fibril_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  */
    521 void 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  */
    540 void 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  */
    563 fibril_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 
    580449/** @}
    581450 */
Note: See TracChangeset for help on using the changeset viewer.