This is the mail archive of the cygwin-patches mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] CPU-time clocks


The attached patches implement POSIX CPU-time clock support:

http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getcpuclockid.html
http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_getcpuclockid.html
http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_gettime.html
http://www.kernel.org/doc/man-pages/online/pages/man3/clock_getcpuclockid.3.html
http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_getcpuclockid.3.html
http://www.kernel.org/doc/man-pages/online/pages/man3/clock_gettime.3.html

There are several things I need to note:

1) Unfortunately newlib's variable naming doesn't currently comply with
POSIX.  Fixing this will affect RTEMS, so this will need to be worked
out on the newlib list.

2) On Linux, clockid_t is a signed int, and glibc uses negative clock
IDs for processes and threads (e.g. clock_getcpuclockid returns -6 -
pid*8 for the given pid).  However, newlib's clockid_t is a unsigned
long, so I've chosen a slightly-different numbering scheme which makes
the code a bit cleaner.  While the scheme is arbitrary and could be
changed at any time, that should only be necessary if several more fixed
clock IDs are required in the future (a (clockid_t)10 would be mistaken
for a CPU-time clock for PID 1); right now POSIX defines only four fixed
clock IDs.

3) timer_create(2) needs to be reworked to support clocks other than
CLOCK_REALTIME.  For now, I'm falling back to the ENOTSUP case allowed
by POSIX, but this should be reexamined after reworking timer_create.

4) As noted in the comments, POSIX says that the permissions required to
set any particular clock are implementation-defined.  On Linux, CPU-time
clocks are not settable (IOW no process has such permissions); I have
done the same here.

5) The clock_getres(3) code is based on my findings on my system (156001
100ns on W7 x64); I'd appreciate some confirmation for other systems.

6) On Linux, clock_getres(3) does not appear to verify if a (potential)
CPU-time clock actually exists.

Patches for newlib, winsup/cygwin, and winsup/doc, along with test
programs for the new and affected functions, attached.


Yaakov

2011-05-12  Yaakov Selkowitz  <yselkowitz@...>

	* libc/include/time.h (CLOCK_PROCESS_CPUTIME_ID): Rename from
	CLOCK_PROCESS_CPUTIME.
	(CLOCK_THREAD_CPUTIME_ID): Rename from CLOCK_THREAD_CPUTIME.
	* libc/include/sys/features.h [__CYGWIN__] (_POSIX_CPUTIME): Define.
	(_POSIX_THREAD_CPUTIME): Define.

Index: libc/include/time.h
===================================================================
RCS file: /cvs/src/src/newlib/libc/include/time.h,v
retrieving revision 1.19
diff -u -r1.19 time.h
--- libc/include/time.h	16 Oct 2008 21:53:58 -0000	1.19
+++ libc/include/time.h	8 May 2011 23:56:27 -0000
@@ -212,7 +212,7 @@
    the identifier of the CPU_time clock associated with the PROCESS
    making the function call.  */
 
-#define CLOCK_PROCESS_CPUTIME (clockid_t)2
+#define CLOCK_PROCESS_CPUTIME_ID (clockid_t)2
 
 #endif
 
@@ -222,7 +222,7 @@
     the identifier of the CPU_time clock associated with the THREAD
     making the function call.  */
 
-#define CLOCK_THREAD_CPUTIME (clockid_t)3
+#define CLOCK_THREAD_CPUTIME_ID (clockid_t)3
 
 #endif
 
Index: libc/include/sys/features.h
===================================================================
RCS file: /cvs/src/src/newlib/libc/include/sys/features.h,v
retrieving revision 1.24
diff -u -r1.24 features.h
--- libc/include/sys/features.h	2 May 2011 16:05:06 -0000	1.24
+++ libc/include/sys/features.h	8 May 2011 23:56:27 -0000
@@ -103,7 +103,7 @@
 /* #define _POSIX_BARRIERS			    -1 */
 #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				200112L
 #define _POSIX_JOB_CONTROL			     1
@@ -130,7 +130,7 @@
 #define _POSIX_SYNCHRONIZED_IO			200112L
 /* #define _POSIX_THREAD_ATTR_STACKADDR		    -1 */
 #define _POSIX_THREAD_ATTR_STACKSIZE		200112L
-/* #define _POSIX_THREAD_CPUTIME		    -1 */
+#define _POSIX_THREAD_CPUTIME			200112L
 /* #define _POSIX_THREAD_PRIO_INHERIT		    -1 */
 /* #define _POSIX_THREAD_PRIO_PROTECT		    -1 */
 #define _POSIX_THREAD_PRIORITY_SCHEDULING	200112L
2011-05-15  Yaakov Selkowitz  <yselkowitz@...>

	* cygwin.din (clock_getcpuclockid): Export.
	(pthread_getcpuclockid): Export.
	* 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.
	* winsup.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.
	* include/pthread.h (pthread_getcpuclockid): Declare.
	* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.

Index: cygwin.din
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/cygwin.din,v
retrieving revision 1.240
diff -u -r1.240 cygwin.din
--- cygwin.din	9 May 2011 08:57:46 -0000	1.240
+++ cygwin.din	13 May 2011 04:02:33 -0000
@@ -217,6 +217,7 @@
 _clearerr = clearerr SIGFE
 clock SIGFE
 _clock = clock SIGFE
