Index: kern/init_sysent.c =================================================================== RCS file: /cvsroot/src/sys/kern/init_sysent.c,v retrieving revision 1.309 diff -u -p -u -r1.309 init_sysent.c --- kern/init_sysent.c 3 Apr 2016 01:22:39 -0000 1.309 +++ kern/init_sysent.c 23 Apr 2016 19:57:58 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: init_sysent.c,v 1.309 2016/04/03 01:22:39 christos Exp $ */ +/* $NetBSD$ */ /* * System call switch table. @@ -8,7 +8,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: init_sysent.c,v 1.309 2016/04/03 01:22:39 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD$"); #include "opt_modular.h" #include "opt_ntp.h" @@ -2323,8 +2323,10 @@ struct sysent sysent[] = { .sy_call = (sy_call_t *)sys_wait6 }, /* 481 = wait6 */ { - .sy_call = sys_nosys, - }, /* 482 = filler */ + ns(struct sys_clock_getcpuclockid2_args), + .sy_flags = SYCALL_ARG_PTR, + .sy_call = (sy_call_t *)sys_clock_getcpuclockid2 + }, /* 482 = clock_getcpuclockid2 */ { .sy_call = sys_nosys, }, /* 483 = filler */ Index: kern/kern_time.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_time.c,v retrieving revision 1.185 diff -u -p -u -r1.185 kern_time.c --- kern/kern_time.c 8 Mar 2016 05:02:55 -0000 1.185 +++ kern/kern_time.c 23 Apr 2016 19:57:58 -0000 @@ -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 = MAKE_PROC_CPUCLOCK(pid); + break; + case P_LWPID: + lid = id == 0 ? l->l_lid : id; + clock_id = MAKE_LWP_CPUCLOCK(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: kern/subr_time.c =================================================================== RCS file: /cvsroot/src/sys/kern/subr_time.c,v retrieving revision 1.17 diff -u -p -u -r1.17 subr_time.c --- kern/subr_time.c 22 May 2013 16:00:52 -0000 1.17 +++ kern/subr_time.c 23 Apr 2016 19:57:58 -0000 @@ -37,6 +37,9 @@ __KERNEL_RCSID(0, "$NetBSD: subr_time.c, #include #include +#include +#include +#include #include #include #include @@ -218,9 +221,61 @@ gettimeleft(struct timespec *ts, struct return tstohz(ts); } +static void +ticks2ts(uint64_t ticks, struct timespec *ts) +{ + ticks /= hz; + if (ticks > 18446744073709551LL) /* floor(2^64 / 1000) */ + ts->tv_nsec = ticks / hz * 1000000000LL; + else if (ticks > 18446744073709LL) /* floor(2^64 / 1000000) */ + ts->tv_nsec = ticks * 1000LL / hz * 1000000LL; + else + ts->tv_nsec = ticks * 1000000000LL / hz; + ts->tv_sec = tick / hz; +} + int clock_gettime1(clockid_t clock_id, struct timespec *ts) { + int error; + uint64_t ticks; + struct proc *p; + + if (clock_id & CPUCLOCK_PROC_BIT) { + pid_t pid = clock_id & CPUCLOCK_ID_MASK; + + mutex_enter(proc_lock); + p = proc_find(pid); + if (p == NULL) { + mutex_exit(proc_lock); + return ESRCH; + } + ticks = p->p_uticks + p->p_sticks + 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 & CPUCLOCK_LWP_BIT) { + struct lwp *l; + lwpid_t lid = clock_id & CPUCLOCK_ID_MASK; + p = curproc; + mutex_enter(p->p_lock); + if ((l = lwp_find(p, lid)) == NULL) { + mutex_exit(p->p_lock); + return ESRCH; + } + ticks = l->l_rticksum + l->l_slpticksum; + } else + ticks = (uint64_t)-1; + + if (ticks != (uint64_t)-1) { + ticks2ts(ticks, ts); + return 0; + } switch (clock_id) { case CLOCK_REALTIME: Index: kern/syscalls.c =================================================================== RCS file: /cvsroot/src/sys/kern/syscalls.c,v retrieving revision 1.299 diff -u -p -u -r1.299 syscalls.c --- kern/syscalls.c 3 Apr 2016 01:22:39 -0000 1.299 +++ kern/syscalls.c 23 Apr 2016 19:57:58 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: syscalls.c,v 1.299 2016/04/03 01:22:39 christos Exp $ */ +/* $NetBSD$ */ /* * System call names. @@ -8,7 +8,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: syscalls.c,v 1.299 2016/04/03 01:22:39 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD$"); #if defined(_KERNEL_OPT) #include "opt_modular.h" @@ -529,7 +529,7 @@ const char *const syscallnames[] = { /* 479 */ "posix_fallocate", /* 480 */ "fdiscard", /* 481 */ "wait6", - /* 482 */ "# filler", + /* 482 */ "clock_getcpuclockid2", /* 483 */ "# filler", /* 484 */ "# filler", /* 485 */ "# filler", @@ -1066,7 +1066,7 @@ const char *const altsyscallnames[] = { /* 479 */ NULL, /* posix_fallocate */ /* 480 */ NULL, /* fdiscard */ /* 481 */ NULL, /* wait6 */ - /* 482 */ NULL, /* filler */ + /* 482 */ NULL, /* clock_getcpuclockid2 */ /* 483 */ NULL, /* filler */ /* 484 */ NULL, /* filler */ /* 485 */ NULL, /* filler */ Index: kern/syscalls.master =================================================================== RCS file: /cvsroot/src/sys/kern/syscalls.master,v retrieving revision 1.283 diff -u -p -u -r1.283 syscalls.master --- kern/syscalls.master 3 Apr 2016 01:00:26 -0000 1.283 +++ kern/syscalls.master 23 Apr 2016 19:57:58 -0000 @@ -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: kern/syscalls_autoload.c =================================================================== RCS file: /cvsroot/src/sys/kern/syscalls_autoload.c,v retrieving revision 1.18 diff -u -p -u -r1.18 syscalls_autoload.c --- kern/syscalls_autoload.c 3 Apr 2016 01:22:39 -0000 1.18 +++ kern/syscalls_autoload.c 23 Apr 2016 19:57:59 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: syscalls_autoload.c,v 1.18 2016/04/03 01:22:39 christos Exp $ */ +/* $NetBSD$ */ /* * System call autoload table. @@ -8,7 +8,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: syscalls_autoload.c,v 1.18 2016/04/03 01:22:39 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD$"); #include static struct sc_autoload netbsd_syscalls_autoload[] = { Index: kern/systrace_args.c =================================================================== RCS file: /cvsroot/src/sys/kern/systrace_args.c,v retrieving revision 1.18 diff -u -p -u -r1.18 systrace_args.c --- kern/systrace_args.c 3 Apr 2016 01:22:39 -0000 1.18 +++ kern/systrace_args.c 23 Apr 2016 19:57:59 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: systrace_args.c,v 1.18 2016/04/03 01:22:39 christos Exp $ */ +/* $NetBSD$ */ /* * System call argument to DTrace register array converstion. @@ -3669,6 +3669,15 @@ systrace_args(register_t sysnum, const v *n_args = 6; break; } + /* sys_clock_getcpuclockid2 */ + case 482: { + struct sys_clock_getcpuclockid2_args *p = params; + iarg[0] = SCARG(p, idtype); /* idtype_t */ + iarg[1] = SCARG(p, id); /* id_t */ + uarg[2] = (intptr_t) SCARG(p, clock_id); /* clockid_t * */ + *n_args = 3; + break; + } default: *n_args = 0; break; @@ -9884,6 +9893,22 @@ systrace_entry_setargdesc(int sysnum, in break; }; break; + /* sys_clock_getcpuclockid2 */ + case 482: + switch(ndx) { + case 0: + p = "idtype_t"; + break; + case 1: + p = "id_t"; + break; + case 2: + p = "clockid_t *"; + break; + default: + break; + }; + break; default: break; }; @@ -11966,6 +11991,11 @@ systrace_return_setargdesc(int sysnum, i if (ndx == 0 || ndx == 1) p = "int"; break; + /* sys_clock_getcpuclockid2 */ + case 482: + if (ndx == 0 || ndx == 1) + p = "int"; + break; default: break; }; Index: sys/syscall.h =================================================================== RCS file: /cvsroot/src/sys/sys/syscall.h,v retrieving revision 1.293 diff -u -p -u -r1.293 syscall.h --- sys/syscall.h 3 Apr 2016 01:22:39 -0000 1.293 +++ sys/syscall.h 23 Apr 2016 19:57:59 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: syscall.h,v 1.293 2016/04/03 01:22:39 christos Exp $ */ +/* $NetBSD$ */ /* * System call numbers. @@ -1328,6 +1328,9 @@ /* syscall: "wait6" ret: "int" args: "idtype_t" "id_t" "int *" "int" "struct wrusage *" "siginfo_t *" */ #define SYS_wait6 481 -#define SYS_MAXSYSCALL 482 +/* syscall: "clock_getcpuclockid2" ret: "int" args: "idtype_t" "id_t" "clockid_t *" */ +#define SYS_clock_getcpuclockid2 482 + +#define SYS_MAXSYSCALL 483 #define SYS_NSYSENT 512 #endif /* _SYS_SYSCALL_H_ */ Index: sys/syscallargs.h =================================================================== RCS file: /cvsroot/src/sys/sys/syscallargs.h,v retrieving revision 1.277 diff -u -p -u -r1.277 syscallargs.h --- sys/syscallargs.h 3 Apr 2016 01:22:39 -0000 1.277 +++ sys/syscallargs.h 23 Apr 2016 19:57:59 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: syscallargs.h,v 1.277 2016/04/03 01:22:39 christos Exp $ */ +/* $NetBSD$ */ /* * System call argument lists. @@ -3141,6 +3141,15 @@ struct sys_wait6_args { check_syscall_args(sys_wait6) #endif /* !RUMP_CLIENT */ +#ifndef RUMP_CLIENT +struct sys_clock_getcpuclockid2_args { + syscallarg(idtype_t) idtype; + syscallarg(id_t) id; + syscallarg(clockid_t *) clock_id; +}; +check_syscall_args(sys_clock_getcpuclockid2) +#endif /* !RUMP_CLIENT */ + /* * System call prototypes. */ @@ -4017,5 +4026,7 @@ int sys_fdiscard(struct lwp *, const str int sys_wait6(struct lwp *, const struct sys_wait6_args *, register_t *); +int sys_clock_getcpuclockid2(struct lwp *, const struct sys_clock_getcpuclockid2_args *, register_t *); + #endif /* !RUMP_CLIENT */ #endif /* _SYS_SYSCALLARGS_H_ */ Index: sys/time.h =================================================================== RCS file: /cvsroot/src/sys/sys/time.h,v retrieving revision 1.71 diff -u -p -u -r1.71 time.h --- sys/time.h 24 Dec 2015 15:53:06 -0000 1.71 +++ sys/time.h 23 Apr 2016 19:57:59 -0000 @@ -292,6 +292,11 @@ struct itimerspec { #ifdef _KERNEL #include +#define CPUCLOCK_LWP_BIT 0x80000000 +#define CPUCLOCK_PROC_BIT 0x40000000 +#define CPUCLOCK_ID_MASK (~(CPUCLOCK_LWP_BIT|CPUCLOCK_PROC_BIT)) +#define MAKE_LWP_CPUCLOCK(lid) (CPUCLOCK_LWP_BIT|(lid)) +#define MAKE_PROC_CPUCLOCK(pid) (CPUCLOCK_PROC_BIT|(pid)) #else /* !_KERNEL */ #ifndef _STANDALONE #if (_POSIX_C_SOURCE - 0) >= 200112L || \