libc/libpthread: Add clock_getcpuclockid() and pthread_getcpuclockid().
authorSascha Wildner <saw@online.de>
Wed, 26 Jul 2017 17:57:32 +0000 (19:57 +0200)
committerSascha Wildner <saw@online.de>
Wed, 26 Jul 2017 17:57:32 +0000 (19:57 +0200)
* Adjust clock_gettime() and clock_getres() to accept values obtained
  this way.

* Also set _POSIX_CPUTIME and _POSIX_THREAD_CPUTIME, although we should
  really support values obtained by these functions in clock_settime()
  too.

Based on and taken from FreeBSD's code.

Reviewed-by: sephe
28 files changed:
include/pthread.h
include/time.h
include/unistd.h
lib/libc/gen/Makefile.inc
lib/libc/gen/Symbol.map
lib/libc/gen/_pthread_stubs.c
lib/libc/gen/clock_getcpuclockid.3 [new file with mode: 0644]
lib/libc/gen/clock_getcpuclockid.c [new file with mode: 0644]
lib/libc/include/namespace.h
lib/libc/include/un-namespace.h
lib/libc/sys/Symbol.map
lib/libc/sys/clock_gettime.2
lib/libpthread/Makefile
lib/libpthread/pthread_getcpuclockid.3 [new file with mode: 0644]
lib/libthread_xu/pthread.map
lib/libthread_xu/thread/Makefile.inc
lib/libthread_xu/thread/thr_getcpuclockid.c [new file with mode: 0644]
lib/libthread_xu/thread/thr_init.c
sys/kern/init_sysent.c
sys/kern/kern_time.c
sys/kern/syscalls.c
sys/kern/syscalls.master
sys/sys/param.h
sys/sys/syscall.h
sys/sys/syscall.mk
sys/sys/sysproto.h
sys/sys/sysunion.h
sys/sys/unistd.h

index 666202f..12fb145 100644 (file)
@@ -198,6 +198,7 @@ int pthread_detach(pthread_t);
 int    pthread_equal(pthread_t, pthread_t);
 void   pthread_exit(void *) __dead2;
 void   *pthread_getspecific(pthread_key_t);
+int    pthread_getcpuclockid(pthread_t, clockid_t *) __nonnull(2);
 int    pthread_join(pthread_t, void **);
 int    pthread_key_create(pthread_key_t *, void (*) (void *)) __nonnull(1);
 int    pthread_key_delete(pthread_key_t);
index 665ed72..94c2fd7 100644 (file)
@@ -96,6 +96,13 @@ typedef      __pid_t         pid_t;
 #endif
 #endif
 
+#if __BSD_VISIBLE
+#ifndef _LWPID_T_DECLARED
+#define        _LWPID_T_DECLARED
+typedef        __pid_t         lwpid_t;        /* light weight process id */
+#endif
+#endif
+
 /* These macros are also in sys/time.h. */
 #if !defined(CLOCK_REALTIME) && __POSIX_VISIBLE >= 199309
 #define        CLOCK_REALTIME          0
@@ -180,9 +187,9 @@ struct tm *localtime_r(const time_t *, struct tm *);
 #endif
 
 #if __POSIX_VISIBLE >= 200112
+int clock_getcpuclockid(pid_t, clockid_t *);
 #if 0 /* XXX missing */
 struct sigevent;
-int clock_getcpuclockid(pid_t, clockid_t *);
 int clock_nanosleep(clockid_t, int, const struct timespec *, struct timespec *);
 int timer_create(clockid_t, struct sigevent *__restrict, timer_t *__restrict);
 int timer_delete(timer_t);
