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:
parent
e9290dc0db
commit
eaf3bfa188
@ -85,11 +85,12 @@ apply_slack(struct tvec_base *base, struct gf_tw_timer_list *timer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
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;
|
struct list_head *entry = &timer->entry;
|
||||||
|
|
||||||
list_del (entry);
|
list_del (entry);
|
||||||
|
entry->next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
@ -141,7 +142,7 @@ run_timers (struct tvec_base *base)
|
|||||||
fn = timer->function;
|
fn = timer->function;
|
||||||
data = timer->data;
|
data = timer->data;
|
||||||
|
|
||||||
gf_tw_detach_timer (timer);
|
__gf_tw_detach_timer (timer);
|
||||||
fn (timer, data, call_time);
|
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 */
|
/* 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
|
* 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)
|
int gf_tw_cleanup_timers (struct tvec_base *base)
|
||||||
|
@ -66,6 +66,12 @@ struct gf_tw_timer_list {
|
|||||||
struct tvec_base *gf_tw_init_timers ();
|
struct tvec_base *gf_tw_init_timers ();
|
||||||
int gf_tw_cleanup_timers (struct tvec_base *);
|
int gf_tw_cleanup_timers (struct tvec_base *);
|
||||||
void gf_tw_add_timer (struct tvec_base *, struct gf_tw_timer_list *);
|
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
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user