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>
This commit is contained in:
Venky Shankar 2015-05-22 11:54:11 +05:30 committed by Vijay Bellur
parent e9290dc0db
commit eaf3bfa188
2 changed files with 89 additions and 5 deletions

View File

@ -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)

View File

@ -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