kernel - Add additional clock_gettime() modes
authorMatthew Dillon <dillon@apollo.backplane.com>
Fri, 24 Aug 2012 07:44:54 +0000 (00:44 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Fri, 24 Aug 2012 07:44:54 +0000 (00:44 -0700)
* Add the following:
CLOCK_UPTIME (same as MONOTONIC)
CLOCK_UPTIME_PRECISE (same as MONOTONIC)
CLOCK_UPTIME_FAST (faster, less precise)
CLOCK_REALTIME_PRECISE (same as REALTIME)
CLOCK_REALTIME_FAST (faster, less precise)
CLOCK_MONOTONIC_PRECISE (same as MONOTONIC)
CLOCK_MONOTONIC_FAST (faster, less precise)
CLOCK_SECOND (just returns 'time_second')

Taken-from: FreeBSD

include/time.h
sys/kern/kern_time.c
sys/sys/time.h

index f0ec9cd..755b002 100644 (file)
@@ -95,12 +95,21 @@ typedef     __timer_t       timer_t;
 
 /* These macros are also in sys/time.h. */
 #if !defined(CLOCK_REALTIME) && __POSIX_VISIBLE >= 200112
-#define CLOCK_REALTIME  0
+#define CLOCK_REALTIME         0
 #ifdef __BSD_VISIBLE
-#define CLOCK_VIRTUAL  1
-#define CLOCK_PROF     2
+#define CLOCK_VIRTUAL          1
+#define CLOCK_PROF             2
 #endif
-#define CLOCK_MONOTONIC        4
+#define CLOCK_MONOTONIC                4       /* from freebsd */
+#define CLOCK_UPTIME           5       /* from freebsd */
+#define CLOCK_UPTIME_PRECISE   7       /* from freebsd */
+#define CLOCK_UPTIME_FAST      8       /* from freebsd */
+#define CLOCK_REALTIME_PRECISE 9       /* from freebsd */
+#define CLOCK_REALTIME_FAST    10      /* from freebsd */
+#define CLOCK_MONOTONIC_PRECISE        11      /* from freebsd */
+#define CLOCK_MONOTONIC_FAST   12      /* from freebsd */
+#define CLOCK_SECOND           13      /* from freebsd */
+
 #endif /* !defined(CLOCK_REALTIME) && __POSIX_VISIBLE >= 200112 */
 
 #if !defined(TIMER_ABSTIME) && __POSIX_VISIBLE >= 200112
index 1bf4105..20cbda9 100644 (file)
@@ -159,14 +159,42 @@ int
 kern_clock_gettime(clockid_t clock_id, struct timespec *ats)
 {
        int error = 0;
+       struct proc *p;
 
        switch(clock_id) {
        case CLOCK_REALTIME:
+       case CLOCK_REALTIME_PRECISE:
                nanotime(ats);
                break;
+       case CLOCK_REALTIME_FAST:
+               getnanotime(ats);
+               break;
        case CLOCK_MONOTONIC:
+       case CLOCK_MONOTONIC_PRECISE:
+       case CLOCK_UPTIME:
+       case CLOCK_UPTIME_PRECISE:
                nanouptime(ats);
                break;
+       case CLOCK_MONOTONIC_FAST:
+       case CLOCK_UPTIME_FAST:
+               getnanouptime(ats);
+               break;
+       case CLOCK_VIRTUAL:
+               p = curproc;
+               ats->tv_sec = p->p_timer[ITIMER_VIRTUAL].it_value.tv_sec;
+               ats->tv_nsec = p->p_timer[ITIMER_VIRTUAL].it_value.tv_usec *
+                              1000;
+               break;
+       case CLOCK_PROF:
+               p = curproc;
+               ats->tv_sec = p->p_timer[ITIMER_PROF].it_value.tv_sec;
+               ats->tv_nsec = p->p_timer[ITIMER_PROF].it_value.tv_usec *
+                              1000;
+               break;
+       case CLOCK_SECOND:
+               ats->tv_sec = time_second;
+               ats->tv_nsec = 0;
+               break;
        default:
                error = EINVAL;
                break;
@@ -237,7 +265,14 @@ kern_clock_getres(clockid_t clock_id, struct timespec *ts)
 
        switch(clock_id) {
        case CLOCK_REALTIME:
+       case CLOCK_REALTIME_FAST:
+       case CLOCK_REALTIME_PRECISE:
        case CLOCK_MONOTONIC:
+       case CLOCK_MONOTONIC_FAST:
+       case CLOCK_MONOTONIC_PRECISE:
+       case CLOCK_UPTIME:
+       case CLOCK_UPTIME_FAST:
+       case CLOCK_UPTIME_PRECISE:
                /*
                 * Round up the result of the division cheaply
                 * by adding 1.  Rounding up is especially important
@@ -248,6 +283,18 @@ kern_clock_getres(clockid_t clock_id, struct timespec *ts)
                ts->tv_nsec = 1000000000 / sys_cputimer->freq + 1;
                error = 0;
                break;
+       case CLOCK_VIRTUAL:
+       case CLOCK_PROF:
+               /* Accurately round up here because we can do so cheaply. */
+               ts->tv_sec = 0;
+               ts->tv_nsec = (1000000000 + hz - 1) / hz;
+               error = 0;
+               break;
+       case CLOCK_SECOND:
+               ts->tv_sec = 1;
+               ts->tv_nsec = 0;
+               error = 0;
+               break;
        default:
                error = EINVAL;
                break;
index cd54de1..3957672 100644 (file)
@@ -167,11 +167,20 @@ struct clockinfo {
 /* CLOCK_REALTIME and TIMER_ABSTIME are supposed to be in time.h */
 
 #ifndef CLOCK_REALTIME
-#define CLOCK_REALTIME 0
+#define CLOCK_REALTIME         0
 #endif
-#define CLOCK_VIRTUAL  1
-#define CLOCK_PROF     2
-#define CLOCK_MONOTONIC        4
+#define CLOCK_VIRTUAL          1
+#define CLOCK_PROF             2
+#define CLOCK_MONOTONIC                4
+
+#define CLOCK_UPTIME           5       /* from freebsd */
+#define CLOCK_UPTIME_PRECISE   7       /* from freebsd */
+#define CLOCK_UPTIME_FAST      8       /* from freebsd */
+#define CLOCK_REALTIME_PRECISE 9       /* from freebsd */
+#define CLOCK_REALTIME_FAST    10      /* from freebsd */
+#define CLOCK_MONOTONIC_PRECISE        11      /* from freebsd */
+#define CLOCK_MONOTONIC_FAST   12      /* from freebsd */
+#define CLOCK_SECOND           13      /* from freebsd */
 
 #define TIMER_RELTIME  0x0     /* relative timer */
 #ifndef TIMER_ABSTIME