Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 192247
b: refs/heads/master
c: 3bbb9ec
h: refs/heads/master
i:
  192245: ffdc3fc
  192243: b77ee26
  192239: aab1c53
v: v3
  • Loading branch information
Arjan van de Ven authored and Thomas Gleixner committed Apr 6, 2010
1 parent e68d87c commit 7cc30d8
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3d0205bd1383aa3cac93c209b7c7d03b27930195
refs/heads/master: 3bbb9ec946428b96657126768f65487a48dd090c
10 changes: 9 additions & 1 deletion trunk/include/linux/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,19 @@
struct tvec_base;

struct timer_list {
/*
* All fields that change during normal runtime grouped to the
* same cacheline
*/
struct list_head entry;
unsigned long expires;
struct tvec_base *base;

void (*function)(unsigned long);
unsigned long data;

struct tvec_base *base;
int slack;

#ifdef CONFIG_TIMER_STATS
void *start_site;
char start_comm[16];
Expand Down Expand Up @@ -165,6 +171,8 @@ extern int mod_timer(struct timer_list *timer, unsigned long expires);
extern int mod_timer_pending(struct timer_list *timer, unsigned long expires);
extern int mod_timer_pinned(struct timer_list *timer, unsigned long expires);

extern void set_timer_slack(struct timer_list *time, int slack_hz);

#define TIMER_NOT_PINNED 0
#define TIMER_PINNED 1
/*
Expand Down
56 changes: 56 additions & 0 deletions trunk/kernel/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,24 @@ unsigned long round_jiffies_up_relative(unsigned long j)
}
EXPORT_SYMBOL_GPL(round_jiffies_up_relative);

/**
* set_timer_slack - set the allowed slack for a timer
* @slack_hz: the amount of time (in jiffies) allowed for rounding
*
* Set the amount of time, in jiffies, that a certain timer has
* in terms of slack. By setting this value, the timer subsystem
* will schedule the actual timer somewhere between
* the time mod_timer() asks for, and that time plus the slack.
*
* By setting the slack to -1, a percentage of the delay is used
* instead.
*/
void set_timer_slack(struct timer_list *timer, int slack_hz)
{
timer->slack = slack_hz;
}
EXPORT_SYMBOL_GPL(set_timer_slack);


static inline void set_running_timer(struct tvec_base *base,
struct timer_list *timer)
Expand Down Expand Up @@ -549,6 +567,7 @@ static void __init_timer(struct timer_list *timer,
{
timer->entry.next = NULL;
timer->base = __raw_get_cpu_var(tvec_bases);
timer->slack = -1;
#ifdef CONFIG_TIMER_STATS
timer->start_site = NULL;
timer->start_pid = -1;
Expand Down Expand Up @@ -714,6 +733,41 @@ int mod_timer_pending(struct timer_list *timer, unsigned long expires)
}
EXPORT_SYMBOL(mod_timer_pending);

/*
* Decide where to put the timer while taking the slack into account
*
* Algorithm:
* 1) calculate the maximum (absolute) time
* 2) calculate the highest bit where the expires and new max are different
* 3) use this bit to make a mask
* 4) use the bitmask to round down the maximum time, so that all last
* bits are zeros
*/
static inline
unsigned long apply_slack(struct timer_list *timer, unsigned long expires)
{
unsigned long expires_limit, mask;
int bit;

expires_limit = expires + timer->slack;

if (timer->slack < 0) /* auto slack: use 0.4% */
expires_limit = expires + (expires - jiffies)/256;

mask = expires ^ expires_limit;

if (mask == 0)
return expires;

bit = find_last_bit(&mask, BITS_PER_LONG);

mask = (1 << bit) - 1;

expires_limit = expires_limit & ~(mask);

return expires_limit;
}

/**
* mod_timer - modify a timer's timeout
* @timer: the timer to be modified
Expand Down Expand Up @@ -744,6 +798,8 @@ int mod_timer(struct timer_list *timer, unsigned long expires)
if (timer_pending(timer) && timer->expires == expires)
return 1;

expires = apply_slack(timer, expires);

return __mod_timer(timer, expires, false, TIMER_NOT_PINNED);
}
EXPORT_SYMBOL(mod_timer);
Expand Down

0 comments on commit 7cc30d8

Please sign in to comment.