getmonotonictime system call and patch for evdev to use such time
Subsystems (2)
PATCH 1/1 getmonotonictime system call and patch for evdev to use such time
Events from the evdev device are timestamped with gettimeofday. If a userland application wants to see a duration of a key press, all it can do is look at the 2 timestamps.
If settimeofday is called in between, it will see a false duration, which is not what it needs. So, for my needs I only want the monotonic (since boot) time. I understand, that someone else might want to maintain compatibility, and have the kind of time selectable (ioctl), but that's above my current kernel knowledge.
If no event arrives I would still like to measure the progressed duration, and thus get the monotonic time, so a system call getmonotonictime is needed.
I found do_posix_clock_monotonic_gettime and made simple wrapper around it. I do NOT claim i know how to add a new system call! And it's i386 only.
All i did is testing with simple:
struct timeval tp; syscall(289, &tv);
arch/i386/kernel/syscall_table.S +1 -0
@@ -289,3 +289,4 @@ .long sys_add_key .long sys_request_key .long sys_keyctl + .long sys_getmonotonictime
drivers/input/evdev.c +2 -2
@@ -52,7 +52,7 @@if (evdev->grab) { list = evdev->grab; -do_gettimeofday (&list->buffer[list->head].time); +do_getmonotonictime (&list->buffer[list->head].time); list->buffer[list->head].type = type; list->buffer[list->head].code = code; list->buffer[list->head].value = value;
@@ -62,7 +62,7 @@ }else list_for_each_entry (list, &evdev->list, node) { -do_gettimeofday (&list->buffer[list->head].time); +do_getmonotonictime (&list->buffer[list->head].time); list->buffer[list->head].type = type; list->buffer[list->head].code = code; list->buffer[list->head].value = value;
include/linux/time.h +1 -0
@@ -92,6 +92,7 @@#define CURRENT_TIME (current_kernel_time())#define CURRENT_TIME_SEC ((struct timespec) { xtime.tv_sec, 0 }) +extern void do_getmonotonictime (struct timeval *tv);extern void do_gettimeofday (struct timeval *tv);extern int do_settimeofday (struct timespec *tv);extern int do_sys_settimeofday (struct timespec *tv,struct timezone *tz);
kernel/time.c +31 -1
@@ -5,7 +5,7 @@* * This file contains the interface functions for the various * time related system calls: time, stime, gettimeofday, settimeofday, -* adjtime +* adjtime, getmonotonictime */ /* * Modification history kernel/time.c
@@ -25,6 +25,9 @@* 2004-07-14 Christoph Lameter * Added getnstimeofday to allow the posix timer functions to return * with nanosecond accuracy +* 2005-06-19 Michal Maruska +* Added getmonotonictime to provide time and (input event) timestamps +* independent of time changes (settimeofday) */ #include <linux/module.h>
@@ -112,6 +115,33 @@return 0 ; } +asmlinkage long sys_getmonotonictime (struct timeval __user *tv) +{ +if (likely (tv !=NULL )) { +struct timeval ktv; +do_getmonotonictime (&ktv); +/* indeed it works! */ +/* printk("%s\n", __FUNCTION__); */ +if (copy_to_user (tv, &ktv,sizeof (ktv))) +return -EFAULT ; + } +return 0 ; +} + + +void do_getmonotonictime (struct timeval *tv) +{ +struct timespec kts; +if (unlikely (tv ==NULL ))return ;/* should not happen */ + +do_posix_clock_monotonic_gettime (&kts); +/* transform the "struct timespec" into "struct timeval" */ + tv->tv_sec = kts.tv_sec; + tv->tv_usec = kts.tv_nsec /NSEC_PER_USEC ; +} + +EXPORT_SYMBOL (do_getmonotonictime); +/* * Adjust the time obtained from the CMOS to be UTC time instead of * local time.
Quoted 2 lines · Michal Maruška
I found
do_posix_clock_monotonic_gettimeand made simple wrapper around it. I do NOT claim i know how to add a new system call! And it's i386 only.
There is a system call already.
man clock_gettime
tglx