summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_time.c
diff options
context:
space:
mode:
authorkbyanc <kbyanc@FreeBSD.org>2004-06-17 23:12:12 +0000
committerkbyanc <kbyanc@FreeBSD.org>2004-06-17 23:12:12 +0000
commitc81446b87e30e802d2709e404e0983c5b774648b (patch)
tree852ebf25daee947b8463cb5defcb56f042dbb5f2 /sys/kern/kern_time.c
parent855c4bb01f3e0dbfe6a96552fcb25a1aaf5de4cc (diff)
downloadFreeBSD-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.c48
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);
}
OpenPOWER on IntegriCloud