+clock_getcpuclockid SIGFE
 clock_getres SIGFE
 clock_gettime SIGFE
 clock_setres SIGFE
@@ -1208,6 +1209,7 @@
 pthread_exit SIGFE
 pthread_getattr_np SIGFE
 pthread_getconcurrency SIGFE
+pthread_getcpuclockid SIGFE
 pthread_getschedparam SIGFE
 pthread_getsequence_np SIGFE
 pthread_getspecific SIGFE
Index: posix.sgml
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/posix.sgml,v
retrieving revision 1.62
diff -u -r1.62 posix.sgml
--- posix.sgml	9 May 2011 08:57:46 -0000	1.62
+++ posix.sgml	13 May 2011 04:02:33 -0000
@@ -90,8 +90,9 @@
     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
@@ -561,6 +562,7 @@
     pthread_equal
     pthread_exit
     pthread_getconcurrency
+    pthread_getcpuclockid
     pthread_getschedparam
     pthread_getspecific
     pthread_join
@@ -833,7 +835,7 @@
     tgamma
     tgammaf
     time
-    timer_create
+    timer_create		(see chapter "Implementation Notes")
     timer_delete
     timer_gettime
     timer_settime
@@ -1288,7 +1290,6 @@
     ceill
     cexpl
     cimagl
-    clock_getcpuclockid
     clogl
     conjl
     copysignl
@@ -1385,7 +1386,6 @@
     pthread_barrier[...]
     pthread_condattr_getclock
     pthread_condattr_setclock
-    pthread_getcpuclockid
     pthread_mutexattr_getrobust
     pthread_mutexattr_setrobust
     pthread_mutex_consistent
@@ -1440,9 +1440,8 @@
 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: sysconf.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/sysconf.cc,v
