]> sourceware.org Git - newlib-cygwin.git/commitdiff
* cygwin.din (clock_getcpuclockid): Export.
authorYaakov Selkowitz <yselkowi@redhat.com>
Tue, 17 May 2011 17:08:10 +0000 (17:08 +0000)
committerYaakov Selkowitz <yselkowi@redhat.com>
Tue, 17 May 2011 17:08:10 +0000 (17:08 +0000)
(pthread_getcpuclockid): Export.
* hires.h (PID_TO_CLOCKID): New macro.
(CLOCKID_TO_PID): New macro.
(CLOCKID_IS_PROCESS): New macro.
(THREADID_TO_CLOCKID): New macro.
(CLOCKID_TO_THREADID): New macro.
(CLOCKID_IS_THREAD): New macro.
* ntdll.h (enum _THREAD_INFORMATION_CLASS): Add ThreadTimes.
* posix.sgml (std-notimpl): Add clock_getcpuclockid and
pthread_getcpuclockid from here...
(std-susv4): ... to here.
(std-notes): Remove limitations of clock_getres and clock_gettime.
Note limitation of timer_create to CLOCK_REALTIME.
* sysconf.cc (sca): Set _SC_CPUTIME to _POSIX_CPUTIME, and
_SC_THREAD_CPUTIME to _POSIX_THREAD_CPUTIME.
* thread.cc (pthread_getcpuclockid): New function.
* timer.cc (timer_create): Set errno to ENOTSUP for CPU-time clocks.
* times.cc (clock_gettime): Handle CLOCK_PROCESS_CPUTIME_ID and
CLOCK_THREAD_CPUTIME_ID.
(clock_getres): Ditto.
(clock_settime): Set errno to EPERM for CPU-time clocks.
(clock_getcpuclockid): New function.
* include/pthread.h (pthread_getcpuclockid): Declare.
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.

winsup/cygwin/ChangeLog
winsup/cygwin/cygwin.din
winsup/cygwin/hires.h
winsup/cygwin/include/cygwin/version.h
winsup/cygwin/include/pthread.h
winsup/cygwin/ntdll.h
winsup/cygwin/posix.sgml
winsup/cygwin/sysconf.cc
winsup/cygwin/thread.cc
winsup/cygwin/timer.cc
winsup/cygwin/times.cc

index 7f5cae4cb427e5ae9a46e5ca01cc30c058694140..61060a8cc4cbc6a89f6e698c07298a91debf64aa 100644 (file)
@@ -1,3 +1,31 @@
+2011-05-17  Yaakov Selkowitz  <yselkowitz@users.sourceforge.net>
+
+       * cygwin.din (clock_getcpuclockid): Export.
+       (pthread_getcpuclockid): Export.
+       * hires.h (PID_TO_CLOCKID): New macro.
+       (CLOCKID_TO_PID): New macro.
+       (CLOCKID_IS_PROCESS): New macro.
+       (THREADID_TO_CLOCKID): New macro.
+       (CLOCKID_TO_THREADID): New macro.
+       (CLOCKID_IS_THREAD): New macro.
+       * ntdll.h (enum _THREAD_INFORMATION_CLASS): Add ThreadTimes.
+       * posix.sgml (std-notimpl): Add clock_getcpuclockid and
+       pthread_getcpuclockid from here...
+       (std-susv4): ... to here.
+       (std-notes): Remove limitations of clock_getres and clock_gettime.
+       Note limitation of timer_create to CLOCK_REALTIME.
+       * sysconf.cc (sca): Set _SC_CPUTIME to _POSIX_CPUTIME, and
+       _SC_THREAD_CPUTIME to _POSIX_THREAD_CPUTIME.
+       * thread.cc (pthread_getcpuclockid): New function.
+       * timer.cc (timer_create): Set errno to ENOTSUP for CPU-time clocks.
+       * times.cc (clock_gettime): Handle CLOCK_PROCESS_CPUTIME_ID and
+       CLOCK_THREAD_CPUTIME_ID.
+       (clock_getres): Ditto.
+       (clock_settime): Set errno to EPERM for CPU-time clocks.
+       (clock_getcpuclockid): New function.
+       * include/pthread.h (pthread_getcpuclockid): Declare.
+       * include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
+
 2011-05-17  Corinna Vinschen  <corinna@vinschen.de>
 
        * miscfuncs.cc (thread_wrapper): Remove unused _cygtls record.
index 12c3f3d5760acc52a5f16250c752e1a649e86db1..8d1e7032ed73dd866e31d6a91f69bb510870effa 100644 (file)
@@ -217,6 +217,7 @@ clearerr SIGFE
 _clearerr = clearerr SIGFE
 clock SIGFE
 _clock = clock SIGFE