@@ -201,6 +208,7 @@ char *strptime(const char * __restrict, const char * __restrict,
 #endif
 
 #if __BSD_VISIBLE
+int getcpuclockid(pid_t, lwpid_t, clockid_t *);
 void tzsetwall(void);
 time_t timelocal(struct tm * const);
 time_t timegm(struct tm * const);
index 638cc91..906ef75 100644 (file)
@@ -99,7 +99,6 @@ typedef       __uint32_t      uid_t;          /* XXX __uid_t */
 #define        _POSIX_SPAWN                    200112L /* [SPN] */
 #define        _POSIX_THREAD_ATTR_STACKADDR    200112L /* [TSA] */
 #define        _POSIX_THREAD_ATTR_STACKSIZE    200112L /* [TSS] */
-#define        _POSIX_THREAD_CPUTIME           -1      /* [TCT] */
 #define        _POSIX_THREAD_PRIO_INHERIT      200112L /* [TPI] */
 #define        _POSIX_THREAD_PRIO_PROTECT      200112L /* [TPP] */
 #define        _POSIX_THREAD_PRIORITY_SCHEDULING 200112L /* [TPS] */
index 7aa4851..5ea0977 100644 (file)
@@ -10,7 +10,7 @@ CMAPS+=       ${.CURDIR}/gen/Symbol.map
 
 SRCS+=  _once_stub.c _pthread_stubs.c _rand48.c _spinlock_stub.c \
        _thread_init.c alarm.c arc4random.c assert.c basename.c \
-       clock.c closedir.c confstr.c creat.c \
+       clock.c clock_getcpuclockid.c closedir.c confstr.c creat.c \
        ctermid.c daemon.c devname.c dirfd.c dirname.c disklabel.c disktab.c \
        dlfcn.c drand48.c elf_utils.c erand48.c err.c errlst.c exec.c \
        fdevname.c fmtcheck.c fmtmsg.c fnmatch.c fpclassify.c \
@@ -53,7 +53,7 @@ SRCS+=        tls.c
 .if ${LIB} == "c"
 MAN+=  alarm.3 arc4random.3 clock.3 \
        basename.3 \
-       confstr.3 creat.3 ctermid.3 daemon.3 \
+       clock_getcpuclockid.3 confstr.3 creat.3 ctermid.3 daemon.3 \
        devname.3 directory.3 dirname.3 \
        dladdr.3 dlinfo.3 dlopen.3 \
        dlclose.3 dlerror.3 dlfcn.3 dlsym.3 dlvsym.3 dl_iterate_phdr.3 \
index bdfce2b..5b23ed7 100644 (file)
@@ -460,7 +460,9 @@ DF404.0 {
 };
 
 DF410.0 {
+    clock_getcpuclockid;
        /* pthread stubs */
+    pthread_getcpuclockid;
     pthread_getthreadid_np;
 };
 
@@ -518,6 +520,7 @@ DFprivate_1.0 {
     _pthread_exit;
     _pthread_getaffinity_np;
     _pthread_getconcurrency;
+    _pthread_getcpuclockid;
     _pthread_getprio;
     _pthread_getschedparam;
     _pthread_getspecific;
index 13c0bd0..a44debe 100644 (file)
@@ -99,6 +99,7 @@ WR(stub_true, pthread_equal);
 WR(stub_exit, pthread_exit);
 WR(stub_zero, pthread_getaffinity_np);
 WR(stub_zero, pthread_getconcurrency);
+WR(stub_zero, pthread_getcpuclockid);
 WR(stub_zero, pthread_getprio);
 WR(stub_zero, pthread_getschedparam);
 WR(stub_null, pthread_getspecific);
diff --git a/lib/libc/gen/clock_getcpuclockid.3 b/lib/libc/gen/clock_getcpuclockid.3
new file mode 100644 (file)
index 0000000..08d9802
--- /dev/null
@@ -0,0 +1,98 @@
+.\" 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 THE AUTHOR 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.
+.\"
+.\" Portions of this text are reprinted and reproduced in electronic form
+.\" from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology --
+.\" Portable Operating System Interface (POSIX), The Open Group Base
+.\" Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of
+.\" Electrical and Electronics Engineers, Inc and The Open Group.  In the
+.\" event of any discrepancy between this version and the original IEEE and
+.\" The Open Group Standard, the original IEEE and The Open Group Standard is
+.\" the referee document.  The original Standard can be obtained online at
+.\"    http://www.opengroup.org/unix/online.html.
+.\"
+.\" $FreeBSD: head/lib/libc/gen/clock_getcpuclockid.3 303742 2016-08-04 11:38:53Z pluknet $
+.\"
+.Dd July 26, 2017
+.Dt CLOCK_GETCPUCLOCKID 3
+.Os
+.Sh NAME
+.Nm clock_getcpuclockid
+.Nd access a process CPU-time clock
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In time.h
+.Ft int
+.Fn clock_getcpuclockid "pid_t pid" "clockid_t *clock_id"
+.Sh DESCRIPTION
+The
+.Fn clock_getcpuclockid
+function returns the clock ID of the CPU-time clock of the process specified by
+.Fa pid .
+If the process described by
+.Fa pid
+exists and the calling process has permission, the clock ID of this
+clock will be returned in
+.Fa clock_id .
+.Pp
+If
+.Fa pid
+is zero,
+.Fn clock_getcpuclockid
+returns the clock ID of the CPU-time clock of the process
+making the call.
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn clock_getcpuclockid
+returns zero; otherwise, an error number is returned to indicate the
+error.
+.Sh ERRORS
+The
+.Fn clock_getcpuclockid
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EPERM
+The requesting process does not have permission to access the CPU-time
+clock for the process.
+.It Bq Er ESRCH
+No process can be found corresponding to the process specified by
+.Fa pid .
+.El
+.Sh SEE ALSO
+.Xr clock_gettime 2
+.Sh STANDARDS
+The
+.Fn clock_getcpuclockid
+function conforms to
+.St -p1003.1-2001 .
+.Sh HISTORY
+The
+.Fn clock_getcpuclockid
+function first appeared in
+.Fx 10.0
+and was ported to
+.Dx 4.9 .
+.Sh AUTHORS
+.An David Xu Aq Mt davidxu@FreeBSD.org
diff --git a/lib/libc/gen/clock_getcpuclockid.c b/lib/libc/gen/clock_getcpuclockid.c
new file mode 100644 (file)
index 0000000..62696bd
--- /dev/null
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2017 The DragonFly Project.  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.
+ * 3. Neither the name of The DragonFly Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific, prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDERS 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 <errno.h>
+#include <time.h>
+
+int
+clock_getcpuclockid(pid_t pid, clockid_t *clock_id)
+{
+       if (getcpuclockid(pid, 0, clock_id))
+               return (errno);
+       return (0);
+}
index e2ad237..d40d59a 100644 (file)
 #define                pthread_exit                    _pthread_exit
 #define                pthread_getaffinity_np          _pthread_getaffinity_np
 #define                pthread_getconcurrency          _pthread_getconcurrency
+#define                pthread_getcpuclockid           _pthread_getcpuclockid
 #define                pthread_getprio                 _pthread_getprio
 #define                pthread_getschedparam           _pthread_getschedparam
 #define                pthread_getspecific             _pthread_getspecific
index cecfc36..7ad87d7 100644 (file)
 #undef         pthread_exit
 #undef         pthread_getaffinity_np
 #undef         pthread_getconcurrency
+#undef         pthread_getcpuclockid
 #undef         pthread_getprio
 #undef         pthread_getschedparam
 #undef         pthread_getspecific
index ece6736..7cc20d1 100644 (file)
@@ -320,6 +320,10 @@ DF408.0 {
     lwp_setaffinity;
 };
 
+DF410.0 {
+    getcpuclockid;
+};
+
 DFprivate_1.0 {
     __fork;
 
@@ -402,6 +406,7 @@ DFprivate_1.0 {
     __sys_futimens;
     __sys_futimes;
     __sys_get_tls_area;
+    __sys_getcpuclockid;
     __sys_getdents;
     __sys_getdirentries;
     __sys_getdtablesize;
@@ -700,6 +705,7 @@ DFprivate_1.0 {
     _futimens;
     _futimes;
     _get_tls_area;
+    _getcpuclockid;
     _getdents;
     _getdirentries;
     _getdtablesize;
index dcab0f0..5ac754c 100644 (file)
@@ -29,7 +29,7 @@
 .\"
 .\" $FreeBSD: head/lib/libc/sys/clock_gettime.2 292777 2015-12-27 15:37:07Z dchagin $
 .\"
-.Dd September 26, 2016
+.Dd July 26, 2017
 .Dt CLOCK_GETTIME 2
 .Os
 .Sh NAME
@@ -58,37 +58,39 @@ used by a clock which is specified by
 .Pp
 The
 .Fa clock_id
-argument
-can be one of the following values:
-.Dv CLOCK_REALTIME ,
-.Dv CLOCK_REALTIME_PRECISE ,
-and
-.Dv CLOCK_REALTIME_FAST
-for time that increments as a wall clock should;
-.Dv CLOCK_MONOTONIC ,
-.Dv CLOCK_MONOTONIC_PRECISE ,
-and
-.Dv CLOCK_MONOTONIC_FAST
-which increments in SI seconds;
-.Dv CLOCK_UPTIME ,
-.Dv CLOCK_UPTIME_PRECISE ,
-and
-.Dv CLOCK_UPTIME_FAST
-which starts at zero when the kernel boots and increments
-monotonically in SI seconds while the machine is running;
-.Dv CLOCK_VIRTUAL
-for time that increments only when
-the CPU is running in user mode on behalf of the calling process;
-.Dv CLOCK_PROF
-for time that increments when the CPU is running in user or
-kernel mode;
-.Dv CLOCK_SECOND
-which returns the current second without performing a full time counter
-query, using in-kernel cached value of current second;
-.Dv CLOCK_PROCESS_CPUTIME_ID
-which returns the CPU-time clock of the calling process; or
-.Dv CLOCK_THREAD_CPUTIME_ID
-which returns the CPU-time clock of the calling thread.
+argument can be a value obtained from
+.Xr clock_getcpuclockid 3
+or
+.Xr pthread_getcpuclockid 3
+as well as the following values:
+.Pp
+.Bl -tag -width indent -compact
+.It Dv CLOCK_REALTIME
+.It Dv CLOCK_REALTIME_PRECISE
+.It Dv CLOCK_REALTIME_FAST
+Increments as a wall clock should.
+.It Dv CLOCK_MONOTONIC
+.It Dv CLOCK_MONOTONIC_PRECISE
+.It Dv CLOCK_MONOTONIC_FAST
+Increments in SI seconds.
+.It Dv CLOCK_UPTIME
+.It Dv CLOCK_UPTIME_PRECISE
+.It Dv CLOCK_UPTIME_FAST
+Starts at zero when the kernel boots and increments
+monotonically in SI seconds while the machine is running.
+.It Dv CLOCK_VIRTUAL
+Increments only when
+the CPU is running in user mode on behalf of the calling process.
+.It Dv CLOCK_PROF
+Increments when the CPU is running in user or kernel mode.
+.It Dv CLOCK_SECOND
+Returns the current second without performing a full time counter
+query, using an in-kernel cached value of the current second.
+.It Dv CLOCK_PROCESS_CPUTIME_ID
+Returns the execution time of the calling process.
+.It Dv CLOCK_THREAD_CPUTIME_ID
+Returns the execution time of the calling thread.
+.El
 .Pp
 The clock IDs
 .Dv CLOCK_REALTIME_FAST ,
@@ -161,7 +163,9 @@ A user other than the super-user attempted to set the time.
 .Sh SEE ALSO
 .Xr date 1 ,
 .Xr adjtime 2 ,
+.Xr clock_getcpuclockid 3 ,
 .Xr ctime 3 ,
+.Xr pthread_getcpuclockid 3 ,
 .Xr timed 8
 .Sh STANDARDS
 The
index f915fdf..eccab0b 100644 (file)
@@ -18,6 +18,7 @@ MAN+= \
        pthread_cleanup_pop.3 \
        pthread_cleanup_push.3 \
        pthread_getconcurrency.3 \
+       pthread_getcpuclockid.3 \
        pthread_condattr.3 \
        pthread_cond_broadcast.3 \
        pthread_cond_destroy.3 \
diff --git a/lib/libpthread/pthread_getcpuclockid.3 b/lib/libpthread/pthread_getcpuclockid.3
new file mode 100644 (file)
index 0000000..ff4cb56
--- /dev/null
@@ -0,0 +1,89 @@
+.\" 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 THE AUTHOR 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.
+.\"
+.\" Portions of this text are reprinted and reproduced in electronic form
+.\" from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology --
+.\" Portable Operating System Interface (POSIX), The Open Group Base
+.\" Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of
+.\" Electrical and Electronics Engineers, Inc and The Open Group.  In the
+.\" event of any discrepancy between this version and the original IEEE and
+.\" The Open Group Standard, the original IEEE and The Open Group Standard is
+.\" the referee document.  The original Standard can be obtained online at
+.\"    http://www.opengroup.org/unix/online.html.
+.\"
+.\" $FreeBSD: head/share/man/man3/pthread_getcpuclockid.3 303742 2016-08-04 11:38:53Z pluknet $
+.\"
+.Dd July 26, 2017
+.Dt PTHREAD_GETCPUCLOCKID 3
+.Os
+.Sh NAME
+.Nm pthread_getcpuclockid
+.Nd access a thread CPU-time clock
+.Sh LIBRARY
+.Lb libpthread
+.Sh SYNOPSIS
+.In pthread.h
+.In time.h
+.Ft int
+.Fn pthread_getcpuclockid "pthread_t thread" "clockid_t *clock_id"
+.Sh DESCRIPTION
+The
+.Fn pthread_getcpuclockid
+returns the clock ID of the CPU-time clock of the thread specified by
+.Fa thread ,
+if the thread described by
+.Fa thread
+exists.
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn pthread_getcpuclockid
+returns zero; otherwise, an error number is returned to indicate the
+error.
+.Sh ERRORS
+The
+.Fn pthread_getcpuclockid
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er ESRCH
+The value specified by
+.Fa thread
+does not refer to an existing thread.
+.El
+.Sh SEE ALSO
+.Xr clock_gettime 2 ,
+.Xr clock_getcpuclockid 3
+.Sh STANDARDS
+The
+.Fn pthread_getcpuclockid
+function conforms to
+.St -p1003.1-2004 .
+.Sh HISTORY
+The
+.Fn pthread_getcpuclockid
+function first appeared in
+.Fx 10.0
+and was ported to
+.Dx 4.9 .
+.Sh AUTHORS
+.An David Xu Aq Mt davidxu@FreeBSD.org
index e15440e..f1628a5 100644 (file)
@@ -393,6 +393,8 @@ global:
 
 LIBTHREAD_1_2 {
 global:
+       _pthread_getcpuclockid;
        _pthread_getthreadid_np;
+       pthread_getcpuclockid;
        pthread_getthreadid_np;
 };
index af110a1..2bf5b70 100644 (file)
@@ -19,6 +19,7 @@ SRCS+= \
        thr_event.c \
        thr_exit.c \
        thr_fork.c \
+       thr_getcpuclockid.c \
        thr_getprio.c \
        thr_getschedparam.c \
        thr_getthreadid_np.c \
diff --git a/lib/libthread_xu/thread/thr_getcpuclockid.c b/lib/libthread_xu/thread/thr_getcpuclockid.c
new file mode 100644 (file)
index 0000000..36d451a
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2008 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 JOHN BIRRELL 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.
+ *
+ * $FreeBSD: head/lib/libthr/thread/thr_getcpuclockid.c 297706 2016-04-08 11:15:26Z kib $
+ */
+
+#include "namespace.h"
+#include <errno.h>
+#include <pthread.h>
+#include <sys/time.h>
+#include "un-namespace.h"
+
+#include "thr_private.h"
+
+int
+_pthread_getcpuclockid(pthread_t pthread, clockid_t *clock_id)
+{
+       if (pthread == NULL)
+               return (EINVAL);
+
+       if (getcpuclockid(getpid(), pthread->tid, clock_id))
+               return (errno);
+       return (0);
+}
+
+__strong_reference(_pthread_getcpuclockid, pthread_getcpuclockid);
index d14c621..c39919d 100644 (file)
@@ -107,6 +107,8 @@ STATIC_LIB_REQUIRE(_pthread_atfork);
 STATIC_LIB_REQUIRE(_fork);
 /* thr_affinity.c */
 STATIC_LIB_REQUIRE(_pthread_getaffinity_np);
+/* thr_getcpuclockid.c */
+STATIC_LIB_REQUIRE(_pthread_getcpuclockid);
 /* thr_getprio.c */
 STATIC_LIB_REQUIRE(_pthread_getprio);
 /* thr_getschedparam.c */
index 90d3de7..2e77761 100644 (file)
@@ -563,4 +563,5 @@ struct sysent sysent[] = {
        { AS(lwp_setaffinity_args), (sy_call_t *)sys_lwp_setaffinity }, /* 544 = lwp_setaffinity */
        { AS(lwp_getaffinity_args), (sy_call_t *)sys_lwp_getaffinity }, /* 545 = lwp_getaffinity */
        { AS(lwp_create2_args), (sy_call_t *)sys_lwp_create2 }, /* 546 = lwp_create2 */
+       { AS(getcpuclockid_args), (sy_call_t *)sys_getcpuclockid },     /* 547 = getcpuclockid */
 };
index 02b7810..887d41b 100644 (file)
 
 extern struct spinlock ntp_spin;
 
+#define CPUCLOCK_BIT                   0x80000000
+#define        CPUCLOCK_ID_MASK                ~CPUCLOCK_BIT
+#define        CPUCLOCK2LWPID(clock_id)        (((clockid_t)(clock_id) >> 32) & CPUCLOCK_ID_MASK)
+#define        CPUCLOCK2PID(clock_id)          ((clock_id) & CPUCLOCK_ID_MASK)
+#define MAKE_CPUCLOCK(pid, lwp_id)     ((clockid_t)(lwp_id) << 32 | (pid) | CPUCLOCK_BIT)
+
 struct timezone tz;
 
 /*
@@ -196,6 +202,8 @@ int
 kern_clock_gettime(clockid_t clock_id, struct timespec *ats)
 {
        struct proc *p;
+       struct lwp *lp;
+       lwpid_t lwp_id;
 
        p = curproc;
        switch(clock_id) {
@@ -231,7 +239,25 @@ kern_clock_gettime(clockid_t clock_id, struct timespec *ats)
                get_thread_cputime(curthread, ats);
                break;
        default:
-               return (EINVAL);
+               if ((clock_id & CPUCLOCK_BIT) == 0)
+                       return (EINVAL);
+               if ((p = pfind(CPUCLOCK2PID(clock_id))) == NULL)
+                       return (EINVAL);
+               lwp_id = CPUCLOCK2LWPID(clock_id);
+               if (lwp_id == 0) {
+                       get_process_cputime(p, ats);
+               } else {
+                       lwkt_gettoken(&p->p_token);
+                       lp = lwp_rb_tree_RB_LOOKUP(&p->p_lwp_tree, lwp_id);
+                       if (lp == NULL) {
+                               lwkt_reltoken(&p->p_token);
+                               PRELE(p);
+                               return (EINVAL);
+                       }
+                       get_thread_cputime(lp->lwp_thread, ats);
+                       lwkt_reltoken(&p->p_token);
+               }
+               PRELE(p);
        }
        return (0);
 }
@@ -330,7 +356,10 @@ kern_clock_getres(clockid_t clock_id, struct timespec *ts)
                ts->tv_nsec = 1000;
                break;
        default:
-               return (EINVAL);
+               if ((clock_id & CPUCLOCK_BIT) != 0)
+                       ts->tv_nsec = 1000;
+               else
+                       return (EINVAL);
        }
 
        return (0);
@@ -352,6 +381,53 @@ sys_clock_getres(struct clock_getres_args *uap)
        return (error);
 }
 
+static int
+kern_getcpuclockid(pid_t pid, lwpid_t lwp_id, clockid_t *clock_id)
+{
+       struct proc *p;
+       int error = 0;
+
+       if (pid == 0) {
+               p = curproc;
+               pid = p->p_pid;
+               PHOLD(p);
+       } else {
+               p = pfind(pid);
+               if (p == NULL)
+                       return (ESRCH);
+       }
+       /* lwp_id can be 0 when called by clock_getcpuclockid() */
+       if (lwp_id < 0) {
+               error = EINVAL;
+               goto out;
+       }
+       lwkt_gettoken(&p->p_token);
+       if (lwp_id > 0 &&
+           lwp_rb_tree_RB_LOOKUP(&p->p_lwp_tree, lwp_id) == NULL) {
+               lwkt_reltoken(&p->p_token);
+               error = ESRCH;
+               goto out;
+       }
+       *clock_id = MAKE_CPUCLOCK(pid, lwp_id);
+       lwkt_reltoken(&p->p_token);
+out:
+       PRELE(p);
+       return (error);
+}
+
+int
+sys_getcpuclockid(struct getcpuclockid_args *uap)
+{
+       clockid_t clk_id;
+       int error;
+
+       error = kern_getcpuclockid(uap->pid, uap->lwp_id, &clk_id);
+       if (error == 0)
+               error = copyout(&clk_id, uap->clock_id, sizeof(clockid_t));
+
+       return (error);
+}
+
 /*
  * nanosleep1()
  *
index 2f47e38..df9e415 100644 (file)
@@ -553,4 +553,5 @@ const char *syscallnames[] = {
        "lwp_setaffinity",                      /* 544 = lwp_setaffinity */
        "lwp_getaffinity",                      /* 545 = lwp_getaffinity */
        "lwp_create2",                  /* 546 = lwp_create2 */
+       "getcpuclockid",                        /* 547 = getcpuclockid */
 };
index 01bf54d..21351da 100644 (file)
 544    STD     { int lwp_setaffinity(pid_t pid, lwpid_t tid, const cpumask_t *mask); }
 545    STD     { int lwp_getaffinity(pid_t pid, lwpid_t tid, cpumask_t *mask); }
 546    STD     { int lwp_create2(struct lwp_params *params, const cpumask_t *mask); }
+547    STD     { int getcpuclockid(pid_t pid, lwpid_t lwp_id, clockid_t *clock_id); }
index 4971dbb..653d149 100644 (file)
  * 400905 - PTHREAD_STACK_MIN increase: 1024 => 16384
  * 400906 - lwpid_t >=1, instead of >=0
  * 400907 - pthread_getthreadid_np()
+ * 400908 - {clock,pthread}_getcpuclockid()
  */
 #undef __DragonFly_version
-#define __DragonFly_version 400907     /* propagated to newvers */
+#define __DragonFly_version 400908     /* propagated to newvers */
 
 #include <sys/_null.h>
 
index 2094c4a..11b23e4 100644 (file)
 #define        SYS_lwp_setaffinity     544
 #define        SYS_lwp_getaffinity     545
 #define        SYS_lwp_create2 546
-#define        SYS_MAXSYSCALL  547
+#define        SYS_getcpuclockid       547
+#define        SYS_MAXSYSCALL  548
index 635a7e2..bf13b67 100644 (file)
@@ -310,4 +310,5 @@ MIASM =  \
        ppoll.o \
        lwp_setaffinity.o \
        lwp_getaffinity.o \
-       lwp_create2.o
+       lwp_create2.o \
+       getcpuclockid.o
index 5e47f00..73f9541 100644 (file)
@@ -2348,6 +2348,14 @@ struct   lwp_create2_args {
        struct lwp_params *     params; char params_[PAD_(struct lwp_params *)];
        const cpumask_t *       mask;   char mask_[PAD_(const cpumask_t *)];
 };
+struct getcpuclockid_args {
+#ifdef _KERNEL
+       struct sysmsg sysmsg;
+#endif
+       pid_t   pid;    char pid_[PAD_(pid_t)];
+       lwpid_t lwp_id; char lwp_id_[PAD_(lwpid_t)];
+       clockid_t *     clock_id;       char clock_id_[PAD_(clockid_t *)];
+};
 struct olseek_args {
 #ifdef _KERNEL
        struct sysmsg sysmsg;
@@ -2844,6 +2852,7 @@ int       sys_ppoll (struct ppoll_args *);
 int    sys_lwp_setaffinity (struct lwp_setaffinity_args *);
 int    sys_lwp_getaffinity (struct lwp_getaffinity_args *);
 int    sys_lwp_create2 (struct lwp_create2_args *);
+int    sys_getcpuclockid (struct getcpuclockid_args *);
 
 #endif /* !_SYS_SYSPROTO_H_ */
 #undef PAD_
index fde0762..bfb4ebb 100644 (file)
@@ -319,4 +319,5 @@ union sysunion {
        struct  lwp_setaffinity_args lwp_setaffinity;
        struct  lwp_getaffinity_args lwp_getaffinity;
        struct  lwp_create2_args lwp_create2;
+       struct  getcpuclockid_args getcpuclockid;
 };
index 7a02556..d62fbe5 100644 (file)
@@ -55,7 +55,7 @@
 #define        _POSIX_BARRIERS                 200112L /* mandatory */
 #define        _POSIX_CHOWN_RESTRICTED         1
 #define        _POSIX_CLOCK_SELECTION          -1      /* XXX mandatory */
-#define        _POSIX_CPUTIME                  -1      /* [CPT] */
+#define        _POSIX_CPUTIME                  200112L /* [CPT] */
 #define        _POSIX_FSYNC                    200112L /* [FSC] */
 #define        _POSIX_IPV6                     0
 #define        _POSIX_JOB_CONTROL              1       /* mandatory */
@@ -75,6 +75,7 @@
 #define        _POSIX_SPIN_LOCKS               200112L /* mandatory */
 #define        _POSIX_SPORADIC_SERVER          -1      /* [SS] */
 #define        _POSIX_SYNCHRONIZED_IO          -1      /* [SIO] */
+#define        _POSIX_THREAD_CPUTIME           200112L /* [TCT] */
 #define        _POSIX_TIMEOUTS                 200112L /* mandatory */
 #define        _POSIX_TIMERS                   200112L /* mandatory */
 #define        _POSIX_TYPED_MEMORY_OBJECTS     -1      /* [TYM] */