--- src/include/time.h 2012-03-28 12:36:00.000000000 0000 +++ src/include/time.h 2012-07-12 03:11:46.000000000 0000 @@ -88,6 +88,13 @@ #include #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,14 @@ int nanosleep(const struct timespec *, struct timespec *); #endif /* __POSIX_VISIBLE >= 199309 */ +#if __POSIX_VISIBLE >= 200112 +int clock_getcpuclockid(pid_t, clockid_t *); +#endif + +#if __BSD_VISIBLE +int clock_getthreadcpuclockid(__lwpid_t, clockid_t *); +#endif + #if __POSIX_VISIBLE >= 199506 char *asctime_r(const struct tm *, char *); char *ctime_r(const time_t *, char *); --- src/lib/libc/sys/Symbol.map 2012-07-10 08:36:40.000000000 0000 +++ src/lib/libc/sys/Symbol.map 2012-07-12 02:57:20.000000000 0000 @@ -383,6 +383,8 @@ ffclock_getestimate; ffclock_setestimate; posix_fadvise; + clock_getcpuclockid; + clock_getthreadcpuclockid; }; FBSDprivate_1.0 { @@ -490,8 +492,12 @@ __sys_chown; _chroot; __sys_chroot; + _clock_getcpuclockid; + __sys_clock_getcpuclockid; _clock_getres; __sys_clock_getres; + _clock_getthreadcpuclockid; + __sys_clock_getthreadcpuclockid; _clock_gettime; __sys_clock_gettime; _clock_settime; --- src/lib/libthr/thread/thr_getcpuclockid.c 2008-03-22 10:39:19.000000000 0000 +++ src/lib/libthr/thread/thr_getcpuclockid.c 2012-07-12 09:20:47.000000000 0000 @@ -39,9 +39,11 @@ int _pthread_getcpuclockid(pthread_t pthread, clockid_t *clock_id) { + if (pthread == NULL) return (EINVAL); - *clock_id = CLOCK_THREAD_CPUTIME_ID; + if (clock_getthreadcpuclockid(TID(pthread), clock_id)) + return (errno); return (0); } --- src/sys/kern/init_sysent.c 2012-05-31 19:35:28.000000000 0000 +++ src/sys/kern/init_sysent.c 2012-07-11 09:48:13.000000000 0000 @@ -2,8 +2,8 @@ * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/kern/init_sysent.c,v 1.270 2012/05/31 19:34:53 pjd Exp $ - * created from FreeBSD: head/sys/kern/syscalls.master 236026 2012-05-25 21:50:48Z ed + * $FreeBSD$ + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.275 2012/05/25 21:50:48 ed Exp */ #include "opt_compat.h" @@ -566,4 +566,6 @@ { AS(rctl_remove_rule_args), (sy_call_t *)sys_rctl_remove_rule, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 529 = rctl_remove_rule */ { AS(posix_fallocate_args), (sy_call_t *)sys_posix_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 530 = posix_fallocate */ { AS(posix_fadvise_args), (sy_call_t *)sys_posix_fadvise, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 531 = posix_fadvise */ + { AS(clock_getthreadcpuclockid_args), (sy_call_t *)sys_clock_getthreadcpuclockid, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 532 = clock_getthreadcpuclockid */ + { AS(clock_getcpuclockid_args), (sy_call_t *)sys_clock_getcpuclockid, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 533 = clock_getcpuclockid */ }; --- src/sys/kern/kern_time.c 2011-09-16 14:00:32.000000000 0000 +++ src/sys/kern/kern_time.c 2012-07-19 08:47:14.000000000 0000 @@ -58,6 +58,12 @@ #include #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,48 @@ } #ifndef _SYS_SYSPROTO_H_ +struct clock_getcpuclockid_args { + pid_t pid; + clockid_t *clock_id; +}; +#endif +/* ARGSUSED */ +int +sys_clock_getcpuclockid(struct thread *td, struct clock_getcpuclockid_args *uap) +{ + clockid_t id; + struct proc *p; + int error; + + p = pfind(uap->pid); + if (p == NULL) + return (ESRCH); + error = p_cansee(td, p); + PROC_UNLOCK(p); + if (error) + return (error); + id = MAKE_PROCESS_CPUCLOCK(uap->pid); + return (copyout(&id, uap->clock_id, sizeof(id))); +} + +#ifndef _SYS_SYSPROTO_H_ +struct clock_getthreadcpuclockid_args { + lwpid_t tid; + clockid_t *clock_id; +}; +#endif +/* ARGSUSED */ +int +sys_clock_getthreadcpuclockid(struct thread *td, + struct clock_getthreadcpuclockid_args *uap) +{ + clockid_t id; + + id = MAKE_THREAD_CPUCLOCK(uap->tid); + return (copyout(&id, uap->clock_id, sizeof(id))); +} + +#ifndef _SYS_SYSPROTO_H_ struct clock_gettime_args { clockid_t clock_id; struct timespec *tp; @@ -184,12 +232,85 @@ 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 +353,17 @@ 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 +457,16 @@ 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); --- src/sys/kern/syscalls.c 2012-05-25 21:55:20.000000000 0000 +++ src/sys/kern/syscalls.c 2012-07-11 09:48:13.000000000 0000 @@ -2,8 +2,8 @@ * System call names. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/kern/syscalls.c,v 1.251 2012/05/25 21:52:57 ed Exp $ - * created from FreeBSD: head/sys/kern/syscalls.master 236026 2012-05-25 21:50:48Z ed + * $FreeBSD$ + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.275 2012/05/25 21:50:48 ed Exp */ const char *syscallnames[] = { @@ -539,4 +539,6 @@ "rctl_remove_rule", /* 529 = rctl_remove_rule */ "posix_fallocate", /* 530 = posix_fallocate */ "posix_fadvise", /* 531 = posix_fadvise */ + "clock_getthreadcpuclockid", /* 532 = clock_getthreadcpuclockid */ + "clock_getcpuclockid", /* 533 = clock_getcpuclockid */ }; --- src/sys/kern/syscalls.master 2012-05-25 21:55:20.000000000 0000 +++ src/sys/kern/syscalls.master 2012-07-11 09:48:13.000000000 0000 @@ -951,5 +951,9 @@ off_t offset, off_t len); } 531 AUE_NULL STD { int posix_fadvise(int fd, off_t offset, \ off_t len, int advice); } +532 AUE_NULL STD { int clock_getthreadcpuclockid(lwpid_t tid,\ + clockid_t *clock_id); } +533 AUE_NULL STD { int clock_getcpuclockid(pid_t pid,\ + clockid_t *clock_id); } ; Please copy any additions and changes to the following compatability tables: ; sys/compat/freebsd32/syscalls.master --- src/sys/kern/systrace_args.c 2012-05-25 21:55:20.000000000 0000 +++ src/sys/kern/systrace_args.c 2012-07-11 09:48:13.000000000 0000 @@ -2,7 +2,7 @@ * System call argument to DTrace register array converstion. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/kern/systrace_args.c,v 1.47 2012/05/25 21:52:57 ed Exp $ + * $FreeBSD$ * This file is part of the DTrace syscall provider. */ @@ -3265,6 +3265,22 @@ *n_args = 4; break; } + /* clock_getthreadcpuclockid */ + case 532: { + struct clock_getthreadcpuclockid_args *p = params; + iarg[0] = p->tid; /* lwpid_t */ + uarg[1] = (intptr_t) p->clock_id; /* clockid_t * */ + *n_args = 2; + break; + } + /* clock_getcpuclockid */ + case 533: { + struct clock_getcpuclockid_args *p = params; + iarg[0] = p->pid; /* pid_t */ + uarg[1] = (intptr_t) p->clock_id; /* clockid_t * */ + *n_args = 2; + break; + } default: *n_args = 0; break; @@ -8683,6 +8699,32 @@ break; }; break; + /* clock_getthreadcpuclockid */ + case 532: + switch(ndx) { + case 0: + p = "lwpid_t"; + break; + case 1: + p = "clockid_t *"; + break; + default: + break; + }; + break; + /* clock_getcpuclockid */ + case 533: + switch(ndx) { + case 0: + p = "pid_t"; + break; + case 1: + p = "clockid_t *"; + break; + default: + break; + }; + break; default: break; }; @@ -10566,6 +10608,16 @@ if (ndx == 0 || ndx == 1) p = "int"; break; + /* clock_getthreadcpuclockid */ + case 532: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* clock_getcpuclockid */ + case 533: + if (ndx == 0 || ndx == 1) + p = "int"; + break; default: break; }; --- src/sys/sys/syscall.h 2012-05-25 21:55:20.000000000 0000 +++ src/sys/sys/syscall.h 2012-07-11 09:48:13.000000000 0000 @@ -2,8 +2,8 @@ * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/sys/syscall.h,v 1.248 2012/05/25 21:52:57 ed Exp $ - * created from FreeBSD: head/sys/kern/syscalls.master 236026 2012-05-25 21:50:48Z ed + * $FreeBSD$ + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.275 2012/05/25 21:50:48 ed Exp */ #define SYS_syscall 0 @@ -450,4 +450,6 @@ #define SYS_rctl_remove_rule 529 #define SYS_posix_fallocate 530 #define SYS_posix_fadvise 531 -#define SYS_MAXSYSCALL 532 +#define SYS_clock_getthreadcpuclockid 532 +#define SYS_clock_getcpuclockid 533 +#define SYS_MAXSYSCALL 534 --- src/sys/sys/syscall.mk 2012-05-25 21:55:20.000000000 0000 +++ src/sys/sys/syscall.mk 2012-07-11 09:48:13.000000000 0000 @@ -1,7 +1,7 @@ # FreeBSD system call names. # DO NOT EDIT-- this file is automatically generated. -# $FreeBSD: src/sys/sys/syscall.mk,v 1.203 2012/05/25 21:52:57 ed Exp $ -# created from FreeBSD: head/sys/kern/syscalls.master 236026 2012-05-25 21:50:48Z ed +# $FreeBSD$ +# created from FreeBSD: src/sys/kern/syscalls.master,v 1.275 2012/05/25 21:50:48 ed Exp MIASM = \ syscall.o \ exit.o \ @@ -398,4 +398,6 @@ rctl_add_rule.o \ rctl_remove_rule.o \ posix_fallocate.o \ - posix_fadvise.o + posix_fadvise.o \ + clock_getthreadcpuclockid.o \ + clock_getcpuclockid.o --- src/sys/sys/sysproto.h 2012-05-25 21:55:20.000000000 0000 +++ src/sys/sys/sysproto.h 2012-07-11 09:48:13.000000000 0000 @@ -2,8 +2,8 @@ * System call prototypes. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/sys/sysproto.h,v 1.256 2012/05/25 21:52:57 ed Exp $ - * created from FreeBSD: head/sys/kern/syscalls.master 236026 2012-05-25 21:50:48Z ed + * $FreeBSD$ + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.275 2012/05/25 21:50:48 ed Exp */ #ifndef _SYS_SYSPROTO_H_ @@ -1749,6 +1749,14 @@ char len_l_[PADL_(off_t)]; off_t len; char len_r_[PADR_(off_t)]; char advice_l_[PADL_(int)]; int advice; char advice_r_[PADR_(int)]; }; +struct clock_getthreadcpuclockid_args { + char tid_l_[PADL_(lwpid_t)]; lwpid_t tid; char tid_r_[PADR_(lwpid_t)]; + char clock_id_l_[PADL_(clockid_t *)]; clockid_t * clock_id; char clock_id_r_[PADR_(clockid_t *)]; +}; +struct clock_getcpuclockid_args { + char pid_l_[PADL_(pid_t)]; pid_t pid; char pid_r_[PADR_(pid_t)]; + char clock_id_l_[PADL_(clockid_t *)]; clockid_t * clock_id; char clock_id_r_[PADR_(clockid_t *)]; +}; int nosys(struct thread *, struct nosys_args *); void sys_sys_exit(struct thread *, struct sys_exit_args *); int sys_fork(struct thread *, struct fork_args *); @@ -2129,6 +2137,8 @@ int sys_rctl_remove_rule(struct thread *, struct rctl_remove_rule_args *); int sys_posix_fallocate(struct thread *, struct posix_fallocate_args *); int sys_posix_fadvise(struct thread *, struct posix_fadvise_args *); +int sys_clock_getthreadcpuclockid(struct thread *, struct clock_getthreadcpuclockid_args *); +int sys_clock_getcpuclockid(struct thread *, struct clock_getcpuclockid_args *); #ifdef COMPAT_43 @@ -2823,6 +2833,8 @@ #define SYS_AUE_rctl_remove_rule AUE_NULL #define SYS_AUE_posix_fallocate AUE_NULL #define SYS_AUE_posix_fadvise AUE_NULL +#define SYS_AUE_clock_getthreadcpuclockid AUE_NULL +#define SYS_AUE_clock_getcpuclockid AUE_NULL #undef PAD_ #undef PADL_ --- src/sys/sys/time.h 2011-08-09 14:11:29.000000000 0000 +++ src/sys/sys/time.h 2012-07-12 03:39:31.000000000 0000 @@ -266,6 +266,7 @@ #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