retrieving revision 1.56
diff -u -r1.56 sysconf.cc
--- sysconf.cc	6 May 2011 18:53:21 -0000	1.56
+++ sysconf.cc	13 May 2011 04:02:33 -0000
@@ -160,7 +160,7 @@
   {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 @@
   {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: thread.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/thread.cc,v
retrieving revision 1.238
diff -u -r1.238 thread.cc
--- thread.cc	4 May 2011 06:16:59 -0000	1.238
+++ thread.cc	13 May 2011 04:02:34 -0000
@@ -2461,6 +2461,15 @@
   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: timer.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/timer.cc,v
retrieving revision 1.26
diff -u -r1.26 timer.cc
--- timer.cc	1 Sep 2010 18:24:11 -0000	1.26
+++ timer.cc	15 May 2011 16:35:46 -0000
@@ -300,6 +300,13 @@
   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: times.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/times.cc,v
retrieving revision 1.108
diff -u -r1.108 times.cc
--- times.cc	9 May 2011 08:57:46 -0000	1.108
+++ times.cc	13 May 2011 04:02:34 -0000
@@ -15,6 +15,7 @@
 #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 @@
 #include "dtable.h"
 #include "cygheap.h"
 #include "pinfo.h"
+#include "thread.h"
 #include "cygtls.h"
 #include "ntdll.h"
 
@@ -594,6 +596,62 @@
 extern "C" int
 clock_gettime (clockid_t clk_id, struct timespec *tp)
 {
+  if (CLOCKID_IS_PROCESS (clk_id))
+    {
+      FILETIME creation_time, exit_time, kernel_time, user_time;
+      pid_t pid = CLOCKID_TO_PID (clk_id);
+      HANDLE hProcess;
+      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);
+      GetProcessTimes (hProcess, &creation_time, &exit_time, &kernel_time, &user_time);
+
+      x = ((long long) kernel_time.dwHighDateTime << 32) + ((unsigned) kernel_time.dwLowDateTime)
+          + ((long long) user_time.dwHighDateTime << 32) + ((unsigned) user_time.dwLowDateTime);
+      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))
+    {
+      FILETIME creation_time, exit_time, kernel_time, user_time;
+      long thr_id = CLOCKID_TO_THREADID (clk_id);
+      HANDLE hThread;
+      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;
+        }
+
+      GetThreadTimes (hThread, &creation_time, &exit_time, &kernel_time, &user_time);
+      x = ((long long) kernel_time.dwHighDateTime << 32) + ((unsigned) kernel_time.dwLowDateTime)
+          + ((long long) user_time.dwHighDateTime << 32) + ((unsigned) user_time.dwLowDateTime);
+      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 +688,16 @@
 {
   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 +770,16 @@
 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 +854,12 @@
   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;
+}
Index: winsup.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/winsup.h,v
retrieving revision 1.235
diff -u -r1.235 winsup.h
--- winsup.h	19 Apr 2011 10:02:06 -0000	1.235
+++ winsup.h	13 May 2011 04:02:34 -0000
@@ -220,6 +220,13 @@
 void *hook_or_detect_cygwin (const char *, const void *, WORD&) __attribute__ ((regparm (3)));
 
 /* Time related */
+#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)
+
 void __stdcall totimeval (struct timeval *, FILETIME *, int, int);
 long __stdcall to_time_t (FILETIME *);
 void __stdcall to_timestruc_t (FILETIME *, timestruc_t *);
Index: include/pthread.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/include/pthread.h,v
retrieving revision 1.31
diff -u -r1.31 pthread.h
--- include/pthread.h	3 May 2011 01:13:37 -0000	1.31
+++ include/pthread.h	15 May 2011 09:51:38 -0000
@@ -139,6 +139,7 @@
 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: include/cygwin/version.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/include/cygwin/version.h,v
retrieving revision 1.345
diff -u -r1.345 version.h
--- include/cygwin/version.h	9 May 2011 08:57:46 -0000	1.345
+++ include/cygwin/version.h	13 May 2011 04:02:34 -0000
@@ -410,12 +410,14 @@
       242: Export psiginfo, psignal, sys_siglist.
       243: Export sysinfo.
       244: Export clock_settime.
+      245: 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 244
+#define CYGWIN_VERSION_API_MINOR 245
 
      /* There is also a compatibity version number associated with the
 	shared memory regions.  It is incremented when incompatible
#pragma CCOD:script no
#pragma CCOD:options -lrt

#define _XOPEN_SOURCE 600
#ifdef __CYGWIN__
#define _POSIX_CPUTIME
#endif
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <dlfcn.h>

int
main (int argc, char *argv[])
{
  clockid_t clockid;
  struct timespec tp;
  int i;

#ifdef __CYGWIN__
  int (*clock_getcpuclockid) (pid_t pid, clockid_t *clk_id);
  clock_getcpuclockid = dlsym (dlopen ("cygwin1.dll", 0), "clock_getcpuclockid");
#endif

  for (i = 1; i < argc; i++) {
    if (clock_getcpuclockid (atoi (argv[i]), &clockid) != 0) {
      perror ("clock_getcpuclockid");
      exit (EXIT_FAILURE);
    }

    if (clock_gettime (clockid, &tp) == -1) {
      perror ("clock_gettime");
      exit (EXIT_FAILURE);
    }

    printf ("CPU-time clock for PID %s is %ld.%09ld seconds\n",
            argv[i], (long) tp.tv_sec, (long) tp.tv_nsec);
  }

  if (clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &tp) == -1) {
    perror ("clock_gettime");
    exit (EXIT_FAILURE);
  }

  printf ("CPU-time clock for this process is %ld.%09ld seconds\n",
          (long) tp.tv_sec, (long) tp.tv_nsec);

  return 0;
}
#pragma CCOD:script no
#pragma CCOD:options -lrt

#define _XOPEN_SOURCE 600
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#ifdef __CYGWIN__
#include <dlfcn.h>
#define CLOCK_PROCESS_CPUTIME_ID	(clockid_t)2
int (*clock_getcpuclockid) (pid_t, clockid_t *);
#endif

int
main (int argc, char **argv)
{
  clockid_t clk_id;
  struct timespec tp;
  pid_t pid;

#ifdef __CYGWIN__
  clock_getcpuclockid = dlopen (dlsym ("cygwin1.dll", 0), "clock_getcpuclockid");
#endif

  clock_getres (CLOCK_REALTIME, &tp);
  printf ("Realtime clock resolution is %ld.%09ld seconds\n",
          (long) tp.tv_sec, (long) tp.tv_nsec);

  clock_getres (CLOCK_MONOTONIC, &tp);
  printf ("Monotonic clock resolution is %ld.%09ld seconds\n",
          (long) tp.tv_sec, (long) tp.tv_nsec);

  clock_getres (CLOCK_PROCESS_CPUTIME_ID, &tp);
  printf ("CPU clock resolution for this process is %ld.%09ld seconds\n",
          (long) tp.tv_sec, (long) tp.tv_nsec);

  pid = argv[1] ? atoi (argv[1]) : -1;

  clock_getcpuclockid (pid, &clk_id);
  clock_getres (clk_id, &tp);
  printf ("CPU clock resolution for PID %d is %ld.%09ld seconds\n",
          pid, (long) tp.tv_sec, (long) tp.tv_nsec);

  return 0;
}
2011-05-15  Yaakov Selkowitz  <yselkowitz@...>

	* new-features.sgml (ov-new1.7.10): Document CPU-time clock support.

Index: new-features.sgml
===================================================================
RCS file: /cvs/src/src/winsup/doc/new-features.sgml,v
retrieving revision 1.80
diff -u -r1.80 new-features.sgml
--- new-features.sgml	9 May 2011 08:58:59 -0000	1.80
+++ new-features.sgml	15 May 2011 17:54:55 -0000
@@ -19,6 +19,12 @@
 </para></listitem>
 
 <listitem><para>
+clock_gettime(3) and clock_getres(3) accept per-process and per-thread CPU-time
+clocks, including CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID.
+New APIs: clock_getcpuclockid, pthread_getcpuclockid.
+</para></listitem>
+
+<listitem><para>
 /proc/loadavg now shows the number of currently running processes and the
 total number of processes.
 </para></listitem>

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]