Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 116339
b: refs/heads/master
c: 2d42244
h: refs/heads/master
i:
  116337: 3e736d5
  116335: cbcada4
v: v3
  • Loading branch information
John Stultz authored and Ingo Molnar committed Aug 21, 2008
1 parent 8b0bbbb commit 7739b63
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9a055117d3d9cb562f83f8d4cd88772761f4cab0
refs/heads/master: 2d42244ae71d6c7b0884b5664cf2eda30fb2ae68
3 changes: 3 additions & 0 deletions trunk/include/linux/clocksource.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ struct clocksource {
/* timekeeping specific data, ignore */
cycle_t cycle_interval;
u64 xtime_interval;
u32 raw_interval;
/*
* Second part is written at each timer interrupt
* Keep it in a different cache line to dirty no
Expand All @@ -87,6 +88,7 @@ struct clocksource {
cycle_t cycle_last ____cacheline_aligned_in_smp;
u64 xtime_nsec;
s64 error;
struct timespec raw_time;

#ifdef CONFIG_CLOCKSOURCE_WATCHDOG
/* Watchdog related data, used by the framework */
Expand Down Expand Up @@ -215,6 +217,7 @@ static inline void clocksource_calculate_interval(struct clocksource *c,

/* Go back from cycles -> shifted ns, this time use ntp adjused mult */
c->xtime_interval = (u64)c->cycle_interval * c->mult;
c->raw_interval = ((u64)c->cycle_interval * c->mult_orig) >> c->shift;
}


Expand Down
2 changes: 2 additions & 0 deletions trunk/include/linux/time.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ extern int do_setitimer(int which, struct itimerval *value,
extern unsigned int alarm_setitimer(unsigned int seconds);
extern int do_getitimer(int which, struct itimerval *value);
extern void getnstimeofday(struct timespec *tv);
extern void getrawmonotonic(struct timespec *ts);
extern void getboottime(struct timespec *ts);
extern void monotonic_to_bootbased(struct timespec *ts);

Expand Down Expand Up @@ -214,6 +215,7 @@ struct itimerval {
#define CLOCK_MONOTONIC 1
#define CLOCK_PROCESS_CPUTIME_ID 2
#define CLOCK_THREAD_CPUTIME_ID 3
#define CLOCK_MONOTONIC_RAW 4

/*
* The IDs of various hardware clocks:
Expand Down
15 changes: 15 additions & 0 deletions trunk/kernel/posix-timers.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,15 @@ static int posix_ktime_get_ts(clockid_t which_clock, struct timespec *tp)
return 0;
}

/*
* Get monotonic time for posix timers
*/
static int posix_get_monotonic_raw(clockid_t which_clock, struct timespec *tp)
{
getrawmonotonic(tp);
return 0;
}

/*
* Initialize everything, well, just everything in Posix clocks/timers ;)
*/
Expand All @@ -235,9 +244,15 @@ static __init int init_posix_timers(void)
.clock_get = posix_ktime_get_ts,
.clock_set = do_posix_clock_nosettime,
};
struct k_clock clock_monotonic_raw = {
.clock_getres = hrtimer_get_res,
.clock_get = posix_get_monotonic_raw,
.clock_set = do_posix_clock_nosettime,
};

register_posix_clock(CLOCK_REALTIME, &clock_realtime);
register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
register_posix_clock(CLOCK_MONOTONIC_RAW, &clock_monotonic_raw);

posix_timers_cache = kmem_cache_create("posix_timers_cache",
sizeof (struct k_itimer), 0, SLAB_PANIC,
Expand Down
44 changes: 44 additions & 0 deletions trunk/kernel/time/timekeeping.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ static void clocksource_forward_now(void)

nsec = cyc2ns(clock, cycle_delta);
timespec_add_ns(&xtime, nsec);

nsec = ((s64)cycle_delta * clock->mult_orig) >> clock->shift;
clock->raw_time.tv_nsec += nsec;
}

/**
Expand Down Expand Up @@ -183,6 +186,8 @@ static void change_clocksource(void)

clocksource_forward_now();

new->raw_time = clock->raw_time;

clock = new;
clock->cycle_last = 0;
clock->cycle_last = clocksource_read(new);
Expand All @@ -204,6 +209,39 @@ static inline void clocksource_forward_now(void) { }
static inline void change_clocksource(void) { }
#endif

/**
* getrawmonotonic - Returns the raw monotonic time in a timespec
* @ts: pointer to the timespec to be set
*
* Returns the raw monotonic time (completely un-modified by ntp)
*/
void getrawmonotonic(struct timespec *ts)
{
unsigned long seq;
s64 nsecs;
cycle_t cycle_now, cycle_delta;

do {
seq = read_seqbegin(&xtime_lock);

/* read clocksource: */
cycle_now = clocksource_read(clock);

/* calculate the delta since the last update_wall_time: */
cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;

/* convert to nanoseconds: */
nsecs = ((s64)cycle_delta * clock->mult_orig) >> clock->shift;

*ts = clock->raw_time;

} while (read_seqretry(&xtime_lock, seq));

timespec_add_ns(ts, nsecs);
}
EXPORT_SYMBOL(getrawmonotonic);


/**
* timekeeping_valid_for_hres - Check if timekeeping is suitable for hres
*/
Expand Down Expand Up @@ -466,6 +504,12 @@ void update_wall_time(void)
second_overflow();
}

clock->raw_time.tv_nsec += clock->raw_interval;
if (clock->raw_time.tv_nsec >= NSEC_PER_SEC) {
clock->raw_time.tv_nsec -= NSEC_PER_SEC;
clock->raw_time.tv_sec++;
}

/* accumulate error between NTP and clock interval */
clock->error += tick_length;
clock->error -= clock->xtime_interval << (NTP_SCALE_SHIFT - clock->shift);
Expand Down

0 comments on commit 7739b63

Please sign in to comment.