+clock_getcpuclockid SIGFE
 clock_getres SIGFE
 clock_gettime SIGFE
 clock_setres SIGFE
@@ -1212,6 +1213,7 @@ pthread_equal SIGFE
 pthread_exit SIGFE
 pthread_getattr_np SIGFE
 pthread_getconcurrency SIGFE
+pthread_getcpuclockid SIGFE
 pthread_getschedparam SIGFE
 pthread_getsequence_np SIGFE
 pthread_getspecific SIGFE
index 0acfafdbde1ab8c927a1edeca9bb1993597790a8..15c8d209db35fa14abdad1eaf9deff436a5b9394 100644 (file)
@@ -13,6 +13,14 @@ details. */
 
 #include <mmsystem.h>
 
+/* Conversions for per-process and per-thread clocks */
+#define PID_TO_CLOCKID(pid) (pid * 8 + CLOCK_PROCESS_CPUTIME_ID)
+#define CLOCKID_TO_PID(cid) ((cid - CLOCK_PROCESS_CPUTIME_ID) / 8)
+#define CLOCKID_IS_PROCESS(cid) ((cid % 8) == CLOCK_PROCESS_CPUTIME_ID)
+#define THREADID_TO_CLOCKID(tid) (tid * 8 + CLOCK_THREAD_CPUTIME_ID)
+#define CLOCKID_TO_THREADID(cid) ((cid - CLOCK_THREAD_CPUTIME_ID) / 8)
+#define CLOCKID_IS_THREAD(cid) ((cid % 8) == CLOCK_THREAD_CPUTIME_ID)
+
 /* Largest delay in ms for sleep and alarm calls.
    Allow actual delay to exceed requested delay by 10 s.
    Express as multiple of 1000 (i.e. seconds) + max resolution
index ea66d409782cdf439b4bc3e181b7d399b5fc90ac..fed1c0cccf94f11f161e9dd8aefa90a8a633a6d8 100644 (file)
@@ -412,12 +412,14 @@ details. */
       244: Export clock_settime.
       245: Export pthread_attr_getguardsize, pthread_attr_setguardsize,
           pthread_attr_setstack, pthread_attr_setstackaddr.
+      246: Add CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID.
+          Export clock_getcpuclockid, pthread_getcpuclockid.
      */
 
      /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
 
 #define CYGWIN_VERSION_API_MAJOR 0
-#define CYGWIN_VERSION_API_MINOR 245
+#define CYGWIN_VERSION_API_MINOR 246
 
      /* There is also a compatibity version number associated with the
        shared memory regions.  It is incremented when incompatible
index e963eba5494a258913f8aa2e26f1d02a59a10b05..4ed53ab08e97ca586b06537b8dab77614213f4a5 100644 (file)
@@ -141,6 +141,7 @@ int pthread_create (pthread_t *, const pthread_attr_t *,
 int pthread_detach (pthread_t);
 int pthread_equal (pthread_t, pthread_t);
 void pthread_exit (void *);
+int pthread_getcpuclockid (pthread_t, clockid_t *);
 int pthread_getschedparam (pthread_t, int *, struct sched_param *);
 void *pthread_getspecific (pthread_key_t);
 int pthread_join (pthread_t, void **);
index 9c5597ec1949d892699a3b703f4a5273e1e113b4..77aeeece09a39ec357c4f02bd1e2334151a1a7ae 100644 (file)
@@ -938,6 +938,7 @@ typedef enum _EVENT_INFORMATION_CLASS
 typedef enum _THREAD_INFORMATION_CLASS
 {
   ThreadBasicInformation = 0,
+  ThreadTimes = 1,
   ThreadImpersonationToken = 5
 } THREAD_INFORMATION_CLASS, *PTHREAD_INFORMATION_CLASS;
 
index a576b353f1126a48dc42c9010ff9ec0528adc59a..f6ec0b0e2ed81ff38f00bad0de90417849a6bd40 100644 (file)
@@ -90,8 +90,9 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
     cimagf
     clearerr
     clock
-    clock_getres               (see chapter "Implementation Notes")
-    clock_gettime              (see chapter "Implementation Notes")
+    clock_getcpuclockid
+    clock_getres
+    clock_gettime
     clock_settime              (see chapter "Implementation Notes")
     clog
     clogf
@@ -564,6 +565,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
     pthread_equal
     pthread_exit
     pthread_getconcurrency
+    pthread_getcpuclockid
     pthread_getschedparam
     pthread_getspecific
     pthread_join
@@ -836,7 +838,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
     tgamma
     tgammaf
     time
-    timer_create
+    timer_create               (see chapter "Implementation Notes")
     timer_delete
     timer_gettime
     timer_settime
@@ -1292,7 +1294,6 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
     ceill
     cexpl
     cimagl
-    clock_getcpuclockid
     clogl
     conjl
     copysignl
@@ -1386,7 +1387,6 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
     pthread_barrier[...]
     pthread_condattr_getclock
     pthread_condattr_setclock
-    pthread_getcpuclockid
     pthread_mutexattr_getrobust
     pthread_mutexattr_setrobust
     pthread_mutex_consistent
@@ -1441,9 +1441,8 @@ by keeping track of the current root and accomodating this in the file
 related function calls.  A real chroot functionality is not supported by
 Windows however.</para>
 
-<para><function>clock_getres</function> and <function>clock_gettime</function>
-only support CLOCK_REALTIME and CLOCK_MONOTONIC for now.  <function>clock_setres</function>
-and <function>clock_settime</function> only support CLOCK_REALTIME.</para>
+<function>clock_setres</function>, <function>clock_settime</function>, and
+<function>timer_create</function> only support CLOCK_REALTIME.</para>
 
 <para>BSD file locks created via <function>flock</function> are not
 propagated to the parent process and sibling processes.  The locks are
index 73c44fe362f690657b476fd27476d19823d31e63..0dbb1761042d8b58519bf7d6aa56fd04936cf205 100644 (file)
@@ -160,7 +160,7 @@ static struct
   {cons, {c:BC_STRING_MAX}},           /*  60, _SC_BC_STRING_MAX */
   {cons, {c:-1L}},                     /*  61, _SC_CLOCK_SELECTION */
   {nsup, {c:0}},                       /*  62, _SC_COLL_WEIGHTS_MAX */
