Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Add clock_getcpuclockid2(2) as well as CLOCK_{PROCESS, TH...



details:   https://anonhg.NetBSD.org/src/rev/e56b52a0c3bf
branches:  trunk
changeset: 814982:e56b52a0c3bf
user:      christos <christos%NetBSD.org@localhost>
date:      Sat Apr 23 23:08:26 2016 +0000

description:
Add clock_getcpuclockid2(2) as well as CLOCK_{PROCESS,THREAD}_CPUTIME_ID.

diffstat:

 sys/kern/kern_time.c     |  35 ++++++++++++++++++++-
 sys/kern/subr_time.c     |  76 ++++++++++++++++++++++++++++++++++++++++++++++-
 sys/kern/syscalls.master |   4 +-
 sys/sys/time.h           |   4 +-
 4 files changed, 113 insertions(+), 6 deletions(-)

diffs (204 lines):

diff -r 08759bce88df -r e56b52a0c3bf sys/kern/kern_time.c
--- a/sys/kern/kern_time.c      Sat Apr 23 21:24:31 2016 +0000
+++ b/sys/kern/kern_time.c      Sat Apr 23 23:08:26 2016 +0000
@@ -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_PROF == CLOCK_PROF);
 CTASSERT(ITIMER_MONOTONIC == CLOCK_MONOTONIC);
 
+
 /*
  * Initialize timekeeping.
  */
@@ -377,6 +378,36 @@
        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,
diff -r 08759bce88df -r e56b52a0c3bf sys/kern/subr_time.c
--- a/sys/kern/subr_time.c      Sat Apr 23 21:24:31 2016 +0000
+++ b/sys/kern/subr_time.c      Sat Apr 23 23:08:26 2016 +0000
@@ -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 @@
        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:
diff -r 08759bce88df -r e56b52a0c3bf sys/kern/syscalls.master
--- a/sys/kern/syscalls.master  Sat Apr 23 21:24:31 2016 +0000
+++ b/sys/kern/syscalls.master  Sat Apr 23 23:08:26 2016 +0000
@@ -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); }
diff -r 08759bce88df -r e56b52a0c3bf sys/sys/time.h
--- a/sys/sys/time.h    Sat Apr 23 21:24:31 2016 +0000
+++ b/sys/sys/time.h    Sat Apr 23 23:08:26 2016 +0000
@@ -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 @@
 #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 */



Home | Main Index | Thread Index | Old Index