Module Name: src Committed By: christos Date: Sat Apr 23 23:08:26 UTC 2016
Modified Files: src/sys/kern: kern_time.c subr_time.c syscalls.master src/sys/sys: time.h Log Message: Add clock_getcpuclockid2(2) as well as CLOCK_{PROCESS,THREAD}_CPUTIME_ID. To generate a diff of this commit: cvs rdiff -u -r1.185 -r1.186 src/sys/kern/kern_time.c cvs rdiff -u -r1.17 -r1.18 src/sys/kern/subr_time.c cvs rdiff -u -r1.283 -r1.284 src/sys/kern/syscalls.master cvs rdiff -u -r1.71 -r1.72 src/sys/sys/time.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_time.c diff -u src/sys/kern/kern_time.c:1.185 src/sys/kern/kern_time.c:1.186 --- src/sys/kern/kern_time.c:1.185 Tue Mar 8 00:02:55 2016 +++ src/sys/kern/kern_time.c Sat Apr 23 19:08:26 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_time.c,v 1.185 2016/03/08 05:02:55 christos Exp $ */ +/* $NetBSD: kern_time.c,v 1.186 2016/04/23 23:08:26 christos Exp $ */ /*- * Copyright (c) 2000, 2004, 2005, 2007, 2008, 2009 The NetBSD Foundation, Inc. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.185 2016/03/08 05:02:55 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.186 2016/04/23 23:08:26 christos Exp $"); #include <sys/param.h> #include <sys/resourcevar.h> @@ -97,6 +97,7 @@ CTASSERT(ITIMER_VIRTUAL == CLOCK_VIRTUAL CTASSERT(ITIMER_PROF == CLOCK_PROF); CTASSERT(ITIMER_MONOTONIC == CLOCK_MONOTONIC); + /* * Initialize timekeeping. */ @@ -377,6 +378,36 @@ again: return error; } +int +sys_clock_getcpuclockid2(struct lwp *l, + const struct sys_clock_getcpuclockid2_args *uap, + register_t *retval) +{ + /* { + syscallarg(idtype_t idtype; + syscallarg(id_t id); + syscallarg(clockid_t *)clock_id; + } */ + pid_t pid; + lwpid_t lid; + clockid_t clock_id; + id_t id = SCARG(uap, id); + + switch (SCARG(uap, idtype)) { + case P_PID: + pid = id == 0 ? l->l_proc->p_pid : id; + clock_id = CLOCK_PROCESS_CPUTIME_ID | pid; + break; + case P_LWPID: + lid = id == 0 ? l->l_lid : id; + clock_id = CLOCK_THREAD_CPUTIME_ID | lid; + break; + default: + return EINVAL; + } + return copyout(&clock_id, SCARG(uap, clock_id), sizeof(clock_id)); +} + /* ARGSUSED */ int sys___gettimeofday50(struct lwp *l, const struct sys___gettimeofday50_args *uap, Index: src/sys/kern/subr_time.c diff -u src/sys/kern/subr_time.c:1.17 src/sys/kern/subr_time.c:1.18 --- src/sys/kern/subr_time.c:1.17 Wed May 22 12:00:52 2013 +++ src/sys/kern/subr_time.c Sat Apr 23 19:08:26 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_time.c,v 1.17 2013/05/22 16:00:52 christos Exp $ */ +/* $NetBSD: subr_time.c,v 1.18 2016/04/23 23:08:26 christos Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -33,15 +33,24 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_time.c,v 1.17 2013/05/22 16:00:52 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_time.c,v 1.18 2016/04/23 23:08:26 christos Exp $"); #include <sys/param.h> #include <sys/kernel.h> +#include <sys/proc.h> +#include <sys/kauth.h> +#include <sys/lwp.h> #include <sys/timex.h> #include <sys/time.h> #include <sys/timetc.h> #include <sys/intr.h> +#ifdef DEBUG_STICKS +#define DPRINTF(a) uprintf a +#else +#define DPRINTF(a) +#endif + /* * Compute number of hz until specified time. Used to compute second * argument to callout_reset() from an absolute time. @@ -218,9 +227,72 @@ gettimeleft(struct timespec *ts, struct return tstohz(ts); } +static void +ticks2ts(uint64_t ticks, struct timespec *ts) +{ + ts->tv_sec = ticks / hz; + uint64_t sticks = ticks - ts->tv_sec * hz; + if (sticks > 18446744073709551LL) /* floor(2^64 / 1000) */ + ts->tv_nsec = sticks / hz * 1000000000LL; + else if (sticks > 18446744073709LL) /* floor(2^64 / 1000000) */ + ts->tv_nsec = sticks * 1000LL / hz * 1000000LL; + else + ts->tv_nsec = sticks * 1000000000LL / hz; + DPRINTF(("%s: %ju/%ju -> %ju.%ju\n", __func__, + (uintmax_t)ticks, (uintmax_t)sticks, + (uintmax_t)ts->tv_sec, (uintmax_t)ts->tv_nsec)); +} + int clock_gettime1(clockid_t clock_id, struct timespec *ts) { + int error; + uint64_t ticks; + struct proc *p; + +#define CPUCLOCK_ID_MASK (~(CLOCK_THREAD_CPUTIME_ID|CLOCK_PROCESS_CPUTIME_ID)) + if (clock_id & CLOCK_PROCESS_CPUTIME_ID) { + pid_t pid = clock_id & CPUCLOCK_ID_MASK; + + mutex_enter(proc_lock); + p = pid == 0 ? curproc : proc_find(pid); + if (p == NULL) { + mutex_exit(proc_lock); + return ESRCH; + } + ticks = p->p_uticks + p->p_sticks + p->p_iticks; + DPRINTF(("%s: u=%ju, s=%ju, i=%ju\n", __func__, + (uintmax_t)p->p_uticks, (uintmax_t)p->p_sticks, + (uintmax_t)p->p_iticks)); + mutex_exit(proc_lock); + + // XXX: Perhaps create a special kauth type + error = kauth_authorize_process(curlwp->l_cred, + KAUTH_PROCESS_PTRACE, p, + KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL); + if (error) + return error; + } else if (clock_id & CLOCK_THREAD_CPUTIME_ID) { + struct lwp *l; + lwpid_t lid = clock_id & CPUCLOCK_ID_MASK; + p = curproc; + mutex_enter(p->p_lock); + l = lid == 0 ? curlwp : lwp_find(p, lid); + if (l == NULL) { + mutex_exit(p->p_lock); + return ESRCH; + } + ticks = l->l_rticksum + l->l_slpticksum; + DPRINTF(("%s: r=%ju, s=%ju\n", __func__, + (uintmax_t)l->l_rticksum, (uintmax_t)l->l_slpticksum)); + mutex_exit(p->p_lock); + } else + ticks = (uint64_t)-1; + + if (ticks != (uint64_t)-1) { + ticks2ts(ticks, ts); + return 0; + } switch (clock_id) { case CLOCK_REALTIME: Index: src/sys/kern/syscalls.master diff -u src/sys/kern/syscalls.master:1.283 src/sys/kern/syscalls.master:1.284 --- src/sys/kern/syscalls.master:1.283 Sat Apr 2 21:00:26 2016 +++ src/sys/kern/syscalls.master Sat Apr 23 19:08:26 2016 @@ -1,4 +1,4 @@ - $NetBSD: syscalls.master,v 1.283 2016/04/03 01:00:26 christos Exp $ + $NetBSD: syscalls.master,v 1.284 2016/04/23 23:08:26 christos Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 @@ -983,3 +983,5 @@ 481 STD { int|sys||wait6(idtype_t idtype, id_t id, \ int *status, int options, struct wrusage *wru, \ siginfo_t *info); } +482 STD { int|sys||clock_getcpuclockid2(idtype_t idtype, \ + id_t id, clockid_t *clock_id); } Index: src/sys/sys/time.h diff -u src/sys/sys/time.h:1.71 src/sys/sys/time.h:1.72 --- src/sys/sys/time.h:1.71 Thu Dec 24 10:53:06 2015 +++ src/sys/sys/time.h Sat Apr 23 19:08:26 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: time.h,v 1.71 2015/12/24 15:53:06 christos Exp $ */ +/* $NetBSD: time.h,v 1.72 2016/04/23 23:08:26 christos Exp $ */ /* * Copyright (c) 1982, 1986, 1993 @@ -284,6 +284,8 @@ struct itimerspec { #define CLOCK_VIRTUAL 1 #define CLOCK_PROF 2 #define CLOCK_MONOTONIC 3 +#define CLOCK_THREAD_CPUTIME_ID 0x80000000 +#define CLOCK_PROCESS_CPUTIME_ID 0x40000000 #if defined(_NETBSD_SOURCE) #define TIMER_RELTIME 0x0 /* relative timer */