Changeset 78192cc7 in mainline for uspace/lib/c/generic/fibril_synch.c


Ignore:
Timestamp:
2014-07-13T14:06:23Z (11 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
af2a76c, f303f2cf
Parents:
c1b979a
Message:

Fibril timer locking improvements.

File:
1 edited

Legend:

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

    rc1b979a r78192cc7  
    448448        int rc;
    449449
    450         fibril_mutex_lock(&timer->lock);
     450        fibril_mutex_lock(timer->lockp);
    451451
    452452        while (timer->state != fts_cleanup) {
     
    454454                case fts_not_set:
    455455                case fts_fired:
    456                         fibril_condvar_wait(&timer->cv, &timer->lock);
     456                        fibril_condvar_wait(&timer->cv, timer->lockp);
    457457                        break;
    458458                case fts_active:
    459459                        rc = fibril_condvar_wait_timeout(&timer->cv,
    460                             &timer->lock, timer->delay);
     460                            timer->lockp, timer->delay);
    461461                        if (rc == ETIMEOUT && timer->state == fts_active) {
    462462                                timer->state = fts_fired;
    463                                 fibril_mutex_unlock(&timer->lock);
     463                                timer->handler_running = true;
     464                                fibril_mutex_unlock(timer->lockp);
    464465                                timer->fun(timer->arg);
    465                                 fibril_mutex_lock(&timer->lock);
     466                                fibril_mutex_lock(timer->lockp);
     467                                timer->handler_running = false;
    466468                        }
    467469                        break;
     
    475477        /* Acknowledge timer fibril has finished cleanup. */
    476478        timer->state = fts_clean;
    477         fibril_condvar_broadcast(&timer->cv);
    478         fibril_mutex_unlock(&timer->lock);
     479        fibril_mutex_unlock(timer->lockp);
     480        free(timer);
    479481
    480482        return 0;
     
    485487 * @return              New timer on success, @c NULL if out of memory.
    486488 */
    487 fibril_timer_t *fibril_timer_create(void)
     489fibril_timer_t *fibril_timer_create(fibril_mutex_t *lock)
    488490{
    489491        fid_t fid;
     
    505507        timer->fibril = fid;
    506508        timer->state = fts_not_set;
     509        timer->lockp = (lock != NULL) ? lock : &timer->lock;
    507510
    508511        fibril_add_ready(fid);
    509 
    510512        return timer;
    511513}
     
    517519void fibril_timer_destroy(fibril_timer_t *timer)
    518520{
    519         fibril_mutex_lock(&timer->lock);
     521        fibril_mutex_lock(timer->lockp);
    520522        assert(timer->state == fts_not_set || timer->state == fts_fired);
    521523
     
    523525        timer->state = fts_cleanup;
    524526        fibril_condvar_broadcast(&timer->cv);
    525 
    526         /* Wait for timer fibril to acknowledge. */
    527         while (timer->state != fts_clean)
    528                 fibril_condvar_wait(&timer->cv, &timer->lock);
    529 
    530         fibril_mutex_unlock(&timer->lock);
     527        fibril_mutex_unlock(timer->lockp);
    531528}
    532529
     
    544541    fibril_timer_fun_t fun, void *arg)
    545542{
    546         fibril_mutex_lock(&timer->lock);
     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 */
     558void 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));
    547562        assert(timer->state == fts_not_set || timer->state == fts_fired);
    548563        timer->state = fts_active;
     
    551566        timer->arg = arg;
    552567        fibril_condvar_broadcast(&timer->cv);
    553         fibril_mutex_unlock(&timer->lock);
    554568}
    555569
     
    569583        fibril_timer_state_t old_state;
    570584
    571         fibril_mutex_lock(&timer->lock);
     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 */
     604fibril_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
    572613        old_state = timer->state;
    573614        timer->state = fts_not_set;
     
    577618        timer->arg = NULL;
    578619        fibril_condvar_broadcast(&timer->cv);
    579         fibril_mutex_unlock(&timer->lock);
    580620
    581621        return old_state;
Note: See TracChangeset for help on using the changeset viewer.