diff options
author | kbyanc <kbyanc@FreeBSD.org> | 2004-06-17 23:12:12 +0000 |
---|---|---|
committer | kbyanc <kbyanc@FreeBSD.org> | 2004-06-17 23:12:12 +0000 |
commit | c81446b87e30e802d2709e404e0983c5b774648b (patch) | |
tree | 852ebf25daee947b8463cb5defcb56f042dbb5f2 /sys/kern/kern_time.c | |
parent | 855c4bb01f3e0dbfe6a96552fcb25a1aaf5de4cc (diff) | |
download | FreeBSD-src-c81446b87e30e802d2709e404e0983c5b774648b.zip FreeBSD-src-c81446b87e30e802d2709e404e0983c5b774648b.tar.gz |
Implement CLOCK_VIRTUAL and CLOCK_PROF for clock_gettime(2) and
clock_getres(2).
Reviewed by: phk
PR: 23304
Diffstat (limited to 'sys/kern/kern_time.c')
-rw-r--r-- | sys/kern/kern_time.c | 48 |
1 files changed, 39 insertions, 9 deletions
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index 6e37cb4..3f11710 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -156,13 +156,31 @@ int clock_gettime(struct thread *td, struct clock_gettime_args *uap) { struct timespec ats; + struct timeval user, sys; - if (uap->clock_id == CLOCK_REALTIME) + switch (uap->clock_id) { + case CLOCK_REALTIME: nanotime(&ats); - else if (uap->clock_id == CLOCK_MONOTONIC) + break; + case CLOCK_MONOTONIC: nanouptime(&ats); - else + break; + case CLOCK_VIRTUAL: + calcru(td->td_proc, &user, &sys, NULL); + TIMEVAL_TO_TIMESPEC(&user, &ats); + break; + case CLOCK_PROF: + calcru(td->td_proc, &user, &sys, NULL); + ats.tv_sec = user.tv_sec + sys.tv_sec; + ats.tv_nsec = (user.tv_usec + sys.tv_usec) * 1000; + if (ats.tv_nsec > 1000000000) { + ats.tv_sec++; + ats.tv_nsec -= 1000000000; + } + break; + default: return (EINVAL); + } return (copyout(&ats, uap->tp, sizeof(ats))); } @@ -216,19 +234,31 @@ clock_getres(struct thread *td, struct clock_getres_args *uap) struct timespec ts; int error; - if (uap->clock_id != CLOCK_REALTIME) - return (EINVAL); - error = 0; - if (uap->tp) { - ts.tv_sec = 0; + ts.tv_sec = 0; + + switch (uap->clock_id) { + case CLOCK_REALTIME: + case CLOCK_MONOTONIC: /* * Round up the result of the division cheaply by adding 1. * Rounding up is especially important if rounding down * would give 0. Perfect rounding is unimportant. */ ts.tv_nsec = 1000000000 / tc_getfrequency() + 1; - error = copyout(&ts, uap->tp, sizeof(ts)); + break; + case CLOCK_VIRTUAL: + case CLOCK_PROF: + /* Accurately round up here because we can do so cheaply. */ + ts.tv_nsec = (1000000000 + hz - 1) / hz; + break; + default: + return (EINVAL); } + + error = 0; + if (uap->tp) + error = copyout(&ts, uap->tp, sizeof(ts)); + return (error); } |