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.salin...@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 <davi...@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-unsubscr...@freebsd.org"

Reply via email to