-  {cons, {c:-1L}},                     /*  63, _SC_CPUTIME */
+  {cons, {c:_POSIX_CPUTIME}},          /*  63, _SC_CPUTIME */
   {cons, {c:EXPR_NEST_MAX}},           /*  64, _SC_EXPR_NEST_MAX */
   {cons, {c:HOST_NAME_MAX}},           /*  65, _SC_HOST_NAME_MAX */
   {cons, {c:IOV_MAX}},                 /*  66, _SC_IOV_MAX */
@@ -177,7 +177,7 @@ static struct
   {cons, {c:-1L}},                     /*  77, _SC_SPORADIC_SERVER */
   {nsup, {c:0}},                       /*  78, _SC_SS_REPL_MAX */
   {cons, {c:SYMLOOP_MAX}},             /*  79, _SC_SYMLOOP_MAX */
-  {cons, {c:-1L}},                     /*  80, _SC_THREAD_CPUTIME */
+  {cons, {c:_POSIX_THREAD_CPUTIME}},   /*  80, _SC_THREAD_CPUTIME */
   {cons, {c:-1L}},                     /*  81, _SC_THREAD_SPORADIC_SERVER */
   {cons, {c:-1L}},                     /*  82, _SC_TIMEOUTS */
   {cons, {c:-1L}},                     /*  83, _SC_TRACE */
index b53fc7f701d532367ac9ffcad11e882c4554d7e8..c70709bff8a5788ceece1a5dbd2f722730bdc092 100644 (file)
@@ -2510,6 +2510,15 @@ pthread_getconcurrency ()
   return MT_INTERFACE->concurrency;
 }
 
