This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc 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]

Re: [time] add support for CLOCK_THREAD_CPUTIME_ID andCLOCK_PROCESS_CPUTIME_ID


On Fri, 24 Sep 2004, Ulrich Drepper wrote:

> Sorry, I fail to see the point.  The CPUTIME stuff will either way be
> entire implemented at userlevel.  If we use TSC, we compute the
> resolution from the CPU clock speed (no need to comment, I know it's not
> reliable everywhere).  If we fall back on realtime, we will simply in
> glibc map
>
>    clock_getres (CLOCK_PROCESS_CPUTIME_ID, &ts)
>
> to
>
>    clock_getres (CLOCK_REALTIME, &ts)
>
> The kernel knows nothing about this clock.

Ok here is the patch that makes CLOCK_PROCESS_CPUTIME_ID etc fall back to
CLOCK_REALTIME. This IMHO still not a good solution:

1. It directly returns CLOCK_REALTIME. It should deduct time value at
startup. This could be done with some work. The kernel solution would need
no modification for since it always knows the start time of a process
and glibc could drop figuring out a timestamp or time at startup.

2. It only falls back if there is an indication that the cpu counters
are not synchronized. There is no testing of any counter offsets in glibc.
Again the kernel is aware of these offsets, glibc naively assumes that the
counters are in sync and has no means of obtained the information at all.

3. If the cpu counter is used then no time corrections are applied. If
CLOCK_PROCESS_CPUTIME_ID is to return a real time value (in violation
of POSIX AFAIK) then maybe it should return correct time?

4. SMP systems may have processors with different speeds. The cpu timer
(TSC or ITC) may suddenly encounter a cpu timer running at different
speeds if a process is moved to a different cpu. Glibc cannot handle that
situation.

5. Systems may reduce the clock speed and therefore vary the speed of the
CPU counter. Glibc has no awareness of this.

Glibc should not use cpu timers in any way to return time information to
the currently running process. Glibc is not the operating system and does
not have the proper information available to provide time information.
IMHO both clocks CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID must
be handled by the kernel.

Applying the following patch to glibc would at least alleviate the worst
problem of clock_gettime(CLOCK_PROCESS_CPUTIME_ID) returning bogus values
on systems with unsynchronized cpu timers by falling back to
CLOCK_REALTIME.

Index: libc/sysdeps/unix/sysv/linux/ia64/clock_getcpuclockid.c
===================================================================
--- libc.orig/sysdeps/unix/sysv/linux/ia64/clock_getcpuclockid.c	2003-12-11 12:46:01.000000000 -0800
+++ libc/sysdeps/unix/sysv/linux/ia64/clock_getcpuclockid.c	2004-06-15 12:12:34.000000000 -0700
@@ -31,10 +31,10 @@
   if (pid != 0 && pid != getpid ())
     return EPERM;

-  static int itc_usable;
+  extern int hp_reliable;
   int retval = ENOENT;

-  if (__builtin_expect (itc_usable == 0, 0))
+  if (__builtin_expect (hp_reliable == 0, 0))
     {
       int newval = 1;
       int fd = open ("/proc/sal/itc_drift", O_RDONLY);
@@ -51,10 +51,10 @@
 	  close (fd);
 	}

-      itc_usable = newval;
+      hp_reliable = newval;
     }

-  if (itc_usable > 0)
+  if (hp_reliable > 0)
     {
       /* Store the number.  */
       *clock_id = CLOCK_PROCESS_CPUTIME_ID;
Index: libc/sysdeps/unix/clock_gettime.c
===================================================================
--- libc.orig/sysdeps/unix/clock_gettime.c	2003-06-24 16:58:29.000000000 -0700
+++ libc/sysdeps/unix/clock_gettime.c	2004-06-15 12:11:52.000000000 -0700
@@ -29,7 +29,7 @@
    because some jokers are already playing with processors with more
    than 4GHz.  */
 static hp_timing_t freq;
-
+int hp_reliable;

 /* This function is defined in the thread library.  */
 extern int __pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq,
@@ -78,7 +78,15 @@
 #if HP_TIMING_AVAIL
       /* FALLTHROUGH.  */
     case CLOCK_PROCESS_CPUTIME_ID:
-      {
+      /* If HP timing reliability has not been determined yet then do so now */
+      if (hp_reliable==0)
+	{
+		if (clock_getcpuclockid()==ENOENT)
+		       	hp_reliable=-1;
+		else
+			hp_reliable=1;
+	}
+      if (hp_reliable>0) {
 	hp_timing_t tsc;

 	if (__builtin_expect (freq == 0, 0))
@@ -115,6 +123,9 @@

 	retval = 0;
       }
+    else
+	_set_errno(ENOENT);
+
     break;
 #endif
     }


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