Ignore:
File:
1 edited

Legend:

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

    r78192cc7 r45cbcaf4  
    448448        int rc;
    449449
    450         fibril_mutex_lock(timer->lockp);
    451 
    452         while (timer->state != fts_cleanup) {
    453                 switch (timer->state) {
    454                 case fts_not_set:
    455                 case fts_fired:
    456                         fibril_condvar_wait(&timer->cv, timer->lockp);
     450        fibril_mutex_lock(&timer->lock);
     451
     452        while (true) {
     453                while (timer->state != fts_active &&
     454                    timer->state != fts_cleanup) {
     455
     456                        if (timer->state == fts_cleanup)
     457                                break;
     458
     459                        fibril_condvar_wait(&timer->cv, &timer->lock);
     460                }
     461
     462                if (timer->state == fts_cleanup)
    457463                        break;
    458                 case fts_active:
    459                         rc = fibril_condvar_wait_timeout(&timer->cv,
    460                             timer->lockp, timer->delay);
    461                         if (rc == ETIMEOUT && timer->state == fts_active) {
    462                                 timer->state = fts_fired;
    463                                 timer->handler_running = true;
    464                                 fibril_mutex_unlock(timer->lockp);
    465                                 timer->fun(timer->arg);
    466                                 fibril_mutex_lock(timer->lockp);
    467                                 timer->handler_running = false;
    468                         }
    469                         break;
    470                 case fts_cleanup:
    471                 case fts_clean:
    472                         assert(false);
    473                         break;
     464
     465                rc = fibril_condvar_wait_timeout(&timer->cv, &timer->lock,
     466                    timer->delay);
     467                if (rc == ETIMEOUT) {
     468                        timer->state = fts_fired;
     469                        fibril_mutex_unlock(&timer->lock);
     470                        timer->fun(timer->arg);
     471                        fibril_mutex_lock(&timer->lock);
    474472                }
    475473        }
    476474
    477         /* Acknowledge timer fibril has finished cleanup. */
    478         timer->state = fts_clean;
    479         fibril_mutex_unlock(timer->lockp);
    480         free(timer);
    481 
     475        fibril_mutex_unlock(&timer->lock);
    482476        return 0;
    483477}
     
    487481 * @return              New timer on success, @c NULL if out of memory.
    488482 */
    489 fibril_timer_t *fibril_timer_create(fibril_mutex_t *lock)
     483fibril_timer_t *fibril_timer_create(void)
    490484{
    491485        fid_t fid;
     
    507501        timer->fibril = fid;
    508502        timer->state = fts_not_set;
    509         timer->lockp = (lock != NULL) ? lock : &timer->lock;
    510503
    511504        fibril_add_ready(fid);
     505
    512506        return timer;
    513507}
     
    519513void fibril_timer_destroy(fibril_timer_t *timer)
    520514{
    521         fibril_mutex_lock(timer->lockp);
    522         assert(timer->state == fts_not_set || timer->state == fts_fired);
    523 
    524         /* Request timer fibril to terminate. */
     515        fibril_mutex_lock(&timer->lock);
     516        assert(timer->state != fts_active);
    525517        timer->state = fts_cleanup;
    526518        fibril_condvar_broadcast(&timer->cv);
    527         fibril_mutex_unlock(timer->lockp);
     519        fibril_mutex_unlock(&timer->lock);
    528520}
    529521
     
    541533    fibril_timer_fun_t fun, void *arg)
    542534{
    543         fibril_mutex_lock(timer->lockp);
    544         fibril_timer_set_locked(timer, delay, fun, arg);
    545         fibril_mutex_unlock(timer->lockp);
    546 }
    547 
    548 /** Set locked timer.
    549  *
    550  * Set timer to execute a callback function after the specified
    551  * interval. Must be called when the timer is locked.
    552  *
    553  * @param timer         Timer
    554  * @param delay         Delay in microseconds
    555  * @param fun           Callback function
    556  * @param arg           Argument for @a fun
    557  */
    558 void fibril_timer_set_locked(fibril_timer_t *timer, suseconds_t delay,
    559     fibril_timer_fun_t fun, void *arg)
    560 {
    561         assert(fibril_mutex_is_locked(timer->lockp));
    562         assert(timer->state == fts_not_set || timer->state == fts_fired);
     535        fibril_mutex_lock(&timer->lock);
    563536        timer->state = fts_active;
    564537        timer->delay = delay;
     
    566539        timer->arg = arg;
    567540        fibril_condvar_broadcast(&timer->cv);
     541        fibril_mutex_unlock(&timer->lock);
    568542}
    569543
     
    583557        fibril_timer_state_t old_state;
    584558
    585         fibril_mutex_lock(timer->lockp);
    586         old_state = fibril_timer_clear_locked(timer);
    587         fibril_mutex_unlock(timer->lockp);
    588 
    589         return old_state;
    590 }
    591 
    592 /** Clear locked timer.
    593  *
    594  * Clears (cancels) timer and returns last state of the timer.
    595  * This can be one of:
    596  *    - fts_not_set     If the timer has not been set or has been cleared
    597  *    - fts_active      Timer was set but did not fire
    598  *    - fts_fired       Timer fired
    599  * Must be called when the timer is locked.
    600  *
    601  * @param timer         Timer
    602  * @return              Last timer state
    603  */
    604 fibril_timer_state_t fibril_timer_clear_locked(fibril_timer_t *timer)
    605 {
    606         fibril_timer_state_t old_state;
    607 
    608         assert(fibril_mutex_is_locked(timer->lockp));
    609 
    610         while (timer->handler_running)
    611                 fibril_condvar_wait(&timer->cv, timer->lockp);
    612 
     559        fibril_mutex_lock(&timer->lock);
    613560        old_state = timer->state;
    614561        timer->state = fts_not_set;
     
    618565        timer->arg = NULL;
    619566        fibril_condvar_broadcast(&timer->cv);
     567        fibril_mutex_unlock(&timer->lock);
    620568
    621569        return old_state;
Note: See TracChangeset for help on using the changeset viewer.