Bug 168417 - pthread_getcpuclockid() does not work to specification
Summary: pthread_getcpuclockid() does not work to specification
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: threads (show other bugs)
Version: Unspecified
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-threads (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-05-28 20:10 UTC by Chris Hall
Modified: 2016-12-23 07:41 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Hall 2012-05-28 20:10:00 UTC
POSIX says that pthread_getcpuclockid() should return a clock_id for the given pthread_id.

What FreeBSD returns is CLOCK_THREAD_CPUTIME_ID.  That is the clock_id which any pthread may use to read its *own* CPUTIME.

But pthread_getcpuclockid() should return is a clock_id so that any pthread can read the CPUTIME for the pthread in question.  (Otherwise the function is completely redundant !)

Fix: 

Not known.
How-To-Repeat: Try pthread_getcpuclockid() and observe that it returns CLOCK_THREAD_CPUTIME_ID.
Comment 1 David Xu freebsd_committer 2012-07-12 08:51:02 UTC
I have worked out a patch trying to fix the problem:
http://people.freebsd.org/~davidxu/patch/cputime_clockid.diff

Regards,
David Xu
Comment 2 dfilter service freebsd_committer 2012-08-17 03:26:43 UTC
Author: davidxu
Date: Fri Aug 17 02:26:31 2012
New Revision: 239347
URL: http://svn.freebsd.org/changeset/base/239347

Log:
  Implement syscall clock_getcpuclockid2, so we can get a clock id
  for process, thread or others we want to support.
  Use the syscall to implement POSIX API clock_getcpuclock and
  pthread_getcpuclockid.
  
  PR:	168417

Added:
  head/lib/libc/gen/clock_getcpuclockid.c   (contents, props changed)
Modified:
  head/lib/libc/gen/Makefile.inc
  head/lib/libc/gen/Symbol.map
  head/lib/libc/gen/sysconf.c
  head/lib/libc/sys/Symbol.map
  head/lib/libthr/thread/thr_getcpuclockid.c
  head/sys/compat/freebsd32/freebsd32_syscall.h
  head/sys/compat/freebsd32/freebsd32_syscalls.c
  head/sys/compat/freebsd32/freebsd32_sysent.c
  head/sys/compat/freebsd32/freebsd32_systrace_args.c
  head/sys/compat/freebsd32/syscalls.master
  head/sys/kern/init_sysent.c
  head/sys/kern/kern_time.c
  head/sys/kern/syscalls.c
  head/sys/kern/syscalls.master
  head/sys/kern/systrace_args.c
  head/sys/sys/syscall.h
  head/sys/sys/syscall.mk
  head/sys/sys/sysproto.h
  head/sys/sys/time.h
  head/sys/sys/unistd.h

Modified: head/lib/libc/gen/Makefile.inc
==============================================================================
--- head/lib/libc/gen/Makefile.inc	Fri Aug 17 01:49:51 2012	(r239346)
+++ head/lib/libc/gen/Makefile.inc	Fri Aug 17 02:26:31 2012	(r239347)
@@ -8,7 +8,7 @@ SRCS+=  __getosreldate.c __xuname.c \
 	_once_stub.c _pthread_stubs.c _rand48.c _spinlock_stub.c \
 	_thread_init.c \
 	alarm.c arc4random.c assert.c auxv.c basename.c check_utility_compat.c \
-	clock.c closedir.c confstr.c \
+	clock.c clock_getcpuclockid.c closedir.c confstr.c \
 	crypt.c ctermid.c daemon.c devname.c dirfd.c dirname.c disklabel.c \
 	dlfcn.c drand48.c elf_utils.c erand48.c err.c errlst.c errno.c \
 	exec.c fdevname.c feature_present.c fmtcheck.c fmtmsg.c fnmatch.c \

Modified: head/lib/libc/gen/Symbol.map
==============================================================================
--- head/lib/libc/gen/Symbol.map	Fri Aug 17 01:49:51 2012	(r239346)
+++ head/lib/libc/gen/Symbol.map	Fri Aug 17 02:26:31 2012	(r239347)
@@ -382,6 +382,7 @@ FBSD_1.2 {
 };
 
 FBSD_1.3 {
+	clock_getcpuclockid;
 	dirfd;
 	 fdlopen;
 	__FreeBSD_libc_enter_restricted_mode;

Added: head/lib/libc/gen/clock_getcpuclockid.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libc/gen/clock_getcpuclockid.c	Fri Aug 17 02:26:31 2012	(r239347)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012 David Xu <davidxu@FreeBSD.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <errno.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+clockid_t
+clock_getcpuclockid(pid_t pid, clockid_t *clock_id)
+{
+	return clock_getcpuclockid2(pid, CPUCLOCK_WHICH_PID, clock_id);
+}

Modified: head/lib/libc/gen/sysconf.c
==============================================================================
--- head/lib/libc/gen/sysconf.c	Fri Aug 17 01:49:51 2012	(r239346)
+++ head/lib/libc/gen/sysconf.c	Fri Aug 17 02:26:31 2012	(r239347)
@@ -359,11 +359,7 @@ yesno:
 		return (_POSIX_CLOCK_SELECTION);
 #endif
 	case _SC_CPUTIME:
-#if _POSIX_CPUTIME == 0
-#error "_POSIX_CPUTIME"
-#else
 		return (_POSIX_CPUTIME);
-#endif
 #ifdef notdef
 	case _SC_FILE_LOCKING:
 		/*

Modified: head/lib/libc/sys/Symbol.map
==============================================================================
--- head/lib/libc/sys/Symbol.map	Fri Aug 17 01:49:51 2012	(r239346)
+++ head/lib/libc/sys/Symbol.map	Fri Aug 17 02:26:31 2012	(r239347)
@@ -379,6 +379,7 @@ FBSD_1.2 {
 };
 
 FBSD_1.3 {
+	clock_getcpuclockid2;
 	ffclock_getcounter;
 	ffclock_getestimate;
 	ffclock_setestimate;
@@ -490,6 +491,8 @@ FBSDprivate_1.0 {
 	__sys_chown;
 	_chroot;
 	__sys_chroot;
+	_clock_getcpuclockid2;
+	__sys_clock_getcpuclockid2;
 	_clock_getres;
 	__sys_clock_getres;
 	_clock_gettime;

Modified: head/lib/libthr/thread/thr_getcpuclockid.c
==============================================================================
--- head/lib/libthr/thread/thr_getcpuclockid.c	Fri Aug 17 01:49:51 2012	(r239346)
+++ head/lib/libthr/thread/thr_getcpuclockid.c	Fri Aug 17 02:26:31 2012	(r239347)
@@ -39,9 +39,11 @@ __weak_reference(_pthread_getcpuclockid,
 int
 _pthread_getcpuclockid(pthread_t pthread, clockid_t *clock_id)
 {
+
 	if (pthread == NULL)
 		return (EINVAL);
 
-	*clock_id = CLOCK_THREAD_CPUTIME_ID;
+	if (clock_getcpuclockid2(TID(pthread), CPUCLOCK_WHICH_TID, clock_id))
+		return (errno);
 	return (0);
 }

Modified: head/sys/compat/freebsd32/freebsd32_syscall.h
==============================================================================
--- head/sys/compat/freebsd32/freebsd32_syscall.h	Fri Aug 17 01:49:51 2012	(r239346)
+++ head/sys/compat/freebsd32/freebsd32_syscall.h	Fri Aug 17 02:26:31 2012	(r239347)
@@ -210,6 +210,7 @@
 #define	FREEBSD32_SYS_ffclock_getcounter	241
 #define	FREEBSD32_SYS_ffclock_setestimate	242
 #define	FREEBSD32_SYS_ffclock_getestimate	243
+#define	FREEBSD32_SYS_clock_getcpuclockid2	247
 #define	FREEBSD32_SYS_minherit	250
 #define	FREEBSD32_SYS_rfork	251
 #define	FREEBSD32_SYS_openbsd_poll	252

Modified: head/sys/compat/freebsd32/freebsd32_syscalls.c
==============================================================================
--- head/sys/compat/freebsd32/freebsd32_syscalls.c	Fri Aug 17 01:49:51 2012	(r239346)
+++ head/sys/compat/freebsd32/freebsd32_syscalls.c	Fri Aug 17 02:26:31 2012	(r239347)
@@ -257,7 +257,7 @@ const char *freebsd32_syscallnames[] = {
 	"#244",			/* 244 = nosys */
 	"#245",			/* 245 = nosys */
 	"#246",			/* 246 = nosys */
-	"#247",			/* 247 = nosys */
+	"clock_getcpuclockid2",			/* 247 = clock_getcpuclockid2 */
 	"#248",			/* 248 = ntp_gettime */
 	"#249",			/* 249 = nosys */
 	"minherit",			/* 250 = minherit */

Modified: head/sys/compat/freebsd32/freebsd32_sysent.c
==============================================================================
--- head/sys/compat/freebsd32/freebsd32_sysent.c	Fri Aug 17 01:49:51 2012	(r239346)
+++ head/sys/compat/freebsd32/freebsd32_sysent.c	Fri Aug 17 02:26:31 2012	(r239347)
@@ -294,7 +294,7 @@ struct sysent freebsd32_sysent[] = {
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 244 = nosys */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 245 = nosys */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 246 = nosys */
-	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 247 = nosys */
+	{ AS(clock_getcpuclockid2_args), (sy_call_t *)sys_clock_getcpuclockid2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC },	/* 247 = clock_getcpuclockid2 */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 248 = ntp_gettime */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 249 = nosys */
 	{ AS(minherit_args), (sy_call_t *)sys_minherit, AUE_MINHERIT, NULL, 0, 0, 0, SY_THR_STATIC },	/* 250 = minherit */

Modified: head/sys/compat/freebsd32/freebsd32_systrace_args.c
==============================================================================
--- head/sys/compat/freebsd32/freebsd32_systrace_args.c	Fri Aug 17 01:49:51 2012	(r239346)
+++ head/sys/compat/freebsd32/freebsd32_systrace_args.c	Fri Aug 17 02:26:31 2012	(r239347)
@@ -1224,6 +1224,15 @@ systrace_args(int sysnum, void *params, 
 		*n_args = 1;
 		break;
 	}
+	/* clock_getcpuclockid2 */
+	case 247: {
+		struct clock_getcpuclockid2_args *p = params;
+		iarg[0] = p->id; /* id_t */
+		iarg[1] = p->which; /* int */
+		uarg[2] = (intptr_t) p->clock_id; /* clockid_t * */
+		*n_args = 3;
+		break;
+	}
 	/* minherit */
 	case 250: {
 		struct minherit_args *p = params;
@@ -4991,6 +5000,22 @@ systrace_entry_setargdesc(int sysnum, in
 			break;
 		};
 		break;
+	/* clock_getcpuclockid2 */
+	case 247:
+		switch(ndx) {
+		case 0:
+			p = "id_t";
+			break;
+		case 1:
+			p = "int";
+			break;
+		case 2:
+			p = "clockid_t *";
+			break;
+		default:
+			break;
+		};
+		break;
 	/* minherit */
 	case 250:
 		switch(ndx) {
@@ -8890,6 +8915,11 @@ systrace_return_setargdesc(int sysnum, i
 		if (ndx == 0 || ndx == 1)
 			p = "int";
 		break;
+	/* clock_getcpuclockid2 */
+	case 247:
+		if (ndx == 0 || ndx == 1)
+			p = "int";
+		break;
 	/* minherit */
 	case 250:
 		if (ndx == 0 || ndx == 1)

Modified: head/sys/compat/freebsd32/syscalls.master
==============================================================================
--- head/sys/compat/freebsd32/syscalls.master	Fri Aug 17 01:49:51 2012	(r239346)
+++ head/sys/compat/freebsd32/syscalls.master	Fri Aug 17 02:26:31 2012	(r239347)
@@ -457,7 +457,8 @@
 244	AUE_NULL	UNIMPL	nosys
 245	AUE_NULL	UNIMPL	nosys
 246	AUE_NULL	UNIMPL	nosys
-247	AUE_NULL	UNIMPL	nosys
+247	AUE_NULL	NOPROTO	{ int clock_getcpuclockid2(id_t id,\
+					int which, clockid_t *clock_id); }
 248	AUE_NULL	UNIMPL	ntp_gettime
 249	AUE_NULL	UNIMPL	nosys
 ; syscall numbers initially used in OpenBSD

Modified: head/sys/kern/init_sysent.c
==============================================================================
--- head/sys/kern/init_sysent.c	Fri Aug 17 01:49:51 2012	(r239346)
+++ head/sys/kern/init_sysent.c	Fri Aug 17 02:26:31 2012	(r239347)
@@ -281,7 +281,7 @@ struct sysent sysent[] = {
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 244 = nosys */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 245 = nosys */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 246 = nosys */
-	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 247 = nosys */
+	{ AS(clock_getcpuclockid2_args), (sy_call_t *)sys_clock_getcpuclockid2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC },	/* 247 = clock_getcpuclockid2 */
 	{ AS(ntp_gettime_args), (sy_call_t *)sys_ntp_gettime, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC },	/* 248 = ntp_gettime */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 249 = nosys */
 	{ AS(minherit_args), (sy_call_t *)sys_minherit, AUE_MINHERIT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC },	/* 250 = minherit */

Modified: head/sys/kern/kern_time.c
==============================================================================
--- head/sys/kern/kern_time.c	Fri Aug 17 01:49:51 2012	(r239346)
+++ head/sys/kern/kern_time.c	Fri Aug 17 02:26:31 2012	(r239347)
@@ -58,6 +58,12 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_extern.h>
 
 #define MAX_CLOCKS 	(CLOCK_MONOTONIC+1)
+#define CPUCLOCK_BIT		0x80000000
+#define CPUCLOCK_PROCESS_BIT	0x40000000
+#define CPUCLOCK_ID_MASK	(~(CPUCLOCK_BIT|CPUCLOCK_PROCESS_BIT))
+#define MAKE_THREAD_CPUCLOCK(tid)	(CPUCLOCK_BIT|(tid))
+#define MAKE_PROCESS_CPUCLOCK(pid)	\
+	(CPUCLOCK_BIT|CPUCLOCK_PROCESS_BIT|(pid))
 
 static struct kclock	posix_clocks[MAX_CLOCKS];
 static uma_zone_t	itimer_zone = NULL;
@@ -165,6 +171,52 @@ settime(struct thread *td, struct timeva
 }
 
 #ifndef _SYS_SYSPROTO_H_
+struct clock_getcpuclockid2_args {
+	id_t id;
+	int which,
+	clockid_t *clock_id;
+};
+#endif
+/* ARGSUSED */
+int
+sys_clock_getcpuclockid2(struct thread *td, struct clock_getcpuclockid2_args *uap)
+{
+	clockid_t clk_id;
+	struct proc *p;
+	pid_t pid;
+	lwpid_t tid;
+	int error;
+
+	switch(uap->which) {
+	case CPUCLOCK_WHICH_PID:
+		if (uap->id != 0) {
+			p = pfind(uap->id);
+			if (p == NULL)
+				return (ESRCH);
+			error = p_cansee(td, p);
+			PROC_UNLOCK(p);
+			if (error)
+				return (error);
+			pid = uap->id;
+		} else {
+			pid = td->td_proc->p_pid;
+		}
+		clk_id = MAKE_PROCESS_CPUCLOCK(pid);
+		break;
+	case CPUCLOCK_WHICH_TID:
+		if (uap->id == 0)
+			tid = td->td_tid;
+		else
+			tid = uap->id;
+		clk_id = MAKE_THREAD_CPUCLOCK(tid);
+		break;
+	default:
+		return (EINVAL);
+	}
+	return (copyout(&clk_id, uap->clock_id, sizeof(clockid_t)));
+}
+
+#ifndef _SYS_SYSPROTO_H_
 struct clock_gettime_args {
 	clockid_t clock_id;
 	struct	timespec *tp;
@@ -184,12 +236,85 @@ sys_clock_gettime(struct thread *td, str
 	return (error);
 }
 
+static inline void 
+cputick2timespec(uint64_t runtime, struct timespec *ats)
+{
+	runtime = cputick2usec(runtime);
+	ats->tv_sec = runtime / 1000000;
+	ats->tv_nsec = runtime % 1000000 * 1000;
+}
+
+static void
+get_thread_cputime(struct thread *targettd, struct timespec *ats)
+{
+	uint64_t runtime, curtime, switchtime;
+
+	if (targettd == NULL) { /* current thread */
+		critical_enter();
+		switchtime = PCPU_GET(switchtime);
+		curtime = cpu_ticks();
+		runtime = curthread->td_runtime;
+		critical_exit();
+		runtime += curtime - switchtime;
+	} else {
+		thread_lock(targettd);
+		runtime = targettd->td_runtime;
+		thread_unlock(targettd);
+	}
+	cputick2timespec(runtime, ats);
+}
+
+static void
+get_process_cputime(struct proc *targetp, struct timespec *ats)
+{
+	uint64_t runtime;
+	struct rusage ru;
+
+	PROC_SLOCK(targetp);
+	rufetch(targetp, &ru);
+	runtime = targetp->p_rux.rux_runtime;
+	PROC_SUNLOCK(targetp);
+	cputick2timespec(runtime, ats);
+}
+
+static int
+get_cputime(struct thread *td, clockid_t clock_id, struct timespec *ats)
+{
+	struct proc *p, *p2;
+	struct thread *td2;
+	lwpid_t tid;
+	pid_t pid;
+	int error;
+
+	p = td->td_proc;
+	if ((clock_id & CPUCLOCK_PROCESS_BIT) == 0) {
+		tid = clock_id & CPUCLOCK_ID_MASK;
+		td2 = tdfind(tid, p->p_pid);
+		if (td2 == NULL)
+			return (EINVAL);
+		get_thread_cputime(td2, ats);
+		PROC_UNLOCK(td2->td_proc);
+	} else {
+		pid = clock_id & CPUCLOCK_ID_MASK;
+		p2 = pfind(pid);
+		if (p2 == NULL)
+			return (EINVAL);
+		error = p_cansee(td, p2);
+		if (error) {
+			PROC_UNLOCK(p2);
+			return (EINVAL);
+		}
+		get_process_cputime(p2, ats);
+		PROC_UNLOCK(p2);
+	}
+	return (0);
+}
+
 int
 kern_clock_gettime(struct thread *td, clockid_t clock_id, struct timespec *ats)
 {
 	struct timeval sys, user;
 	struct proc *p;
-	uint64_t runtime, curtime, switchtime;
 
 	p = td->td_proc;
 	switch (clock_id) {
@@ -232,17 +357,17 @@ kern_clock_gettime(struct thread *td, cl
 		ats->tv_nsec = 0;
 		break;
 	case CLOCK_THREAD_CPUTIME_ID:
-		critical_enter();
-		switchtime = PCPU_GET(switchtime);
-		curtime = cpu_ticks();
-		runtime = td->td_runtime;
-		critical_exit();
-		runtime = cputick2usec(runtime + curtime - switchtime);
-		ats->tv_sec = runtime / 1000000;
-		ats->tv_nsec = runtime % 1000000 * 1000;
+		get_thread_cputime(NULL, ats);
+		break;
+	case CLOCK_PROCESS_CPUTIME_ID:
+		PROC_LOCK(p);
+		get_process_cputime(p, ats);
+		PROC_UNLOCK(p);
 		break;
 	default:
-		return (EINVAL);
+		if ((int)clock_id >= 0)
+			return (EINVAL);
+		return (get_cputime(td, clock_id, ats));
 	}
 	return (0);
 }
@@ -336,12 +461,16 @@ kern_clock_getres(struct thread *td, clo
 		ts->tv_nsec = 0;
 		break;
 	case CLOCK_THREAD_CPUTIME_ID:
+	case CLOCK_PROCESS_CPUTIME_ID:
+	cputime:
 		/* sync with cputick2usec */
 		ts->tv_nsec = 1000000 / cpu_tickrate();
 		if (ts->tv_nsec == 0)
 			ts->tv_nsec = 1000;
 		break;
 	default:
+		if ((int)clock_id < 0)
+			goto cputime;
 		return (EINVAL);
 	}
 	return (0);

Modified: head/sys/kern/syscalls.c
==============================================================================
--- head/sys/kern/syscalls.c	Fri Aug 17 01:49:51 2012	(r239346)
+++ head/sys/kern/syscalls.c	Fri Aug 17 02:26:31 2012	(r239347)
@@ -254,7 +254,7 @@ const char *syscallnames[] = {
 	"#244",			/* 244 = nosys */
 	"#245",			/* 245 = nosys */
 	"#246",			/* 246 = nosys */
-	"#247",			/* 247 = nosys */
+	"clock_getcpuclockid2",			/* 247 = clock_getcpuclockid2 */
 	"ntp_gettime",			/* 248 = ntp_gettime */
 	"#249",			/* 249 = nosys */
 	"minherit",			/* 250 = minherit */

Modified: head/sys/kern/syscalls.master
==============================================================================
--- head/sys/kern/syscalls.master	Fri Aug 17 01:49:51 2012	(r239346)
+++ head/sys/kern/syscalls.master	Fri Aug 17 02:26:31 2012	(r239347)
@@ -464,7 +464,8 @@
 244	AUE_NULL	UNIMPL	nosys
 245	AUE_NULL	UNIMPL	nosys
 246	AUE_NULL	UNIMPL	nosys
-247	AUE_NULL	UNIMPL	nosys
+247	AUE_NULL	STD	{ int clock_getcpuclockid2(id_t id,\
+				    int which, clockid_t *clock_id); }
 248	AUE_NULL	STD	{ int ntp_gettime(struct ntptimeval *ntvp); }
 249	AUE_NULL	UNIMPL	nosys
 ; syscall numbers initially used in OpenBSD

Modified: head/sys/kern/systrace_args.c
==============================================================================
--- head/sys/kern/systrace_args.c	Fri Aug 17 01:49:51 2012	(r239346)
+++ head/sys/kern/systrace_args.c	Fri Aug 17 02:26:31 2012	(r239347)
@@ -1358,6 +1358,15 @@ systrace_args(int sysnum, void *params, 
 		*n_args = 1;
 		break;
 	}
+	/* clock_getcpuclockid2 */
+	case 247: {
+		struct clock_getcpuclockid2_args *p = params;
+		iarg[0] = p->id; /* id_t */
+		iarg[1] = p->which; /* int */
+		uarg[2] = (intptr_t) p->clock_id; /* clockid_t * */
+		*n_args = 3;
+		break;
+	}
 	/* ntp_gettime */
 	case 248: {
 		struct ntp_gettime_args *p = params;
@@ -5432,6 +5441,22 @@ systrace_entry_setargdesc(int sysnum, in
 			break;
 		};
 		break;
+	/* clock_getcpuclockid2 */
+	case 247:
+		switch(ndx) {
+		case 0:
+			p = "id_t";
+			break;
+		case 1:
+			p = "int";
+			break;
+		case 2:
+			p = "clockid_t *";
+			break;
+		default:
+			break;
+		};
+		break;
 	/* ntp_gettime */
 	case 248:
 		switch(ndx) {
@@ -9464,6 +9489,11 @@ systrace_return_setargdesc(int sysnum, i
 		if (ndx == 0 || ndx == 1)
 			p = "int";
 		break;
+	/* clock_getcpuclockid2 */
+	case 247:
+		if (ndx == 0 || ndx == 1)
+			p = "int";
+		break;
 	/* ntp_gettime */
 	case 248:
 		if (ndx == 0 || ndx == 1)

Modified: head/sys/sys/syscall.h
==============================================================================
--- head/sys/sys/syscall.h	Fri Aug 17 01:49:51 2012	(r239346)
+++ head/sys/sys/syscall.h	Fri Aug 17 02:26:31 2012	(r239347)
@@ -219,6 +219,7 @@
 #define	SYS_ffclock_getcounter	241
 #define	SYS_ffclock_setestimate	242
 #define	SYS_ffclock_getestimate	243
+#define	SYS_clock_getcpuclockid2	247
 #define	SYS_ntp_gettime	248
 #define	SYS_minherit	250
 #define	SYS_rfork	251

Modified: head/sys/sys/syscall.mk
==============================================================================
--- head/sys/sys/syscall.mk	Fri Aug 17 01:49:51 2012	(r239346)
+++ head/sys/sys/syscall.mk	Fri Aug 17 02:26:31 2012	(r239347)
@@ -171,6 +171,7 @@ MIASM =  \
 	ffclock_getcounter.o \
 	ffclock_setestimate.o \
 	ffclock_getestimate.o \
+	clock_getcpuclockid2.o \
 	ntp_gettime.o \
 	minherit.o \
 	rfork.o \

Modified: head/sys/sys/sysproto.h
==============================================================================
--- head/sys/sys/sysproto.h	Fri Aug 17 01:49:51 2012	(r239346)
+++ head/sys/sys/sysproto.h	Fri Aug 17 02:26:31 2012	(r239347)
@@ -736,6 +736,11 @@ struct ffclock_setestimate_args {
 struct ffclock_getestimate_args {
 	char cest_l_[PADL_(struct ffclock_estimate *)]; struct ffclock_estimate * cest; char cest_r_[PADR_(struct ffclock_estimate *)];
 };
+struct clock_getcpuclockid2_args {
+	char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)];
+	char which_l_[PADL_(int)]; int which; char which_r_[PADR_(int)];
+	char clock_id_l_[PADL_(clockid_t *)]; clockid_t * clock_id; char clock_id_r_[PADR_(clockid_t *)];
+};
 struct ntp_gettime_args {
 	char ntvp_l_[PADL_(struct ntptimeval *)]; struct ntptimeval * ntvp; char ntvp_r_[PADR_(struct ntptimeval *)];
 };
@@ -1907,6 +1912,7 @@ int	sys_nanosleep(struct thread *, struc
 int	sys_ffclock_getcounter(struct thread *, struct ffclock_getcounter_args *);
 int	sys_ffclock_setestimate(struct thread *, struct ffclock_setestimate_args *);
 int	sys_ffclock_getestimate(struct thread *, struct ffclock_getestimate_args *);
+int	sys_clock_getcpuclockid2(struct thread *, struct clock_getcpuclockid2_args *);
 int	sys_ntp_gettime(struct thread *, struct ntp_gettime_args *);
 int	sys_minherit(struct thread *, struct minherit_args *);
 int	sys_rfork(struct thread *, struct rfork_args *);
@@ -2597,6 +2603,7 @@ int	freebsd7_shmctl(struct thread *, str
 #define	SYS_AUE_ffclock_getcounter	AUE_NULL
 #define	SYS_AUE_ffclock_setestimate	AUE_NULL
 #define	SYS_AUE_ffclock_getestimate	AUE_NULL
+#define	SYS_AUE_clock_getcpuclockid2	AUE_NULL
 #define	SYS_AUE_ntp_gettime	AUE_NULL
 #define	SYS_AUE_minherit	AUE_MINHERIT
 #define	SYS_AUE_rfork	AUE_RFORK

Modified: head/sys/sys/time.h
==============================================================================
--- head/sys/sys/time.h	Fri Aug 17 01:49:51 2012	(r239346)
+++ head/sys/sys/time.h	Fri Aug 17 02:26:31 2012	(r239347)
@@ -266,6 +266,7 @@ struct clockinfo {
 #define CLOCK_MONOTONIC_FAST	12	/* FreeBSD-specific. */
 #define CLOCK_SECOND	13		/* FreeBSD-specific. */
 #define CLOCK_THREAD_CPUTIME_ID	14
+#define CLOCK_PROCESS_CPUTIME_ID	15
 #endif
 
 #ifndef TIMER_ABSTIME
@@ -273,6 +274,11 @@ struct clockinfo {
 #define TIMER_ABSTIME	0x1	/* absolute timer */
 #endif
 
+#if __BSD_VISIBLE
+#define	CPUCLOCK_WHICH_PID	0
+#define	CPUCLOCK_WHICH_TID	1
+#endif
+
 #ifdef _KERNEL
 
 /*
@@ -344,6 +350,7 @@ int	utimes(const char *, const struct ti
 
 #if __BSD_VISIBLE
 int	adjtime(const struct timeval *, struct timeval *);
+int	clock_getcpuclockid2(id_t, int, clockid_t *);
 int	futimes(int, const struct timeval *);
 int	futimesat(int, const char *, const struct timeval [2]);
 int	lutimes(const char *, const struct timeval *);

Modified: head/sys/sys/unistd.h
==============================================================================
--- head/sys/sys/unistd.h	Fri Aug 17 01:49:51 2012	(r239346)
+++ head/sys/sys/unistd.h	Fri Aug 17 02:26:31 2012	(r239347)
@@ -53,7 +53,7 @@
 #define	_POSIX_ASYNCHRONOUS_IO		0
 #define	_POSIX_CHOWN_RESTRICTED		1
 #define	_POSIX_CLOCK_SELECTION		(-1)
-#define	_POSIX_CPUTIME			(-1)
+#define	_POSIX_CPUTIME			200112L
 #define	_POSIX_FSYNC			200112L
 #define	_POSIX_IPV6			0
 #define	_POSIX_JOB_CONTROL		1
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 3 dfilter service freebsd_committer 2013-08-16 07:40:26 UTC
Author: davidxu
Date: Fri Aug 16 06:40:12 2013
New Revision: 254398
URL: http://svnweb.freebsd.org/changeset/base/254398

Log:
  MFC r239347, 240295, 240296 and 253325:
  
      r239347 | davidxu | 2012-08-17 10:26:31 +0800 (Fri, 17 Aug 2012) | 7 lines
  
      Implement syscall clock_getcpuclockid2, so we can get a clock id
      for process, thread or others we want to support.
      Use the syscall to implement POSIX API clock_getcpuclock and
      pthread_getcpuclockid.
  
      PR:	168417
  
      ------------------------------------------------------------------------
      r240295 | davidxu | 2012-09-10 13:00:29 +0800 (Mon, 10 Sep 2012) | 2 lines
  
      Add missing prototype for clock_getcpuclockid.
  
      ------------------------------------------------------------------------
      r240296 | davidxu | 2012-09-10 13:09:39 +0800 (Mon, 10 Sep 2012) | 2 lines
  
      Process CPU-Time Clocks option is supported, define _POSIX_CPUTIME.
  
      ------------------------------------------------------------------------
      r253325 | kib | 2013-07-14 03:32:50 +0800 (Sun, 14 Jul 2013) | 6 lines
  
      Allow to call clock_gettime() on the clock id for zombie process.
  
      Reported by:	Petr Salinger <Petr.Salinger@seznam.cz>
      PR:	threads/180496
      Sponsored by:	The FreeBSD Foundation

Added:
  stable/9/lib/libc/gen/clock_getcpuclockid.c
     - copied unchanged from r239347, head/lib/libc/gen/clock_getcpuclockid.c
Modified:
  stable/9/include/time.h
  stable/9/include/unistd.h
  stable/9/lib/libc/gen/Makefile.inc
  stable/9/lib/libc/gen/Symbol.map
  stable/9/lib/libc/gen/sysconf.c
  stable/9/lib/libc/sys/Symbol.map
  stable/9/lib/libthr/thread/thr_getcpuclockid.c
  stable/9/sys/compat/freebsd32/freebsd32_syscall.h
  stable/9/sys/compat/freebsd32/freebsd32_syscalls.c
  stable/9/sys/compat/freebsd32/freebsd32_sysent.c
  stable/9/sys/compat/freebsd32/freebsd32_systrace_args.c
  stable/9/sys/compat/freebsd32/syscalls.master
  stable/9/sys/kern/init_sysent.c
  stable/9/sys/kern/kern_time.c
  stable/9/sys/kern/syscalls.c
  stable/9/sys/kern/syscalls.master
  stable/9/sys/kern/systrace_args.c
  stable/9/sys/sys/syscall.h
  stable/9/sys/sys/syscall.mk
  stable/9/sys/sys/sysproto.h
  stable/9/sys/sys/time.h
  stable/9/sys/sys/unistd.h
Directory Properties:
  stable/9/   (props changed)
  stable/9/include/   (props changed)
  stable/9/lib/   (props changed)
  stable/9/lib/libc/   (props changed)
  stable/9/lib/libc/sys/   (props changed)
  stable/9/lib/libthr/   (props changed)
  stable/9/sys/   (props changed)
  stable/9/sys/sys/   (props changed)

Modified: stable/9/include/time.h
==============================================================================
--- stable/9/include/time.h	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/include/time.h	Fri Aug 16 06:40:12 2013	(r254398)
@@ -88,6 +88,13 @@ typedef	__timer_t	timer_t;
 #include <sys/timespec.h>
 #endif /* __POSIX_VISIBLE >= 199309 */
 
+#if __POSIX_VISIBLE >= 200112
+#ifndef _PID_T_DECLARED
+typedef	__pid_t		pid_t;
+#define	_PID_T_DECLARED
+#endif
+#endif
+
 /* These macros are also in sys/time.h. */
 #if !defined(CLOCK_REALTIME) && __POSIX_VISIBLE >= 200112
 #define CLOCK_REALTIME	0
@@ -165,6 +172,10 @@ int clock_settime(clockid_t, const struc
 int nanosleep(const struct timespec *, struct timespec *);
 #endif /* __POSIX_VISIBLE >= 199309 */
 
+#if __POSIX_VISIBLE >= 200112
+int clock_getcpuclockid(pid_t, clockid_t *);
+#endif
+
 #if __POSIX_VISIBLE >= 199506
 char *asctime_r(const struct tm *, char *);
 char *ctime_r(const time_t *, char *);

Modified: stable/9/include/unistd.h
==============================================================================
--- stable/9/include/unistd.h	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/include/unistd.h	Fri Aug 16 06:40:12 2013	(r254398)
@@ -100,6 +100,7 @@ typedef	__useconds_t	useconds_t;
  * returns -1, the functions may be stubbed out.
  */
 #define	_POSIX_BARRIERS			200112L
+#define	_POSIX_CPUTIME			200112L
 #define	_POSIX_READER_WRITER_LOCKS	200112L
 #define	_POSIX_REGEXP			1
 #define	_POSIX_SHELL			1

Modified: stable/9/lib/libc/gen/Makefile.inc
==============================================================================
--- stable/9/lib/libc/gen/Makefile.inc	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/lib/libc/gen/Makefile.inc	Fri Aug 16 06:40:12 2013	(r254398)
@@ -8,7 +8,7 @@ SRCS+=  __getosreldate.c __xuname.c \
 	_once_stub.c _pthread_stubs.c _rand48.c _spinlock_stub.c \
 	_thread_init.c \
 	alarm.c arc4random.c assert.c aux.c basename.c check_utility_compat.c \
-	clock.c closedir.c confstr.c \
+	clock.c clock_getcpuclockid.c closedir.c confstr.c \
 	crypt.c ctermid.c daemon.c devname.c dirname.c disklabel.c \
 	dlfcn.c drand48.c elf_utils.c erand48.c err.c errlst.c errno.c \
 	exec.c fdevname.c feature_present.c fmtcheck.c fmtmsg.c fnmatch.c \

Modified: stable/9/lib/libc/gen/Symbol.map
==============================================================================
--- stable/9/lib/libc/gen/Symbol.map	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/lib/libc/gen/Symbol.map	Fri Aug 16 06:40:12 2013	(r254398)
@@ -380,6 +380,8 @@ FBSD_1.2 {
 };
 
 FBSD_1.3 {
+	clock_getcpuclockid;
+	dirfd;
 	 fdlopen;
 	__FreeBSD_libc_enter_restricted_mode;
 	getcontextx;

Copied: stable/9/lib/libc/gen/clock_getcpuclockid.c (from r239347, head/lib/libc/gen/clock_getcpuclockid.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/9/lib/libc/gen/clock_getcpuclockid.c	Fri Aug 16 06:40:12 2013	(r254398, copy of r239347, head/lib/libc/gen/clock_getcpuclockid.c)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012 David Xu <davidxu@FreeBSD.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <errno.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+clockid_t
+clock_getcpuclockid(pid_t pid, clockid_t *clock_id)
+{
+	return clock_getcpuclockid2(pid, CPUCLOCK_WHICH_PID, clock_id);
+}

Modified: stable/9/lib/libc/gen/sysconf.c
==============================================================================
--- stable/9/lib/libc/gen/sysconf.c	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/lib/libc/gen/sysconf.c	Fri Aug 16 06:40:12 2013	(r254398)
@@ -359,11 +359,7 @@ yesno:
 		return (_POSIX_CLOCK_SELECTION);
 #endif
 	case _SC_CPUTIME:
-#if _POSIX_CPUTIME == 0
-#error "_POSIX_CPUTIME"
-#else
 		return (_POSIX_CPUTIME);
-#endif
 #ifdef notdef
 	case _SC_FILE_LOCKING:
 		/*

Modified: stable/9/lib/libc/sys/Symbol.map
==============================================================================
--- stable/9/lib/libc/sys/Symbol.map	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/lib/libc/sys/Symbol.map	Fri Aug 16 06:40:12 2013	(r254398)
@@ -379,6 +379,7 @@ FBSD_1.2 {
 };
 
 FBSD_1.3 {
+	clock_getcpuclockid2;
 	posix_fadvise;
 	wait6;
 };
@@ -488,6 +489,8 @@ FBSDprivate_1.0 {
 	__sys_chown;
 	_chroot;
 	__sys_chroot;
+	_clock_getcpuclockid2;
+	__sys_clock_getcpuclockid2;
 	_clock_getres;
 	__sys_clock_getres;
 	_clock_gettime;

Modified: stable/9/lib/libthr/thread/thr_getcpuclockid.c
==============================================================================
--- stable/9/lib/libthr/thread/thr_getcpuclockid.c	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/lib/libthr/thread/thr_getcpuclockid.c	Fri Aug 16 06:40:12 2013	(r254398)
@@ -39,9 +39,11 @@ __weak_reference(_pthread_getcpuclockid,
 int
 _pthread_getcpuclockid(pthread_t pthread, clockid_t *clock_id)
 {
+
 	if (pthread == NULL)
 		return (EINVAL);
 
-	*clock_id = CLOCK_THREAD_CPUTIME_ID;
+	if (clock_getcpuclockid2(TID(pthread), CPUCLOCK_WHICH_TID, clock_id))
+		return (errno);
 	return (0);
 }

Modified: stable/9/sys/compat/freebsd32/freebsd32_syscall.h
==============================================================================
--- stable/9/sys/compat/freebsd32/freebsd32_syscall.h	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/sys/compat/freebsd32/freebsd32_syscall.h	Fri Aug 16 06:40:12 2013	(r254398)
@@ -212,6 +212,7 @@
 #define	FREEBSD32_SYS_freebsd32_ktimer_gettime	238
 #define	FREEBSD32_SYS_ktimer_getoverrun	239
 #define	FREEBSD32_SYS_freebsd32_nanosleep	240
+#define	FREEBSD32_SYS_clock_getcpuclockid2	247
 #define	FREEBSD32_SYS_minherit	250
 #define	FREEBSD32_SYS_rfork	251
 #define	FREEBSD32_SYS_openbsd_poll	252

Modified: stable/9/sys/compat/freebsd32/freebsd32_syscalls.c
==============================================================================
--- stable/9/sys/compat/freebsd32/freebsd32_syscalls.c	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/sys/compat/freebsd32/freebsd32_syscalls.c	Fri Aug 16 06:40:12 2013	(r254398)
@@ -257,7 +257,7 @@ const char *freebsd32_syscallnames[] = {
 	"#244",			/* 244 = nosys */
 	"#245",			/* 245 = nosys */
 	"#246",			/* 246 = nosys */
-	"#247",			/* 247 = nosys */
+	"clock_getcpuclockid2",			/* 247 = clock_getcpuclockid2 */
 	"#248",			/* 248 = ntp_gettime */
 	"#249",			/* 249 = nosys */
 	"minherit",			/* 250 = minherit */

Modified: stable/9/sys/compat/freebsd32/freebsd32_sysent.c
==============================================================================
--- stable/9/sys/compat/freebsd32/freebsd32_sysent.c	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/sys/compat/freebsd32/freebsd32_sysent.c	Fri Aug 16 06:40:12 2013	(r254398)
@@ -294,7 +294,7 @@ struct sysent freebsd32_sysent[] = {
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 244 = nosys */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 245 = nosys */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 246 = nosys */
-	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 247 = nosys */
+	{ AS(clock_getcpuclockid2_args), (sy_call_t *)sys_clock_getcpuclockid2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC },	/* 247 = clock_getcpuclockid2 */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 248 = ntp_gettime */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 249 = nosys */
 	{ AS(minherit_args), (sy_call_t *)sys_minherit, AUE_MINHERIT, NULL, 0, 0, 0, SY_THR_STATIC },	/* 250 = minherit */

Modified: stable/9/sys/compat/freebsd32/freebsd32_systrace_args.c
==============================================================================
--- stable/9/sys/compat/freebsd32/freebsd32_systrace_args.c	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/sys/compat/freebsd32/freebsd32_systrace_args.c	Fri Aug 16 06:40:12 2013	(r254398)
@@ -1244,6 +1244,15 @@ systrace_args(int sysnum, void *params, 
 		*n_args = 2;
 		break;
 	}
+	/* clock_getcpuclockid2 */
+	case 247: {
+		struct clock_getcpuclockid2_args *p = params;
+		iarg[0] = p->id; /* id_t */
+		iarg[1] = p->which; /* int */
+		uarg[2] = (intptr_t) p->clock_id; /* clockid_t * */
+		*n_args = 3;
+		break;
+	}
 	/* minherit */
 	case 250: {
 		struct minherit_args *p = params;
@@ -5104,6 +5113,22 @@ systrace_setargdesc(int sysnum, int ndx,
 			break;
 		};
 		break;
+	/* clock_getcpuclockid2 */
+	case 247:
+		switch(ndx) {
+		case 0:
+			p = "id_t";
+			break;
+		case 1:
+			p = "int";
+			break;
+		case 2:
+			p = "clockid_t *";
+			break;
+		default:
+			break;
+		};
+		break;
 	/* minherit */
 	case 250:
 		switch(ndx) {

Modified: stable/9/sys/compat/freebsd32/syscalls.master
==============================================================================
--- stable/9/sys/compat/freebsd32/syscalls.master	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/sys/compat/freebsd32/syscalls.master	Fri Aug 16 06:40:12 2013	(r254398)
@@ -461,7 +461,8 @@
 244	AUE_NULL	UNIMPL	nosys
 245	AUE_NULL	UNIMPL	nosys
 246	AUE_NULL	UNIMPL	nosys
-247	AUE_NULL	UNIMPL	nosys
+247	AUE_NULL	NOPROTO	{ int clock_getcpuclockid2(id_t id,\
+					int which, clockid_t *clock_id); }
 248	AUE_NULL	UNIMPL	ntp_gettime
 249	AUE_NULL	UNIMPL	nosys
 ; syscall numbers initially used in OpenBSD

Modified: stable/9/sys/kern/init_sysent.c
==============================================================================
--- stable/9/sys/kern/init_sysent.c	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/sys/kern/init_sysent.c	Fri Aug 16 06:40:12 2013	(r254398)
@@ -281,7 +281,7 @@ struct sysent sysent[] = {
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 244 = nosys */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 245 = nosys */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 246 = nosys */
-	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 247 = nosys */
+	{ AS(clock_getcpuclockid2_args), (sy_call_t *)sys_clock_getcpuclockid2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC },	/* 247 = clock_getcpuclockid2 */
 	{ AS(ntp_gettime_args), (sy_call_t *)sys_ntp_gettime, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC },	/* 248 = ntp_gettime */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 249 = nosys */
 	{ AS(minherit_args), (sy_call_t *)sys_minherit, AUE_MINHERIT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC },	/* 250 = minherit */

Modified: stable/9/sys/kern/kern_time.c
==============================================================================
--- stable/9/sys/kern/kern_time.c	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/sys/kern/kern_time.c	Fri Aug 16 06:40:12 2013	(r254398)
@@ -58,6 +58,12 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_extern.h>
 
 #define MAX_CLOCKS 	(CLOCK_MONOTONIC+1)
+#define CPUCLOCK_BIT		0x80000000
+#define CPUCLOCK_PROCESS_BIT	0x40000000
+#define CPUCLOCK_ID_MASK	(~(CPUCLOCK_BIT|CPUCLOCK_PROCESS_BIT))
+#define MAKE_THREAD_CPUCLOCK(tid)	(CPUCLOCK_BIT|(tid))
+#define MAKE_PROCESS_CPUCLOCK(pid)	\
+	(CPUCLOCK_BIT|CPUCLOCK_PROCESS_BIT|(pid))
 
 static struct kclock	posix_clocks[MAX_CLOCKS];
 static uma_zone_t	itimer_zone = NULL;
@@ -162,6 +168,52 @@ settime(struct thread *td, struct timeva
 }
 
 #ifndef _SYS_SYSPROTO_H_
+struct clock_getcpuclockid2_args {
+	id_t id;
+	int which,
+	clockid_t *clock_id;
+};
+#endif
+/* ARGSUSED */
+int
+sys_clock_getcpuclockid2(struct thread *td, struct clock_getcpuclockid2_args *uap)
+{
+	clockid_t clk_id;
+	struct proc *p;
+	pid_t pid;
+	lwpid_t tid;
+	int error;
+
+	switch(uap->which) {
+	case CPUCLOCK_WHICH_PID:
+		if (uap->id != 0) {
+			p = pfind(uap->id);
+			if (p == NULL)
+				return (ESRCH);
+			error = p_cansee(td, p);
+			PROC_UNLOCK(p);
+			if (error)
+				return (error);
+			pid = uap->id;
+		} else {
+			pid = td->td_proc->p_pid;
+		}
+		clk_id = MAKE_PROCESS_CPUCLOCK(pid);
+		break;
+	case CPUCLOCK_WHICH_TID:
+		if (uap->id == 0)
+			tid = td->td_tid;
+		else
+			tid = uap->id;
+		clk_id = MAKE_THREAD_CPUCLOCK(tid);
+		break;
+	default:
+		return (EINVAL);
+	}
+	return (copyout(&clk_id, uap->clock_id, sizeof(clockid_t)));
+}
+
+#ifndef _SYS_SYSPROTO_H_
 struct clock_gettime_args {
 	clockid_t clock_id;
 	struct	timespec *tp;
@@ -181,12 +233,80 @@ sys_clock_gettime(struct thread *td, str
 	return (error);
 }
 
+static inline void 
+cputick2timespec(uint64_t runtime, struct timespec *ats)
+{
+	runtime = cputick2usec(runtime);
+	ats->tv_sec = runtime / 1000000;
+	ats->tv_nsec = runtime % 1000000 * 1000;
+}
+
+static void
+get_thread_cputime(struct thread *targettd, struct timespec *ats)
+{
+	uint64_t runtime, curtime, switchtime;
+
+	if (targettd == NULL) { /* current thread */
+		critical_enter();
+		switchtime = PCPU_GET(switchtime);
+		curtime = cpu_ticks();
+		runtime = curthread->td_runtime;
+		critical_exit();
+		runtime += curtime - switchtime;
+	} else {
+		thread_lock(targettd);
+		runtime = targettd->td_runtime;
+		thread_unlock(targettd);
+	}
+	cputick2timespec(runtime, ats);
+}
+
+static void
+get_process_cputime(struct proc *targetp, struct timespec *ats)
+{
+	uint64_t runtime;
+	struct rusage ru;
+
+	PROC_SLOCK(targetp);
+	rufetch(targetp, &ru);
+	runtime = targetp->p_rux.rux_runtime;
+	PROC_SUNLOCK(targetp);
+	cputick2timespec(runtime, ats);
+}
+
+static int
+get_cputime(struct thread *td, clockid_t clock_id, struct timespec *ats)
+{
+	struct proc *p, *p2;
+	struct thread *td2;
+	lwpid_t tid;
+	pid_t pid;
+	int error;
+
+	p = td->td_proc;
+	if ((clock_id & CPUCLOCK_PROCESS_BIT) == 0) {
+		tid = clock_id & CPUCLOCK_ID_MASK;
+		td2 = tdfind(tid, p->p_pid);
+		if (td2 == NULL)
+			return (EINVAL);
+		get_thread_cputime(td2, ats);
+		PROC_UNLOCK(td2->td_proc);
+	} else {
+		pid = clock_id & CPUCLOCK_ID_MASK;
+		error = pget(pid, PGET_CANSEE, &p2);
+		if (error != 0)
+			return (EINVAL);
+		get_process_cputime(p2, ats);
+		PROC_UNLOCK(p2);
+	}
+	return (0);
+}
+
 int
 kern_clock_gettime(struct thread *td, clockid_t clock_id, struct timespec *ats)
 {
 	struct timeval sys, user;
 	struct proc *p;
-	uint64_t runtime, curtime, switchtime;
 
 	p = td->td_proc;
 	switch (clock_id) {
@@ -229,17 +349,17 @@ kern_clock_gettime(struct thread *td, cl
 		ats->tv_nsec = 0;
 		break;
 	case CLOCK_THREAD_CPUTIME_ID:
-		critical_enter();
-		switchtime = PCPU_GET(switchtime);
-		curtime = cpu_ticks();
-		runtime = td->td_runtime;
-		critical_exit();
-		runtime = cputick2usec(runtime + curtime - switchtime);
-		ats->tv_sec = runtime / 1000000;
-		ats->tv_nsec = runtime % 1000000 * 1000;
+		get_thread_cputime(NULL, ats);
+		break;
+	case CLOCK_PROCESS_CPUTIME_ID:
+		PROC_LOCK(p);
+		get_process_cputime(p, ats);
+		PROC_UNLOCK(p);
 		break;
 	default:
-		return (EINVAL);
+		if ((int)clock_id >= 0)
+			return (EINVAL);
+		return (get_cputime(td, clock_id, ats));
 	}
 	return (0);
 }
@@ -333,12 +453,16 @@ kern_clock_getres(struct thread *td, clo
 		ts->tv_nsec = 0;
 		break;
 	case CLOCK_THREAD_CPUTIME_ID:
+	case CLOCK_PROCESS_CPUTIME_ID:
+	cputime:
 		/* sync with cputick2usec */
 		ts->tv_nsec = 1000000 / cpu_tickrate();
 		if (ts->tv_nsec == 0)
 			ts->tv_nsec = 1000;
 		break;
 	default:
+		if ((int)clock_id < 0)
+			goto cputime;
 		return (EINVAL);
 	}
 	return (0);

Modified: stable/9/sys/kern/syscalls.c
==============================================================================
--- stable/9/sys/kern/syscalls.c	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/sys/kern/syscalls.c	Fri Aug 16 06:40:12 2013	(r254398)
@@ -254,7 +254,7 @@ const char *syscallnames[] = {
 	"#244",			/* 244 = nosys */
 	"#245",			/* 245 = nosys */
 	"#246",			/* 246 = nosys */
-	"#247",			/* 247 = nosys */
+	"clock_getcpuclockid2",			/* 247 = clock_getcpuclockid2 */
 	"ntp_gettime",			/* 248 = ntp_gettime */
 	"#249",			/* 249 = nosys */
 	"minherit",			/* 250 = minherit */

Modified: stable/9/sys/kern/syscalls.master
==============================================================================
--- stable/9/sys/kern/syscalls.master	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/sys/kern/syscalls.master	Fri Aug 16 06:40:12 2013	(r254398)
@@ -461,7 +461,8 @@
 244	AUE_NULL	UNIMPL	nosys
 245	AUE_NULL	UNIMPL	nosys
 246	AUE_NULL	UNIMPL	nosys
-247	AUE_NULL	UNIMPL	nosys
+247	AUE_NULL	STD	{ int clock_getcpuclockid2(id_t id,\
+				    int which, clockid_t *clock_id); }
 248	AUE_NULL	STD	{ int ntp_gettime(struct ntptimeval *ntvp); }
 249	AUE_NULL	UNIMPL	nosys
 ; syscall numbers initially used in OpenBSD

Modified: stable/9/sys/kern/systrace_args.c
==============================================================================
--- stable/9/sys/kern/systrace_args.c	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/sys/kern/systrace_args.c	Fri Aug 16 06:40:12 2013	(r254398)
@@ -1337,6 +1337,15 @@ systrace_args(int sysnum, void *params, 
 		*n_args = 2;
 		break;
 	}
+	/* clock_getcpuclockid2 */
+	case 247: {
+		struct clock_getcpuclockid2_args *p = params;
+		iarg[0] = p->id; /* id_t */
+		iarg[1] = p->which; /* int */
+		uarg[2] = (intptr_t) p->clock_id; /* clockid_t * */
+		*n_args = 3;
+		break;
+	}
 	/* ntp_gettime */
 	case 248: {
 		struct ntp_gettime_args *p = params;
@@ -5393,6 +5402,22 @@ systrace_setargdesc(int sysnum, int ndx,
 			break;
 		};
 		break;
+	/* clock_getcpuclockid2 */
+	case 247:
+		switch(ndx) {
+		case 0:
+			p = "id_t";
+			break;
+		case 1:
+			p = "int";
+			break;
+		case 2:
+			p = "clockid_t *";
+			break;
+		default:
+			break;
+		};
+		break;
 	/* ntp_gettime */
 	case 248:
 		switch(ndx) {

Modified: stable/9/sys/sys/syscall.h
==============================================================================
--- stable/9/sys/sys/syscall.h	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/sys/sys/syscall.h	Fri Aug 16 06:40:12 2013	(r254398)
@@ -216,6 +216,7 @@
 #define	SYS_ktimer_gettime	238
 #define	SYS_ktimer_getoverrun	239
 #define	SYS_nanosleep	240
+#define	SYS_clock_getcpuclockid2	247
 #define	SYS_ntp_gettime	248
 #define	SYS_minherit	250
 #define	SYS_rfork	251

Modified: stable/9/sys/sys/syscall.mk
==============================================================================
--- stable/9/sys/sys/syscall.mk	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/sys/sys/syscall.mk	Fri Aug 16 06:40:12 2013	(r254398)
@@ -168,6 +168,7 @@ MIASM =  \
 	ktimer_gettime.o \
 	ktimer_getoverrun.o \
 	nanosleep.o \
+	clock_getcpuclockid2.o \
 	ntp_gettime.o \
 	minherit.o \
 	rfork.o \

Modified: stable/9/sys/sys/sysproto.h
==============================================================================
--- stable/9/sys/sys/sysproto.h	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/sys/sys/sysproto.h	Fri Aug 16 06:40:12 2013	(r254398)
@@ -726,6 +726,11 @@ struct nanosleep_args {
 	char rqtp_l_[PADL_(const struct timespec *)]; const struct timespec * rqtp; char rqtp_r_[PADR_(const struct timespec *)];
 	char rmtp_l_[PADL_(struct timespec *)]; struct timespec * rmtp; char rmtp_r_[PADR_(struct timespec *)];
 };
+struct clock_getcpuclockid2_args {
+	char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)];
+	char which_l_[PADL_(int)]; int which; char which_r_[PADR_(int)];
+	char clock_id_l_[PADL_(clockid_t *)]; clockid_t * clock_id; char clock_id_r_[PADR_(clockid_t *)];
+};
 struct ntp_gettime_args {
 	char ntvp_l_[PADL_(struct ntptimeval *)]; struct ntptimeval * ntvp; char ntvp_r_[PADR_(struct ntptimeval *)];
 };
@@ -1902,6 +1907,7 @@ int	sys_ktimer_settime(struct thread *, 
 int	sys_ktimer_gettime(struct thread *, struct ktimer_gettime_args *);
 int	sys_ktimer_getoverrun(struct thread *, struct ktimer_getoverrun_args *);
 int	sys_nanosleep(struct thread *, struct nanosleep_args *);
+int	sys_clock_getcpuclockid2(struct thread *, struct clock_getcpuclockid2_args *);
 int	sys_ntp_gettime(struct thread *, struct ntp_gettime_args *);
 int	sys_minherit(struct thread *, struct minherit_args *);
 int	sys_rfork(struct thread *, struct rfork_args *);
@@ -2590,6 +2596,7 @@ int	freebsd7_shmctl(struct thread *, str
 #define	SYS_AUE_ktimer_gettime	AUE_NULL
 #define	SYS_AUE_ktimer_getoverrun	AUE_NULL
 #define	SYS_AUE_nanosleep	AUE_NULL
+#define	SYS_AUE_clock_getcpuclockid2	AUE_NULL
 #define	SYS_AUE_ntp_gettime	AUE_NULL
 #define	SYS_AUE_minherit	AUE_MINHERIT
 #define	SYS_AUE_rfork	AUE_RFORK

Modified: stable/9/sys/sys/time.h
==============================================================================
--- stable/9/sys/sys/time.h	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/sys/sys/time.h	Fri Aug 16 06:40:12 2013	(r254398)
@@ -266,6 +266,7 @@ struct clockinfo {
 #define CLOCK_MONOTONIC_FAST	12	/* FreeBSD-specific. */
 #define CLOCK_SECOND	13		/* FreeBSD-specific. */
 #define CLOCK_THREAD_CPUTIME_ID	14
+#define CLOCK_PROCESS_CPUTIME_ID	15
 #endif
 
 #ifndef TIMER_ABSTIME
@@ -273,6 +274,11 @@ struct clockinfo {
 #define TIMER_ABSTIME	0x1	/* absolute timer */
 #endif
 
+#if __BSD_VISIBLE
+#define	CPUCLOCK_WHICH_PID	0
+#define	CPUCLOCK_WHICH_TID	1
+#endif
+
 #ifdef _KERNEL
 
 /*
@@ -344,6 +350,7 @@ int	utimes(const char *, const struct ti
 
 #if __BSD_VISIBLE
 int	adjtime(const struct timeval *, struct timeval *);
+int	clock_getcpuclockid2(id_t, int, clockid_t *);
 int	futimes(int, const struct timeval *);
 int	futimesat(int, const char *, const struct timeval [2]);
 int	lutimes(const char *, const struct timeval *);

Modified: stable/9/sys/sys/unistd.h
==============================================================================
--- stable/9/sys/sys/unistd.h	Fri Aug 16 05:30:13 2013	(r254397)
+++ stable/9/sys/sys/unistd.h	Fri Aug 16 06:40:12 2013	(r254398)
@@ -53,7 +53,7 @@
 #define	_POSIX_ASYNCHRONOUS_IO		0
 #define	_POSIX_CHOWN_RESTRICTED		1
 #define	_POSIX_CLOCK_SELECTION		(-1)
-#define	_POSIX_CPUTIME			(-1)
+#define	_POSIX_CPUTIME			200112L
 #define	_POSIX_FSYNC			200112L
 #define	_POSIX_IPV6			0
 #define	_POSIX_JOB_CONTROL		1
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 4 Ed Maste freebsd_committer 2015-05-14 21:20:06 UTC
Is this resolved now?