There are several functions that might seem appropriate for a timestamp:
get_cycles()
current_kernel_time()
do_gettimeofday()
<read jiffies/jiffies_64>
Each has problems with combinations of SMP-safety, low resolution, and
monotonicity. This patch adds a new function that returns a monotonic SMP-safe
timestamp with nanosecond resolution where available.
Changes:
Split timestamp into separate patch
Moved to kernel/time.c
Renamed to getnstimestamp
Fixed unintended-pointer-arithmetic bug
Signed-off-by: Matt Helsley <matthltc@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
extern int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue);
extern int do_getitimer(int which, struct itimerval *value);
extern void getnstimeofday (struct timespec *tv);
extern int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue);
extern int do_getitimer(int which, struct itimerval *value);
extern void getnstimeofday (struct timespec *tv);
+extern void getnstimestamp(struct timespec *ts);
extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
EXPORT_SYMBOL_GPL(getnstimeofday);
#endif
EXPORT_SYMBOL_GPL(getnstimeofday);
#endif
+void getnstimestamp(struct timespec *ts)
+{
+ unsigned int seq;
+ struct timespec wall2mono;
+
+ /* synchronize with settimeofday() changes */
+ do {
+ seq = read_seqbegin(&xtime_lock);
+ getnstimeofday(ts);
+ wall2mono = wall_to_monotonic;
+ } while(unlikely(read_seqretry(&xtime_lock, seq)));
+
+ /* adjust to monotonicaly-increasing values */
+ ts->tv_sec += wall2mono.tv_sec;
+ ts->tv_nsec += wall2mono.tv_nsec;
+ while (unlikely(ts->tv_nsec >= NSEC_PER_SEC)) {
+ ts->tv_nsec -= NSEC_PER_SEC;
+ ts->tv_sec++;
+ }
+}
+EXPORT_SYMBOL_GPL(getnstimestamp);
+
#if (BITS_PER_LONG < 64)
u64 get_jiffies_64(void)
{
#if (BITS_PER_LONG < 64)
u64 get_jiffies_64(void)
{