This is follow up to http://www.freebsd.org/cgi/query-pr.cgi?pr=168417 Our testsuite expects, that clock id created by clock_getcpuclockid() is valid also in time frame after process exit before its reap by parent. http://sourceware.org/git/?p=glibc.git;a=blob;f=rt/tst-cpuclock1.c;hb=HEAD live PID 46968 clock ffffffffc000b778 resolution 0.000001000 live PID 46968 before sleep => 0.000000000 live PID 46968 after sleep => 0.506846000 clock_nanosleep not supported for other process clock: Operation not supported clock_gettime on dead PID 46968 clock ffffffffc000b778 => Invalid argument It is rather reasonable expectation. Please allow getting of used time also for zombie processes.
Please try this. The clock_gettime() call on zombie clock worked for me. Note that the check for clock_getres() on the reapped process clock failed since we do not check for pid validity, all processes has the same clock. I do not see much sense in adding the useless check. diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index b68c949..9e0cc06 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -297,14 +297,9 @@ get_cputime(struct thread *td, clockid_t clock_id, struct timespec *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); + error = pget(pid, PGET_CANSEE, &p2); + if (error != 0) return (EINVAL); - } get_process_cputime(p2, ats); PROC_UNLOCK(p2); }
> Please try this. The clock_gettime() call on zombie clock worked > for me. Perfect. Many thanks. > Note that the check for clock_getres() on the reapped process clock > failed since we do not check for pid validity, all processes has > the same clock. I do not see much sense in adding the useless check. I agree that such check is technically useless. I cannot imagine usage of such restriction. The only reason of this check is wording of POSIX standard in http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html "The clock_getres(), clock_gettime(), and clock_settime() functions shall fail if: [EINVAL] The clock_id argument does not specify a known clock." But this behaviour can be easily added in userspace wrapper. Similarly as " The clock_settime() function shall fail if: [EINVAL] The value of the clock_id argument is CLOCK_MONOTONIC." The kernel returns EPERM for ordinary user. Would be possible to MFC SYS_clock_getcpuclockid2 and related kernel changes into STABLE-9 ? Thanks again Petr
Author: kib Date: Sat Jul 13 19:32:50 2013 New Revision: 253325 URL: http://svnweb.freebsd.org/changeset/base/253325 Log: 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 Modified: head/sys/kern/kern_time.c Modified: head/sys/kern/kern_time.c ============================================================================== --- head/sys/kern/kern_time.c Sat Jul 13 18:09:42 2013 (r253324) +++ head/sys/kern/kern_time.c Sat Jul 13 19:32:50 2013 (r253325) @@ -297,14 +297,9 @@ get_cputime(struct thread *td, clockid_t 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); + error = pget(pid, PGET_CANSEE, &p2); + if (error != 0) return (EINVAL); - } get_process_cputime(p2, ats); PROC_UNLOCK(p2); } _______________________________________________ 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"
On Fri, Jul 12, 2013 at 10:59:51PM +0200, Petr Salinger wrote: > > Please try this. The clock_gettime() call on zombie clock worked > > for me. > > Perfect. Many thanks. > > > > Note that the check for clock_getres() on the reapped process clock > > failed since we do not check for pid validity, all processes has > > the same clock. I do not see much sense in adding the useless check. > > I agree that such check is technically useless. > I cannot imagine usage of such restriction. > > The only reason of this check is wording of POSIX standard in > http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html > > "The clock_getres(), clock_gettime(), and clock_settime() functions shall > fail if: > [EINVAL] > The clock_id argument does not specify a known clock." I could argue that the clock_id for the reapped pid is/was known. Anyway, due to our implementation of the clock ids, the id is not a handle, but rather a pid-like value. The reused pid would suddenly revive the clock. > > But this behaviour can be easily added in userspace wrapper. > Similarly as > " The clock_settime() function shall fail if: > [EINVAL] > The value of the clock_id argument is CLOCK_MONOTONIC." > > The kernel returns EPERM for ordinary user. > > > Would be possible to MFC SYS_clock_getcpuclockid2 > and related kernel changes into STABLE-9 ? stable/9 is frozen for 9.2. I do not think that re would approve merging of the non-critical new feature now.
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"
Is this resolved now?
batch change: For bugs that match the following - Status Is In progress AND - Untouched since 2018-01-01. AND - Affects Base System OR Documentation DO: Reset to open status. Note: I did a quick pass but if you are getting this email it might be worthwhile to double check to see if this bug ought to be closed.
Assumed resolved, but not confirmed because of feedback timeout.