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 */

Reply via email to