diff options
| author | Venky Shankar <vshankar@redhat.com> | 2015-05-22 11:54:11 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vbellur@redhat.com> | 2015-05-28 02:44:25 -0700 | 
| commit | eaf3bfa1886928240eda3a83ab1ece3d61f7fd50 (patch) | |
| tree | be69c62dce342351e14e9043da236c459c368678 /contrib | |
| parent | e9290dc0db7bee31cda1cbed1d9eb68d9c404746 (diff) | |
contrib/timer-wheel: mod_timer() and friends
Couple of timer-wheel api's to modify timer expiry times:
  mod_timer()
  mod_timer_pending()
Both the api's perform almost the same job with one minute
difference: mod_timer_pending() modifies timer expiry only
if the timer is pending (i.e. being tracked in timer-wheel).
Change-Id: Iae64934854ccfd6b081b849bff998ae3c3021bac
BUG: 1224596
Signed-off-by: Venky Shankar <vshankar@redhat.com>
Reviewed-on: http://review.gluster.org/10892
Tested-by: NetBSD Build System
Reviewed-by: Niels de Vos <ndevos@redhat.com>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Diffstat (limited to 'contrib')
| -rw-r--r-- | contrib/timer-wheel/timer-wheel.c | 86 | ||||
| -rw-r--r-- | contrib/timer-wheel/timer-wheel.h | 8 | 
2 files changed, 89 insertions, 5 deletions
diff --git a/contrib/timer-wheel/timer-wheel.c b/contrib/timer-wheel/timer-wheel.c index 77fbfbe9953..df8bb31fe87 100644 --- a/contrib/timer-wheel/timer-wheel.c +++ b/contrib/timer-wheel/timer-wheel.c @@ -85,11 +85,12 @@ apply_slack(struct tvec_base *base, struct gf_tw_timer_list *timer)  }  static inline void -gf_tw_detach_timer (struct gf_tw_timer_list *timer) +__gf_tw_detach_timer (struct gf_tw_timer_list *timer)  {          struct list_head *entry = &timer->entry;          list_del (entry); +        entry->next = NULL;  }  static inline int @@ -141,7 +142,7 @@ run_timers (struct tvec_base *base)                          fn = timer->function;                          data = timer->data; -                        gf_tw_detach_timer (timer); +                        __gf_tw_detach_timer (timer);                          fn (timer, data, call_time);                  }          } @@ -166,6 +167,38 @@ void *runner (void *arg)  } +static inline int timer_pending (struct gf_tw_timer_list *timer) +{ +        struct list_head *entry = &timer->entry; + +        return (entry->next != NULL); +} + +static inline int __detach_if_pending (struct gf_tw_timer_list *timer) +{ +        if (!timer_pending (timer)) +                return 0; + +        __gf_tw_detach_timer (timer); +        return 1; +} + +static inline int __mod_timer (struct tvec_base *base, +                               struct gf_tw_timer_list *timer, int pending_only) +{ +        int ret = 0; + +        ret = __detach_if_pending (timer); +        if (!ret && pending_only) +                goto done; + +        ret = 1; +        __gf_tw_add_timer (base, timer); + + done: +        return ret; +} +  /* interface */  /** @@ -185,9 +218,54 @@ void gf_tw_add_timer (struct tvec_base *base, struct gf_tw_timer_list *timer)  /**   * Remove a timer from the timer wheel   */ -void gf_tw_del_timer (struct gf_tw_timer_list *timer) +void gf_tw_del_timer (struct tvec_base *base, struct gf_tw_timer_list *timer)  { -        gf_tw_detach_timer (timer); +        pthread_spin_lock (&base->lock); +        { +                if (timer_pending (timer)) +                        __gf_tw_detach_timer (timer); +        } +        pthread_spin_lock (&base->lock); +} + +int gf_tw_mod_timer_pending (struct tvec_base *base, +                             struct gf_tw_timer_list *timer, +                             unsigned long expires) +{ +        int ret = 1; + +        pthread_spin_lock (&base->lock); +        { +                timer->expires = expires + base->timer_sec; +                timer->expires = apply_slack (base, timer); + +                ret = __mod_timer (base, timer, 1); +        } +        pthread_spin_unlock (&base->lock); + +        return ret; +} + +int gf_tw_mod_timer (struct tvec_base *base, +                     struct gf_tw_timer_list *timer, unsigned long expires) +{ +        int ret = 1; + +        pthread_spin_lock (&base->lock); +        { +                /* fast path optimization */ +                if (timer_pending (timer) && timer->expires == expires) +                        goto unblock; + +                timer->expires = expires + base->timer_sec; +                timer->expires = apply_slack (base, timer); + +                ret = __mod_timer (base, timer, 0); +        } + unblock: +        pthread_spin_unlock (&base->lock); + +        return ret;  }  int gf_tw_cleanup_timers (struct tvec_base *base) diff --git a/contrib/timer-wheel/timer-wheel.h b/contrib/timer-wheel/timer-wheel.h index 74b8dfdff5e..c52f2fc9b9c 100644 --- a/contrib/timer-wheel/timer-wheel.h +++ b/contrib/timer-wheel/timer-wheel.h @@ -66,6 +66,12 @@ struct gf_tw_timer_list {  struct tvec_base *gf_tw_init_timers ();  int gf_tw_cleanup_timers (struct tvec_base *);  void gf_tw_add_timer (struct tvec_base *, struct gf_tw_timer_list *); -void gf_tw_del_timer (struct gf_tw_timer_list *); +void gf_tw_del_timer (struct tvec_base *, struct gf_tw_timer_list *); + +int gf_tw_mod_timer_pending (struct tvec_base *, +                             struct gf_tw_timer_list *, unsigned long); + +int gf_tw_mod_timer (struct tvec_base *, +                     struct gf_tw_timer_list *, unsigned long);  #endif  | 