+extern "C" int
+pthread_getcpuclockid (pthread_t thread, clockid_t *clk_id)
+{
+  if (!pthread::is_good_object (&thread))
+    return (ESRCH);
+  *clk_id = (clockid_t) THREADID_TO_CLOCKID (thread->getsequence_np ());
+  return 0;
+}
+
 /* keep this in sync with sched.cc */
 extern "C" int
 pthread_getschedparam (pthread_t thread, int *policy,
index 91e71146c179a7be01e4185b5b27fd7d55232112..be740e07ad8be17ff0ca67b83411c1b723de7563 100644 (file)
@@ -300,6 +300,13 @@ timer_create (clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
   myfault efault;
   if (efault.faulted (EFAULT))
     return -1;
+
+  if (CLOCKID_IS_PROCESS (clock_id) || CLOCKID_IS_THREAD (clock_id))
+    {
+      set_errno (ENOTSUP);
+      return -1;
+    }
+
   if (clock_id != CLOCK_REALTIME)
     {
       set_errno (EINVAL);
index 4e6697e76c3df8341911bae5e4795a950da089a2..6bb68ecd16a337a7671c896963eb7d2e8e953e49 100644 (file)
@@ -15,6 +15,7 @@ details. */
 #include <sys/timeb.h>
 #include <utime.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include "cygerrno.h"
 #include "security.h"
 #include "path.h"
@@ -22,6 +23,7 @@ details. */
 #include "dtable.h"
 #include "cygheap.h"
 #include "pinfo.h"
+#include "thread.h"
 #include "cygtls.h"
 #include "ntdll.h"
 
@@ -594,6 +596,63 @@ hires_ms::nsecs ()
 extern "C" int
 clock_gettime (clockid_t clk_id, struct timespec *tp)
 {
+  if (CLOCKID_IS_PROCESS (clk_id))
+    {
+      pid_t pid = CLOCKID_TO_PID (clk_id);
+      HANDLE hProcess;
+      KERNEL_USER_TIMES kut;
+      ULONG sizeof_kut = sizeof (KERNEL_USER_TIMES);
+      long long x;
+
+      if (pid == 0)
+        pid = getpid ();
+
+      pinfo p (pid);
+      if (!p->exists ())
+        {
+          set_errno (EINVAL);
+          return -1;
+        }
+
+      hProcess = OpenProcess (PROCESS_QUERY_INFORMATION, 0, p->dwProcessId);
+      NtQueryInformationProcess (hProcess, ProcessTimes, &kut, sizeof_kut, &sizeof_kut);
+
+      x = kut.KernelTime.QuadPart + kut.UserTime.QuadPart;
+      tp->tv_sec = x / (long long) NSPERSEC;
+      tp->tv_nsec = (x % (long long) NSPERSEC) * 100LL;
+
+      CloseHandle (hProcess);
+      return 0;
+    }
+
+  if (CLOCKID_IS_THREAD (clk_id))
+    {
+      long thr_id = CLOCKID_TO_THREADID (clk_id);
+      HANDLE hThread;
+      KERNEL_USER_TIMES kut;
+      ULONG sizeof_kut = sizeof (KERNEL_USER_TIMES);
+      long long x;
+
+      if (thr_id == 0)
+        thr_id = pthread::self ()->getsequence_np ();
+
+      hThread = OpenThread (THREAD_QUERY_INFORMATION, 0, thr_id);
+      if (!hThread)
+        {
+          set_errno (EINVAL);
+          return -1;
+        }
+
+      NtQueryInformationThread (hThread, ThreadTimes, &kut, sizeof_kut, &sizeof_kut);
+
+      x = kut.KernelTime.QuadPart + kut.UserTime.QuadPart;
+      tp->tv_sec = x / (long long) NSPERSEC;
+      tp->tv_nsec = (x % (long long) NSPERSEC) * 100LL;
+
+      CloseHandle (hThread);
+      return 0;
+    }
+
   switch (clk_id)
     {
       case CLOCK_REALTIME:
@@ -630,6 +689,16 @@ clock_settime (clockid_t clk_id, const struct timespec *tp)
 {
   struct timeval tv;
 
+  if (CLOCKID_IS_PROCESS (clk_id) || CLOCKID_IS_THREAD (clk_id))
+    /* According to POSIX, the privileges to set a particular clock
+     * are implementation-defined.  On Linux, CPU-time clocks are not
+     * settable; do the same here.
+     */
+    {
+      set_errno (EPERM);
+      return -1;
+    }
+
   if (clk_id != CLOCK_REALTIME)
     {
       set_errno (EINVAL);
@@ -702,6 +771,16 @@ hires_ms::resolution ()
 extern "C" int
 clock_getres (clockid_t clk_id, struct timespec *tp)
 {
+  if (CLOCKID_IS_PROCESS (clk_id) || CLOCKID_IS_THREAD (clk_id))
+    {
+      ULONG coarsest, finest, actual;
+
+      NtQueryTimerResolution (&coarsest, &finest, &actual);
+      tp->tv_sec = coarsest / NSPERSEC;
+      tp->tv_nsec = (coarsest % NSPERSEC) * 100;
+      return 0;
+    }
+
   switch (clk_id)
     {
       case CLOCK_REALTIME:
@@ -776,3 +855,12 @@ clock_setres (clockid_t clk_id, struct timespec *tp)
   period_set = true;
   return 0;
 }
+
+extern "C" int
+clock_getcpuclockid (pid_t pid, clockid_t *clk_id)
+{
+  if (pid != 0 && !pinfo (pid)->exists ())
+    return (ESRCH);
+  *clk_id = (clockid_t) PID_TO_CLOCKID (pid);
+  return 0;
+}
This page took 0.049633 seconds and 5 git commands to generate.