All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [time] add support for CLOCK_THREAD_CPUTIME_ID and CLOCK_PROCESS_CPUTIME_ID
       [not found] <B6E8046E1E28D34EB815A11AC8CA312902CD3264@mtv-atc-605e--n.corp.sgi.com>
@ 2004-09-24 12:16 ` Christoph Lameter
  2004-09-25  4:25   ` Ulrich Drepper
  0 siblings, 1 reply; 57+ messages in thread
From: Christoph Lameter @ 2004-09-24 12:16 UTC (permalink / raw)
  To: linux-kernel

Hmm .... some further refinement to properly handle the process clock. The
new thread groups make that possible ...

Index: linus/kernel/posix-timers.c
===================================================================
--- linus.orig/kernel/posix-timers.c	2004-09-23 15:12:01.000000000 -0700
+++ linus/kernel/posix-timers.c	2004-09-24 05:07:42.000000000 -0700
@@ -133,18 +133,10 @@
  *	    resolution.	 Here we define the standard CLOCK_REALTIME as a
  *	    1/HZ resolution clock.
  *
- * CPUTIME & THREAD_CPUTIME: We are not, at this time, definding these
- *	    two clocks (and the other process related clocks (Std
- *	    1003.1d-1999).  The way these should be supported, we think,
- *	    is to use large negative numbers for the two clocks that are
- *	    pinned to the executing process and to use -pid for clocks
- *	    pinned to particular pids.	Calls which supported these clock
- *	    ids would split early in the function.
- *
  * RESOLUTION: Clock resolution is used to round up timer and interval
  *	    times, NOT to report clock times, which are reported with as
  *	    much resolution as the system can muster.  In some cases this
- *	    resolution may depend on the underlaying clock hardware and
+ *	    resolution may depend on the underlying clock hardware and
  *	    may not be quantifiable until run time, and only then is the
  *	    necessary code is written.	The standard says we should say
  *	    something about this issue in the documentation...
@@ -162,7 +154,7 @@
  *
  *          At this time all functions EXCEPT clock_nanosleep can be
  *          redirected by the CLOCKS structure.  Clock_nanosleep is in
- *          there, but the code ignors it.
+ *          there, but the code ignores it.
  *
  * Permissions: It is assumed that the clock_settime() function defined
  *	    for each clock will take care of permission checks.	 Some
@@ -198,6 +190,8 @@
 	struct timespec *tp, struct timespec *mo);
 int do_posix_clock_monotonic_gettime(struct timespec *tp);
 int do_posix_clock_monotonic_settime(struct timespec *tp);
+int do_posix_clock_process_gettime(struct timespec *tp);
+int do_posix_clock_thread_gettime(struct timespec *tp);
 static struct k_itimer *lock_timer(timer_t timer_id, unsigned long *flags);

 static inline void unlock_timer(struct k_itimer *timr, unsigned long flags)
@@ -218,6 +212,14 @@
 		.clock_get = do_posix_clock_monotonic_gettime,
 		.clock_set = do_posix_clock_monotonic_settime
 	};
+	struct k_clock clock_thread = {.res = CLOCK_REALTIME_RES,
+		.abs_struct = NULL,
+		.clock_get = do_posix_clock_thread_gettime
+	};
+	struct k_clock clock_process = {.res = CLOCK_REALTIME_RES,
+		.abs_struct = NULL,
+		.clock_get = do_posix_clock_process_gettime
+	};

 #ifdef CONFIG_TIME_INTERPOLATION
 	/* Clocks are more accurate with time interpolators */
@@ -226,6 +228,8 @@

 	register_posix_clock(CLOCK_REALTIME, &clock_realtime);
 	register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
+	register_posix_clock(CLOCK_PROCESS_CPUTIME_ID, &clock_process);
+	register_posix_clock(CLOCK_THREAD_CPUTIME_ID, &clock_thread);

 	posix_timers_cache = kmem_cache_create("posix_timers_cache",
 					sizeof (struct k_itimer), 0, 0, NULL, NULL);
@@ -1227,6 +1231,18 @@
 	return -EINVAL;
 }

+int do_posix_clock_thread_gettime(struct timespec *tp)
+{
+	jiffies_to_timespec(get_jiffies_64()-current->start_time, tp);
+	return 0;
+}
+
+int do_posix_clock_process_gettime(struct timespec *tp)
+{
+	jiffies_to_timespec(get_jiffies_64()-current->group_leader->start_time, tp);
+	return 0;
+}
+
 asmlinkage long
 sys_clock_settime(clockid_t which_clock, const struct timespec __user *tp)
 {

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [time] add support for CLOCK_THREAD_CPUTIME_ID and CLOCK_PROCESS_CPUTIME_ID
  2004-09-24 12:16 ` [time] add support for CLOCK_THREAD_CPUTIME_ID and CLOCK_PROCESS_CPUTIME_ID Christoph Lameter
@ 2004-09-25  4:25   ` Ulrich Drepper
  2004-09-25  5:25     ` Christoph Lameter
  2004-09-25  5:54     ` Christoph Lameter
  0 siblings, 2 replies; 57+ messages in thread
From: Ulrich Drepper @ 2004-09-25  4:25 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: linux-kernel

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Christoph Lameter wrote:

> +int do_posix_clock_thread_gettime(struct timespec *tp)
> +{
> +	jiffies_to_timespec(get_jiffies_64()-current->start_time, tp);
> +	return 0;
> +}
> +
> +int do_posix_clock_process_gettime(struct timespec *tp)
> +{
> +	jiffies_to_timespec(get_jiffies_64()-current->group_leader->start_time, tp);
> +	return 0;
> +}
> +

This is pretty useless.  Why would you need kernel support for this, it
just measures realtime.

We have an implementation of the CPU time in glibc which can easily be
changed to support clocks of this precision if there are no usable
timestamp counters (which is what is currently used).

And all this is not really what was really meant by "CPU time" in the
POSIX spec.  We hijacked this symbol, maybe incorrectly so.  What is
really meant is how much time a process/thread actually _uses_ the CPU
(hence the name).  I.e., the information contained in struct rusage.

For this I would love to get kernel support and we hopefully have soon a
patch for this.

- --
? Ulrich Drepper ? Red Hat, Inc. ? 444 Castro St ? Mountain View, CA ?
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)

iD8DBQFBVPNJ2ijCOnn/RHQRAjXeAJ0dUlvRmh6eDJLD6BtmjI3CNWC7pQCfZvAG
wSJclC6wagAwrYqL7/rdpVs=
=SLxp
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [time] add support for CLOCK_THREAD_CPUTIME_ID and CLOCK_PROCESS_CPUTIME_ID
  2004-09-25  4:25   ` Ulrich Drepper
@ 2004-09-25  5:25     ` Christoph Lameter
  2004-09-25  5:54     ` Christoph Lameter
  1 sibling, 0 replies; 57+ messages in thread
From: Christoph Lameter @ 2004-09-25  5:25 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: linux-kernel

On Fri, 24 Sep 2004, Ulrich Drepper wrote:

> This is pretty useless.  Why would you need kernel support for this, it
> just measures realtime.

Glibc cannot do that reliably on an SMP system with its HP_TIMING
technique. Even systems with "synchronized" CPU timers typically have an
offset between the timers of different CPUs.

> We have an implementation of the CPU time in glibc which can easily be
> changed to support clocks of this precision if there are no usable
> timestamp counters (which is what is currently used).

Sorry it cannot be easily changed as I have repeatedly experienced.
I have posted lots of patches to address that issue for SMP systems which
were all rejected and you got insulted by my attempt to discuss the
problem and insisted that it was "solved".

> And all this is not really what was really meant by "CPU time" in the
> POSIX spec.  We hijacked this symbol, maybe incorrectly so.  What is
> really meant is how much time a process/thread actually _uses_ the CPU
> (hence the name).  I.e., the information contained in struct rusage.
>
> For this I would love to get kernel support and we hopefully have soon a
> patch for this.

Yes this may be easily addressed in the kernel. clock_gettime belongs
completely into the kernel. Could we get glibc to no longer handle clocks
on its own? The glibc code has always been horribly broken on SMP systems
and I fear that lots of software now assumes that CLOCK_PROCESS_CPUTIME_ID
gets you the runtime of the current process. The patch would allow this
software to run reliably on an SMP system.

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [time] add support for CLOCK_THREAD_CPUTIME_ID and CLOCK_PROCESS_CPUTIME_ID
  2004-09-25  4:25   ` Ulrich Drepper
  2004-09-25  5:25     ` Christoph Lameter
@ 2004-09-25  5:54     ` Christoph Lameter
  2004-09-25  6:08       ` Ulrich Drepper
  1 sibling, 1 reply; 57+ messages in thread
From: Christoph Lameter @ 2004-09-25  5:54 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: linux-kernel

On Fri, 24 Sep 2004, Ulrich Drepper wrote:

> For this I would love to get kernel support and we hopefully have soon a
> patch for this.

Then please sign off on the following patch:

Index: linus/kernel/posix-timers.c
===================================================================
--- linus.orig/kernel/posix-timers.c	2004-09-23 15:12:01.000000000 -0700
+++ linus/kernel/posix-timers.c	2004-09-24 22:51:51.000000000 -0700
@@ -133,18 +133,10 @@
  *	    resolution.	 Here we define the standard CLOCK_REALTIME as a
  *	    1/HZ resolution clock.
  *
- * CPUTIME & THREAD_CPUTIME: We are not, at this time, definding these
- *	    two clocks (and the other process related clocks (Std
- *	    1003.1d-1999).  The way these should be supported, we think,
- *	    is to use large negative numbers for the two clocks that are
- *	    pinned to the executing process and to use -pid for clocks
- *	    pinned to particular pids.	Calls which supported these clock
- *	    ids would split early in the function.
- *
  * RESOLUTION: Clock resolution is used to round up timer and interval
  *	    times, NOT to report clock times, which are reported with as
  *	    much resolution as the system can muster.  In some cases this
- *	    resolution may depend on the underlaying clock hardware and
+ *	    resolution may depend on the underlying clock hardware and
  *	    may not be quantifiable until run time, and only then is the
  *	    necessary code is written.	The standard says we should say
  *	    something about this issue in the documentation...
@@ -162,7 +154,7 @@
  *
  *          At this time all functions EXCEPT clock_nanosleep can be
  *          redirected by the CLOCKS structure.  Clock_nanosleep is in
- *          there, but the code ignors it.
+ *          there, but the code ignores it.
  *
  * Permissions: It is assumed that the clock_settime() function defined
  *	    for each clock will take care of permission checks.	 Some
@@ -198,6 +190,8 @@
 	struct timespec *tp, struct timespec *mo);
 int do_posix_clock_monotonic_gettime(struct timespec *tp);
 int do_posix_clock_monotonic_settime(struct timespec *tp);
+int do_posix_clock_process_gettime(struct timespec *tp);
+int do_posix_clock_thread_gettime(struct timespec *tp);
 static struct k_itimer *lock_timer(timer_t timer_id, unsigned long *flags);

 static inline void unlock_timer(struct k_itimer *timr, unsigned long flags)
@@ -218,6 +212,14 @@
 		.clock_get = do_posix_clock_monotonic_gettime,
 		.clock_set = do_posix_clock_monotonic_settime
 	};
+	struct k_clock clock_thread = {.res = CLOCK_REALTIME_RES,
+		.abs_struct = NULL,
+		.clock_get = do_posix_clock_thread_gettime
+	};
+	struct k_clock clock_process = {.res = CLOCK_REALTIME_RES,
+		.abs_struct = NULL,
+		.clock_get = do_posix_clock_process_gettime
+	};

 #ifdef CONFIG_TIME_INTERPOLATION
 	/* Clocks are more accurate with time interpolators */
@@ -226,6 +228,8 @@

 	register_posix_clock(CLOCK_REALTIME, &clock_realtime);
 	register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
+	register_posix_clock(CLOCK_PROCESS_CPUTIME_ID, &clock_process);
+	register_posix_clock(CLOCK_THREAD_CPUTIME_ID, &clock_thread);

 	posix_timers_cache = kmem_cache_create("posix_timers_cache",
 					sizeof (struct k_itimer), 0, 0, NULL, NULL);
@@ -1227,6 +1231,19 @@
 	return -EINVAL;
 }

+int do_posix_clock_thread_gettime(struct timespec *tp)
+{
+	jiffies_to_timespec(current->signal->cutime + current->signal->cstime, tp);
+	return 0;
+}
+
+int do_posix_clock_process_gettime(struct timespec *tp)
+{
+	jiffies_to_timespec(current->group_leader->signal->cutime +
+		current->group_leader->signal->cstime, tp);
+	return 0;
+}
+
 asmlinkage long
 sys_clock_settime(clockid_t which_clock, const struct timespec __user *tp)
 {

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [time] add support for CLOCK_THREAD_CPUTIME_ID and CLOCK_PROCESS_CPUTIME_ID
  2004-09-25  5:54     ` Christoph Lameter
@ 2004-09-25  6:08       ` Ulrich Drepper
  2004-09-25 14:51         ` Christoph Lameter
                           ` (2 more replies)
  0 siblings, 3 replies; 57+ messages in thread
From: Ulrich Drepper @ 2004-09-25  6:08 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: linux-kernel

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Christoph Lameter wrote:

> Then please sign off on the following patch:

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.

The comment changes are OK, of course.

If there is more to change this is in glibc.  So far I have not heard of
anybody wanting to use the clocks this way.  This is why we do not have
the fallback to realtime implemented.  If you say you need it I have no
problem adding appropriate patches.

- --
➧ Ulrich Drepper ➧ Red Hat, Inc. ➧ 444 Castro St ➧ Mountain View, CA ❖
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)

iD8DBQFBVQt32ijCOnn/RHQRAsWHAJ9q1Aztzf7/6TYQbu6X+DNQhFFW5wCfTP57
wbjQQe+iV/s1ODANFFYK+zs=
=JVgJ
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [time] add support for CLOCK_THREAD_CPUTIME_ID and CLOCK_PROCESS_CPUTIME_ID
  2004-09-25  6:08       ` Ulrich Drepper
@ 2004-09-25 14:51         ` Christoph Lameter
  2004-09-25 15:19           ` Ulrich Drepper
  2004-09-27 15:34         ` Christoph Lameter
       [not found]         ` <B6E8046E1E28D34EB815A11AC8CA312902CD327E@mtv-atc-605e--n.corp.sgi.com>
  2 siblings, 1 reply; 57+ messages in thread
From: Christoph Lameter @ 2004-09-25 14:51 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: linux-kernel

On Fri, 24 Sep 2004, Ulrich Drepper wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Christoph Lameter wrote:
>
> > Then please sign off on the following patch:
>
> 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

I thought I heard you asking for CPUTIME returning the actual cputime
used in the last message. I have proposed falling back to realtime in the
past but that was not acceptable.

>
>    clock_getres (CLOCK_PROCESS_CPUTIME_ID, &ts)
>
> to
>
>    clock_getres (CLOCK_REALTIME, &ts)
>
> The kernel knows nothing about this clock.

Yes and glibc will have to get through contortions to
simulate a clock that returns the actual cpu time used. Why not cleanly
do the clock_gettime syscall without doing any redirection of clocks?

Any implementation of the CPUTIME clocks is always easier to do in the
kernel with just a few lines.

> The comment changes are OK, of course.
>
> If there is more to change this is in glibc.  So far I have not heard of
> anybody wanting to use the clocks this way.  This is why we do not have
> the fallback to realtime implemented.  If you say you need it I have no
> problem adding appropriate patches.

Ok, I will dig out my old patch and repost it to glibc-alpha.

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [time] add support for CLOCK_THREAD_CPUTIME_ID and CLOCK_PROCESS_CPUTIME_ID
  2004-09-25 14:51         ` Christoph Lameter
@ 2004-09-25 15:19           ` Ulrich Drepper
  2004-09-27 15:03             ` Christoph Lameter
  0 siblings, 1 reply; 57+ messages in thread
From: Ulrich Drepper @ 2004-09-25 15:19 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: linux-kernel

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Christoph Lameter wrote:

> Yes and glibc will have to get through contortions to
> simulate a clock that returns the actual cpu time used. Why not cleanly
> do the clock_gettime syscall without doing any redirection of clocks?

First of all, unnecessary kernel code where it is not needed.  And
second, because with the definition of the CPUTIME clock in use for many
years now not all variants can be handled in the kernel.  We use this
clock to provide access to the TSC functionality.  This is nothing the
kernel does.


> Any implementation of the CPUTIME clocks is always easier to do in the
> kernel with just a few lines.

No, you don't know the glibc side.


> Ok, I will dig out my old patch and repost it to glibc-alpha.

I haven't gotten an answer to the question "is there really any value in
this kind of clock?".

- --
➧ Ulrich Drepper ➧ Red Hat, Inc. ➧ 444 Castro St ➧ Mountain View, CA ❖
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)

iD8DBQFBVYxt2ijCOnn/RHQRAmohAKCVAlRAxIHBi5uHqoKtfjfORQQNiACdHPuD
aCn2+pHl7MnBmWE2CAmSdb8=
=vJAO
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [time] add support for CLOCK_THREAD_CPUTIME_ID and CLOCK_PROCESS_CPUTIME_ID
  2004-09-25 15:19           ` Ulrich Drepper
@ 2004-09-27 15:03             ` Christoph Lameter
  0 siblings, 0 replies; 57+ messages in thread
From: Christoph Lameter @ 2004-09-27 15:03 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: linux-kernel

On Sat, 25 Sep 2004, Ulrich Drepper wrote:

> > Yes and glibc will have to get through contortions to
> > simulate a clock that returns the actual cpu time used. Why not cleanly
> > do the clock_gettime syscall without doing any redirection of clocks?
>
> First of all, unnecessary kernel code where it is not needed.  And
> second, because with the definition of the CPUTIME clock in use for many
> years now not all variants can be handled in the kernel.  We use this
> clock to provide access to the TSC functionality.  This is nothing the
> kernel does.

The kernel can do the same now in a much more reliable way since it can
produce time with nanosecond accuracy.

> > Any implementation of the CPUTIME clocks is always easier to do in the
> > kernel with just a few lines.
>
> No, you don't know the glibc side.

Yes, I do know that in detail. I have proposed numerous patches for this
issue to glibc-alpha.

> > Ok, I will dig out my old patch and repost it to glibc-alpha.
>
> I haven't gotten an answer to the question "is there really any value in
> this kind of clock?".

My old patches implement what you suggested: fallback to CLOCK_REALTIME in
glibc if the cputimer is not reliable.

I do not really understand your question. The CLOCK_PROCESS_CPUTIME_ID is
a clock mandated by the POSIX standard and it should work reliably. There
is no question that this clock must be provided.

I do not care how it is done as long as it always works reliably. It is IMHO
the best solution to put that into the kernel since glibc does not really
have all the information available to provide this clock (f.e. the
information obtained via TSC is not adjusted properly since the kernel
time adjustments will not be applied to it) but I will respect your
preferred way to solving this issue.

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [time] add support for CLOCK_THREAD_CPUTIME_ID and CLOCK_PROCESS_CPUTIME_ID
  2004-09-25  6:08       ` Ulrich Drepper
  2004-09-25 14:51         ` Christoph Lameter
@ 2004-09-27 15:34         ` Christoph Lameter
       [not found]         ` <B6E8046E1E28D34EB815A11AC8CA312902CD327E@mtv-atc-605e--n.corp.sgi.com>
  2 siblings, 0 replies; 57+ messages in thread
From: Christoph Lameter @ 2004-09-27 15:34 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: linux-kernel, libc-alpha

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
     }

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [RFC] Posix compliant behavior of CLOCK_PROCESS/THREAD_CPUTIME_ID
       [not found]         ` <B6E8046E1E28D34EB815A11AC8CA312902CD327E@mtv-atc-605e--n.corp.sgi.com>
@ 2004-09-27 20:58           ` Christoph Lameter
  2004-09-27 22:54             ` George Anzinger
                               ` (2 more replies)
  0 siblings, 3 replies; 57+ messages in thread
From: Christoph Lameter @ 2004-09-27 20:58 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: johnstul, Ulrich.Windl, george, linux-kernel, libc-alpha

Attached follows a patch to implement the POSIX clocks according to the
POSIX standard which states in V3 of the Single Unix Specification:

1. CLOCK_PROCESS_CPUTIME_ID

  Implementations shall also support the special clockid_t value
  CLOCK_PROCESS_CPUTIME_ID, which represents the CPU-time clock of the
  calling process when invoking one of the clock_*() or timer_*()
  functions. For these clock IDs, the values returned by clock_gettime() and specified
  by clock_settime() represent the amount of execution time of the process
  associated with the clock.

2. CLOCK_THREAD_CPUTIME_ID

  Implementations shall also support the special clockid_t value
  CLOCK_THREAD_CPUTIME_ID, which represents the CPU-time clock of the
  calling thread when invoking one of the clock_*() or timer_*()
  functions. For these clock IDs, the values returned by clock_gettime()
  and specified by clock_settime() shall represent the amount of
  execution time of the thread associated with the clock.

These times mentioned are CPU processing times and not the time that has
passed since the startup of a process. Glibc currently provides its own
implementation of these two clocks which is designed to return the time
that passed since the startup of a process or a thread.

Moreover this clock is bound to CPU timers which is problematic when the
frequency of the clock changes or the process is moved to a different
processor whose cpu timer may not be fully synchronized to the cpu timer
of the current CPU.

I would like to have the following patch integrated into the kernel. Glibc
would need to be modified to simply generate a system call for clock_* without
doing its own emulation of a clock. CLOCK_PROCESS_CPUTIME_ID and
CLOCK_THREAD_CPUTIME id were never intended to be used as a means to
access a time stamp counter on a CPU and it may be better to find another
means of accesses the cpu time registerss.

The patch is really quite straighforward and only affects one file...

Index: linus/kernel/posix-timers.c
===================================================================
--- linus.orig/kernel/posix-timers.c	2004-09-23 15:12:01.000000000 -0700
+++ linus/kernel/posix-timers.c	2004-09-27 13:42:40.000000000 -0700
@@ -10,6 +10,10 @@
  * 2004-06-01  Fix CLOCK_REALTIME clock/timer TIMER_ABSTIME bug.
  *			     Copyright (C) 2004 Boris Hu
  *
+ * 2004-07-27 Provide POSIX compliant clocks
+ *		CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID.
+ *		by Christoph Lameter
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or (at
@@ -133,18 +137,10 @@
  *	    resolution.	 Here we define the standard CLOCK_REALTIME as a
  *	    1/HZ resolution clock.
  *
- * CPUTIME & THREAD_CPUTIME: We are not, at this time, definding these
- *	    two clocks (and the other process related clocks (Std
- *	    1003.1d-1999).  The way these should be supported, we think,
- *	    is to use large negative numbers for the two clocks that are
- *	    pinned to the executing process and to use -pid for clocks
- *	    pinned to particular pids.	Calls which supported these clock
- *	    ids would split early in the function.
- *
  * RESOLUTION: Clock resolution is used to round up timer and interval
  *	    times, NOT to report clock times, which are reported with as
  *	    much resolution as the system can muster.  In some cases this
- *	    resolution may depend on the underlaying clock hardware and
+ *	    resolution may depend on the underlying clock hardware and
  *	    may not be quantifiable until run time, and only then is the
  *	    necessary code is written.	The standard says we should say
  *	    something about this issue in the documentation...
@@ -162,7 +158,7 @@
  *
  *          At this time all functions EXCEPT clock_nanosleep can be
  *          redirected by the CLOCKS structure.  Clock_nanosleep is in
- *          there, but the code ignors it.
+ *          there, but the code ignores it.
  *
  * Permissions: It is assumed that the clock_settime() function defined
  *	    for each clock will take care of permission checks.	 Some
@@ -198,6 +194,8 @@
 	struct timespec *tp, struct timespec *mo);
 int do_posix_clock_monotonic_gettime(struct timespec *tp);
 int do_posix_clock_monotonic_settime(struct timespec *tp);
+int do_posix_clock_process_gettime(struct timespec *tp);
+int do_posix_clock_thread_gettime(struct timespec *tp);
 static struct k_itimer *lock_timer(timer_t timer_id, unsigned long *flags);

 static inline void unlock_timer(struct k_itimer *timr, unsigned long flags)
@@ -218,6 +216,14 @@
 		.clock_get = do_posix_clock_monotonic_gettime,
 		.clock_set = do_posix_clock_monotonic_settime
 	};
+	struct k_clock clock_thread = {.res = CLOCK_REALTIME_RES,
+		.abs_struct = NULL,
+		.clock_get = do_posix_clock_thread_gettime
+	};
+	struct k_clock clock_process = {.res = CLOCK_REALTIME_RES,
+		.abs_struct = NULL,
+		.clock_get = do_posix_clock_process_gettime
+	};

 #ifdef CONFIG_TIME_INTERPOLATION
 	/* Clocks are more accurate with time interpolators */
@@ -226,6 +232,8 @@

 	register_posix_clock(CLOCK_REALTIME, &clock_realtime);
 	register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
+	register_posix_clock(CLOCK_PROCESS_CPUTIME_ID, &clock_process);
+	register_posix_clock(CLOCK_THREAD_CPUTIME_ID, &clock_thread);

 	posix_timers_cache = kmem_cache_create("posix_timers_cache",
 					sizeof (struct k_itimer), 0, 0, NULL, NULL);
@@ -1227,6 +1235,46 @@
 	return -EINVAL;
 }

+/*
+ * Single Unix Specification V3:
+ *
+ * Implementations shall also support the special clockid_t value
+ * CLOCK_THREAD_CPUTIME_ID, which represents the CPU-time clock of the calling
+ * thread when invoking one of the clock_*() or timer_*() functions. For these
+ * clock IDs, the values returned by clock_gettime() and specified by
+ * clock_settime() shall represent the amount of execution time of the thread
+ * associated with the clock.
+ */
+int do_posix_clock_thread_gettime(struct timespec *tp)
+{
+	jiffies_to_timespec(current->signal->cutime + current->signal->cstime, tp);
+	return 0;
+}
+
+/*
+ * Single Unix Specification V3:
+ *
+ * Implementations shall also support the special clockid_t value
+ * CLOCK_PROCESS_CPUTIME_ID, which represents the CPU-time clock of the
+ * calling process when invoking one of the clock_*() or timer_*() functions.
+ * For these clock IDs, the values returned by clock_gettime() and specified
+ * by clock_settime() represent the amount of execution time of the process
+ * associated with the clock.
+ */
+int do_posix_clock_process_gettime(struct timespec *tp)
+{
+	unsigned long ticks = 0;
+	struct task *t;
+
+	/* Add up the cpu time for all the threads of this process */
+	for (t = current; t != current; t = next_thread(p)) {
+		ticks += t->signal->cutime + t->signal->cstime;
+	}
+
+	jiffies_to_timespec(ticks, tp);
+	return 0;
+}
+
 asmlinkage long
 sys_clock_settime(clockid_t which_clock, const struct timespec __user *tp)
 {

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [RFC] Posix compliant behavior of CLOCK_PROCESS/THREAD_CPUTIME_ID
  2004-09-27 20:58           ` [RFC] Posix compliant behavior of CLOCK_PROCESS/THREAD_CPUTIME_ID Christoph Lameter
@ 2004-09-27 22:54             ` George Anzinger
  2004-09-28 19:18             ` Ulrich Drepper
  2004-10-01 21:57             ` [RFC] Posix compliant behavior of CLOCK_PROCESS/THREAD_CPUTIME_ID Roland McGrath
  2 siblings, 0 replies; 57+ messages in thread
From: George Anzinger @ 2004-09-27 22:54 UTC (permalink / raw)
  To: Christoph Lameter
  Cc: Ulrich Drepper, johnstul, Ulrich.Windl, linux-kernel, libc-alpha

Uh, do you have a test program to verify these?  I would like to add it to the 
support package on sourceforge.

George

Christoph Lameter wrote:
> Attached follows a patch to implement the POSIX clocks according to the
> POSIX standard which states in V3 of the Single Unix Specification:
> 
> 1. CLOCK_PROCESS_CPUTIME_ID
> 
>   Implementations shall also support the special clockid_t value
>   CLOCK_PROCESS_CPUTIME_ID, which represents the CPU-time clock of the
>   calling process when invoking one of the clock_*() or timer_*()
>   functions. For these clock IDs, the values returned by clock_gettime() and specified
>   by clock_settime() represent the amount of execution time of the process
>   associated with the clock.
> 
> 2. CLOCK_THREAD_CPUTIME_ID
> 
>   Implementations shall also support the special clockid_t value
>   CLOCK_THREAD_CPUTIME_ID, which represents the CPU-time clock of the
>   calling thread when invoking one of the clock_*() or timer_*()
>   functions. For these clock IDs, the values returned by clock_gettime()
>   and specified by clock_settime() shall represent the amount of
>   execution time of the thread associated with the clock.
> 
> These times mentioned are CPU processing times and not the time that has
> passed since the startup of a process. Glibc currently provides its own
> implementation of these two clocks which is designed to return the time
> that passed since the startup of a process or a thread.
> 
> Moreover this clock is bound to CPU timers which is problematic when the
> frequency of the clock changes or the process is moved to a different
> processor whose cpu timer may not be fully synchronized to the cpu timer
> of the current CPU.
> 
> I would like to have the following patch integrated into the kernel. Glibc
> would need to be modified to simply generate a system call for clock_* without
> doing its own emulation of a clock. CLOCK_PROCESS_CPUTIME_ID and
> CLOCK_THREAD_CPUTIME id were never intended to be used as a means to
> access a time stamp counter on a CPU and it may be better to find another
> means of accesses the cpu time registerss.
> 
> The patch is really quite straighforward and only affects one file...
> 
> Index: linus/kernel/posix-timers.c
> ===================================================================
> --- linus.orig/kernel/posix-timers.c	2004-09-23 15:12:01.000000000 -0700
> +++ linus/kernel/posix-timers.c	2004-09-27 13:42:40.000000000 -0700
> @@ -10,6 +10,10 @@
>   * 2004-06-01  Fix CLOCK_REALTIME clock/timer TIMER_ABSTIME bug.
>   *			     Copyright (C) 2004 Boris Hu
>   *
> + * 2004-07-27 Provide POSIX compliant clocks
> + *		CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID.
> + *		by Christoph Lameter
> + *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License as published by
>   * the Free Software Foundation; either version 2 of the License, or (at
> @@ -133,18 +137,10 @@
>   *	    resolution.	 Here we define the standard CLOCK_REALTIME as a
>   *	    1/HZ resolution clock.
>   *
> - * CPUTIME & THREAD_CPUTIME: We are not, at this time, definding these
> - *	    two clocks (and the other process related clocks (Std
> - *	    1003.1d-1999).  The way these should be supported, we think,
> - *	    is to use large negative numbers for the two clocks that are
> - *	    pinned to the executing process and to use -pid for clocks
> - *	    pinned to particular pids.	Calls which supported these clock
> - *	    ids would split early in the function.
> - *
>   * RESOLUTION: Clock resolution is used to round up timer and interval
>   *	    times, NOT to report clock times, which are reported with as
>   *	    much resolution as the system can muster.  In some cases this
> - *	    resolution may depend on the underlaying clock hardware and
> + *	    resolution may depend on the underlying clock hardware and
>   *	    may not be quantifiable until run time, and only then is the
>   *	    necessary code is written.	The standard says we should say
>   *	    something about this issue in the documentation...
> @@ -162,7 +158,7 @@
>   *
>   *          At this time all functions EXCEPT clock_nanosleep can be
>   *          redirected by the CLOCKS structure.  Clock_nanosleep is in
> - *          there, but the code ignors it.
> + *          there, but the code ignores it.
>   *
>   * Permissions: It is assumed that the clock_settime() function defined
>   *	    for each clock will take care of permission checks.	 Some
> @@ -198,6 +194,8 @@
>  	struct timespec *tp, struct timespec *mo);
>  int do_posix_clock_monotonic_gettime(struct timespec *tp);
>  int do_posix_clock_monotonic_settime(struct timespec *tp);
> +int do_posix_clock_process_gettime(struct timespec *tp);
> +int do_posix_clock_thread_gettime(struct timespec *tp);
>  static struct k_itimer *lock_timer(timer_t timer_id, unsigned long *flags);
> 
>  static inline void unlock_timer(struct k_itimer *timr, unsigned long flags)
> @@ -218,6 +216,14 @@
>  		.clock_get = do_posix_clock_monotonic_gettime,
>  		.clock_set = do_posix_clock_monotonic_settime
>  	};
> +	struct k_clock clock_thread = {.res = CLOCK_REALTIME_RES,
> +		.abs_struct = NULL,
> +		.clock_get = do_posix_clock_thread_gettime
> +	};
> +	struct k_clock clock_process = {.res = CLOCK_REALTIME_RES,
> +		.abs_struct = NULL,
> +		.clock_get = do_posix_clock_process_gettime
> +	};

You will have to supply functions to return errors for the unimplemented calls. 
  Otherwise the caller will end up in the CLOCK_REALTIME code which will just 
not work.

Also, to trap calls to clock_nanosleep() you will need to start running it 
through the same dispatch table.  (See notes on this in the comments.).

-g
> 
>  #ifdef CONFIG_TIME_INTERPOLATION
>  	/* Clocks are more accurate with time interpolators */
> @@ -226,6 +232,8 @@
> 
>  	register_posix_clock(CLOCK_REALTIME, &clock_realtime);
>  	register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
> +	register_posix_clock(CLOCK_PROCESS_CPUTIME_ID, &clock_process);
> +	register_posix_clock(CLOCK_THREAD_CPUTIME_ID, &clock_thread);
> 
>  	posix_timers_cache = kmem_cache_create("posix_timers_cache",
>  					sizeof (struct k_itimer), 0, 0, NULL, NULL);
> @@ -1227,6 +1235,46 @@
>  	return -EINVAL;
>  }
> 
> +/*
> + * Single Unix Specification V3:
> + *
> + * Implementations shall also support the special clockid_t value
> + * CLOCK_THREAD_CPUTIME_ID, which represents the CPU-time clock of the calling
> + * thread when invoking one of the clock_*() or timer_*() functions. For these
> + * clock IDs, the values returned by clock_gettime() and specified by
> + * clock_settime() shall represent the amount of execution time of the thread
> + * associated with the clock.
> + */
> +int do_posix_clock_thread_gettime(struct timespec *tp)
> +{
> +	jiffies_to_timespec(current->signal->cutime + current->signal->cstime, tp);
> +	return 0;
> +}
> +
> +/*
> + * Single Unix Specification V3:
> + *
> + * Implementations shall also support the special clockid_t value
> + * CLOCK_PROCESS_CPUTIME_ID, which represents the CPU-time clock of the
> + * calling process when invoking one of the clock_*() or timer_*() functions.
> + * For these clock IDs, the values returned by clock_gettime() and specified
> + * by clock_settime() represent the amount of execution time of the process
> + * associated with the clock.
> + */
> +int do_posix_clock_process_gettime(struct timespec *tp)
> +{
> +	unsigned long ticks = 0;
> +	struct task *t;
> +
> +	/* Add up the cpu time for all the threads of this process */
> +	for (t = current; t != current; t = next_thread(p)) {
> +		ticks += t->signal->cutime + t->signal->cstime;
> +	}
> +
> +	jiffies_to_timespec(ticks, tp);
> +	return 0;
> +}
> +
>  asmlinkage long
>  sys_clock_settime(clockid_t which_clock, const struct timespec __user *tp)
>  {
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 

-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [RFC] Posix compliant behavior of CLOCK_PROCESS/THREAD_CPUTIME_ID
  2004-09-27 20:58           ` [RFC] Posix compliant behavior of CLOCK_PROCESS/THREAD_CPUTIME_ID Christoph Lameter
  2004-09-27 22:54             ` George Anzinger
@ 2004-09-28 19:18             ` Ulrich Drepper
  2004-09-28 19:25               ` Christoph Lameter
                                 ` (2 more replies)
  2004-10-01 21:57             ` [RFC] Posix compliant behavior of CLOCK_PROCESS/THREAD_CPUTIME_ID Roland McGrath
  2 siblings, 3 replies; 57+ messages in thread
From: Ulrich Drepper @ 2004-09-28 19:18 UTC (permalink / raw)
  To: Christoph Lameter
  Cc: johnstul, Ulrich.Windl, george, linux-kernel, libc-alpha

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I'm not the right person to comment on this, I hope Roland will.  Roland
has been working on an implementation of this clock.  I think the
situation is quite a bit more complicated than your patch suggests.  So,
please wait until he has time to comment.

- --
➧ Ulrich Drepper ➧ Red Hat, Inc. ➧ 444 Castro St ➧ Mountain View, CA ❖
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)

iD8DBQFBWbkg2ijCOnn/RHQRArRbAJ9jEv/jwYuHuxQeT7fITmBAixaP2wCfcu0e
Ysb9uKlNxF58eycti8tA2us=
=AHNp
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [RFC] Posix compliant behavior of CLOCK_PROCESS/THREAD_CPUTIME_ID
  2004-09-28 19:18             ` Ulrich Drepper
@ 2004-09-28 19:25               ` Christoph Lameter
  2004-09-29  3:25               ` Posix compliant CLOCK_PROCESS/THREAD_CPUTIME_ID V4 Christoph Lameter
  2004-10-21 19:32               ` Posix compliant process clock patch for the linux arch in glibc Christoph Lameter
  2 siblings, 0 replies; 57+ messages in thread
From: Christoph Lameter @ 2004-09-28 19:25 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: johnstul, Ulrich.Windl, george, linux-kernel, libc-alpha

Could you forward the messages to him?

On Tue, 28 Sep 2004, Ulrich Drepper wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> I'm not the right person to comment on this, I hope Roland will.  Roland
> has been working on an implementation of this clock.  I think the
> situation is quite a bit more complicated than your patch suggests.  So,
> please wait until he has time to comment.
>
> - --
> ➧ Ulrich Drepper ➧ Red Hat, Inc. ➧ 444 Castro St ➧ Mountain View, CA ❖
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.2.6 (GNU/Linux)
>
> iD8DBQFBWbkg2ijCOnn/RHQRArRbAJ9jEv/jwYuHuxQeT7fITmBAixaP2wCfcu0e
> Ysb9uKlNxF58eycti8tA2us=
> =AHNp
> -----END PGP SIGNATURE-----
>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Posix compliant CLOCK_PROCESS/THREAD_CPUTIME_ID V4
  2004-09-28 19:18             ` Ulrich Drepper
  2004-09-28 19:25               ` Christoph Lameter
@ 2004-09-29  3:25               ` Christoph Lameter
  2004-09-29 17:45                 ` George Anzinger
  2004-10-21 19:32               ` Posix compliant process clock patch for the linux arch in glibc Christoph Lameter
  2 siblings, 1 reply; 57+ messages in thread
From: Christoph Lameter @ 2004-09-29  3:25 UTC (permalink / raw)
  To: Ulrich Drepper
  Cc: johnstul, Ulrich.Windl, george, jbarnes, linux-kernel, libc-alpha

George asked for a test program so I wrote one and debugged the patch.
The test program uses syscall to bypass glibc processing. I have been
working on a patch for glibc but that gets a bit complicated
because backwards compatibility has to be kept. Maybe tomorrow.
Found also that glibc allows the setting of these clocks so I also
implemented that and used it in the test program.  Setting these
clocks modifies stime and utime directly, which may not be such a good
idea. Do we really need to be able to set these clocks?

So it actually works now. Test output, test program and revised patch:

christoph@athlon:~$ ./test_cputime
Single Thread Testing
  CLOCK_THREAD_CPUTIME_ID=          0.373943152 resolution= 0.000999848
 CLOCK_PROCESS_CPUTIME_ID=          0.373943152 resolution= 0.000999848
Multi Thread Testing
Starting Thread: 0 1 2 3 4 5 6 7 8 9
 Joining Thread: 0 1 2 3 4 5 6 7 8 9
0 Cycles=      0 Thread=  0.000000000ns Process=  0.000000000ns
1 Cycles=1000000 Thread=  0.037994224ns Process=  0.507922784ns
2 Cycles=2000000 Thread=  0.073988752ns Process=  0.097985104ns
3 Cycles=3000000 Thread=  0.108983432ns Process=  0.612906824ns
4 Cycles=4000000 Thread=  0.146977656ns Process=  0.657899984ns
5 Cycles=5000000 Thread=  0.182972184ns Process=  0.739887520ns
6 Cycles=6000000 Thread=  0.217966864ns Process=  1.456778536ns
7 Cycles=7000000 Thread=  0.254961240ns Process=  1.461777776ns
8 Cycles=8000000 Thread=  0.290955768ns Process=  1.627752544ns
9 Cycles=9000000 Thread=  0.326950296ns Process=  1.641750416ns

Clock status at the end of the timer tests:
          Gettimeofday() = 1096427813.738929000
           CLOCK_REALTIME= 1096427813.738941000 resolution= 0.000999848
          CLOCK_MONOTONIC=        161.938418328 resolution= 0.000999848
 CLOCK_PROCESS_CPUTIME_ID=          1.641750416 resolution= 0.000999848
  CLOCK_THREAD_CPUTIME_ID=          0.000000000 resolution= 0.000999848

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <asm/unistd.h>
#include <pthread.h>

#define clock_getres(x,y) syscall(__NR_clock_getres, x,y)
#define clock_gettime(x,y) syscall(__NR_clock_gettime, x, y)
#define clock_settime(x,y) syscall(__NR_clock_settime, x, y)

void pr(int clock,const char *n)
{
	struct timespec tv = {1,2};
	struct timespec res = {3,4};
	int rc;


	rc=clock_getres(clock,&res);
	if (rc) {
		printf("getres return code on %s=%d errno=%d\n",n,rc,errno);
	}
	rc=clock_gettime(clock,&tv);
	if (rc) {
		printf("gettime return code on %s=%d errno=%d\n",n,rc, errno);
	}
	else
	printf("%25s=% 11d.%09d resolution=% 2d.%09d\n",n,tv.tv_sec,tv.tv_nsec,res.tv_sec,res.tv_nsec);
}

int y;

void kx(long long x) {
	y=x;
};

struct timespec zero;

pthread_t thread[10];

struct tinfo {
	int i;
	struct timespec ttime,ptime;
} tinf[10];

void *thread_function(void *x) {
	struct tinfo *t=x;
	int i;

	for(i=1;i< t->i;i++) kx(1000000000000LL/i);
	clock_gettime(CLOCK_THREAD_CPUTIME_ID,&t->ttime);
	clock_gettime(CLOCK_PROCESS_CPUTIME_ID,&t->ptime);
}

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

	/* Waste some time */
	printf("Single Thread Testing\n");

	for(i=1;i<10000000;i++) kx(1000000000000LL/i);
	pr(CLOCK_THREAD_CPUTIME_ID,"CLOCK_THREAD_CPUTIME_ID");
	pr(CLOCK_PROCESS_CPUTIME_ID,"CLOCK_PROCESS_CPUTIME_ID");
	/* Waste some more time in threads */
	printf("Multi Thread Testing\nStarting Thread:");
	clock_settime(CLOCK_PROCESS_CPUTIME_ID,&zero);
	for(i=0;i<10;i++) {
		tinf[i].i=i*1000000;
		if (pthread_create(&thread[i], NULL, thread_function, tinf+i))
			perror("thread");
		else
			printf(" %d",i);
	}
	printf("\n Joining Thread:");
	for(i=0;i<10;i++) if (pthread_join( thread[i], NULL)) perror("join"); else printf(" %d",i);
	printf("\n");
	for(i=0;i<10;i++) {
		printf("%d Cycles=%7d Thread=% 3d.%09dns Process=% 3d.%09dns\n",i,tinf[i].i,tinf[i].ttime.tv_sec,tinf[i].ttime.tv_nsec,tinf[i].ptime.tv_sec,tinf[i].ptime.tv_nsec);
	}
	gettimeofday((struct timeval *)&tv);
	tv.tv_nsec = tv.tv_nsec*1000;
	printf("\nClock status at the end of the timer tests:\n");
	printf("          Gettimeofday() =% 11d.%09d\n",tv.tv_sec,tv.tv_nsec);
	pr(CLOCK_REALTIME,"CLOCK_REALTIME");
	pr(CLOCK_MONOTONIC,"CLOCK_MONOTONIC");
	pr(CLOCK_PROCESS_CPUTIME_ID,"CLOCK_PROCESS_CPUTIME_ID");
	pr(CLOCK_THREAD_CPUTIME_ID,"CLOCK_THREAD_CPUTIME_ID");
	printf("\n");
}

Index: linux-2.6.9-rc2/kernel/posix-timers.c
===================================================================
--- linux-2.6.9-rc2.orig/kernel/posix-timers.c	2004-09-12 22:32:48.000000000 -0700
+++ linux-2.6.9-rc2/kernel/posix-timers.c	2004-09-28 19:49:59.919624581 -0700
@@ -10,6 +10,10 @@
  * 2004-06-01  Fix CLOCK_REALTIME clock/timer TIMER_ABSTIME bug.
  *			     Copyright (C) 2004 Boris Hu
  *
+ * 2004-07-27 Provide POSIX compliant clocks
+ *		CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID.
+ *		by Christoph Lameter
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or (at
@@ -133,18 +137,10 @@
  *	    resolution.	 Here we define the standard CLOCK_REALTIME as a
  *	    1/HZ resolution clock.
  *
- * CPUTIME & THREAD_CPUTIME: We are not, at this time, definding these
- *	    two clocks (and the other process related clocks (Std
- *	    1003.1d-1999).  The way these should be supported, we think,
- *	    is to use large negative numbers for the two clocks that are
- *	    pinned to the executing process and to use -pid for clocks
- *	    pinned to particular pids.	Calls which supported these clock
- *	    ids would split early in the function.
- *
  * RESOLUTION: Clock resolution is used to round up timer and interval
  *	    times, NOT to report clock times, which are reported with as
  *	    much resolution as the system can muster.  In some cases this
- *	    resolution may depend on the underlaying clock hardware and
+ *	    resolution may depend on the underlying clock hardware and
  *	    may not be quantifiable until run time, and only then is the
  *	    necessary code is written.	The standard says we should say
  *	    something about this issue in the documentation...
@@ -162,7 +158,7 @@
  *
  *          At this time all functions EXCEPT clock_nanosleep can be
  *          redirected by the CLOCKS structure.  Clock_nanosleep is in
- *          there, but the code ignors it.
+ *          there, but the code ignores it.
  *
  * Permissions: It is assumed that the clock_settime() function defined
  *	    for each clock will take care of permission checks.	 Some
@@ -198,6 +194,10 @@
 	struct timespec *tp, struct timespec *mo);
 int do_posix_clock_monotonic_gettime(struct timespec *tp);
 int do_posix_clock_monotonic_settime(struct timespec *tp);
+int do_posix_clock_process_gettime(struct timespec *tp);
+int do_posix_clock_process_settime(struct timespec *tp);
+int do_posix_clock_thread_gettime(struct timespec *tp);
+int do_posix_clock_thread_settime(struct timespec *tp);
 static struct k_itimer *lock_timer(timer_t timer_id, unsigned long *flags);

 static inline void unlock_timer(struct k_itimer *timr, unsigned long flags)
@@ -218,6 +218,16 @@
 		.clock_get = do_posix_clock_monotonic_gettime,
 		.clock_set = do_posix_clock_monotonic_settime
 	};
+	struct k_clock clock_thread = {.res = CLOCK_REALTIME_RES,
+		.abs_struct = NULL,
+		.clock_get = do_posix_clock_thread_gettime,
+		.clock_set = do_posix_clock_thread_settime
+	};
+	struct k_clock clock_process = {.res = CLOCK_REALTIME_RES,
+		.abs_struct = NULL,
+		.clock_get = do_posix_clock_process_gettime,
+		.clock_set = do_posix_clock_process_settime
+	};

 #ifdef CONFIG_TIME_INTERPOLATION
 	/* Clocks are more accurate with time interpolators */
@@ -226,6 +236,8 @@

 	register_posix_clock(CLOCK_REALTIME, &clock_realtime);
 	register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
+	register_posix_clock(CLOCK_PROCESS_CPUTIME_ID, &clock_process);
+	register_posix_clock(CLOCK_THREAD_CPUTIME_ID, &clock_thread);

 	posix_timers_cache = kmem_cache_create("posix_timers_cache",
 					sizeof (struct k_itimer), 0, 0, NULL, NULL);
@@ -1227,6 +1239,76 @@
 	return -EINVAL;
 }

+/*
+ * Single Unix Specification V3:
+ *
+ * Implementations shall also support the special clockid_t value
+ * CLOCK_THREAD_CPUTIME_ID, which represents the CPU-time clock of the calling
+ * thread when invoking one of the clock_*() or timer_*() functions. For these
+ * clock IDs, the values returned by clock_gettime() and specified by
+ * clock_settime() shall represent the amount of execution time of the thread
+ * associated with the clock.
+ */
+int do_posix_clock_thread_gettime(struct timespec *tp)
+{
+	jiffies_to_timespec(current->utime + current->stime, tp);
+	return 0;
+}
+
+int do_posix_clock_thread_settime(struct timespec *tp)
+{
+	current->stime = 0;
+	current->utime = timespec_to_jiffies(tp);
+	return 0;
+}
+
+/*
+ * Single Unix Specification V3:
+ *
+ * Implementations shall also support the special clockid_t value
+ * CLOCK_PROCESS_CPUTIME_ID, which represents the CPU-time clock of the
+ * calling process when invoking one of the clock_*() or timer_*() functions.
+ * For these clock IDs, the values returned by clock_gettime() and specified
+ * by clock_settime() represent the amount of execution time of the process
+ * associated with the clock.
+ */
+int do_posix_clock_process_gettime(struct timespec *tp)
+{
+	unsigned long ticks;
+	task_t *t;
+
+	/* The signal structure is shared between all threads */
+	ticks = current->signal->utime + current->signal->stime;
+
+	/* Add up the cpu time for all the still running threads of this process */
+	t = current;
+	do {
+		ticks += t->utime + t->stime;
+		t = next_thread(t);
+	} while (t != current);
+
+	jiffies_to_timespec(ticks, tp);
+	return 0;
+}
+
+int do_posix_clock_process_settime(struct timespec *tp)
+{
+	task_t *t;
+	/*
+	 * Set all other threads to zero cs/cutime and then set up the
+	 * desired time in the current thread
+	 */
+
+	for (t = next_thread(current); t != current; t = next_thread(t))
+	{
+		t->stime = 0;
+		t->utime = 0;
+	}
+
+	do_posix_clock_thread_settime(tp);
+	return 0;
+}
+
 asmlinkage long
 sys_clock_settime(clockid_t which_clock, const struct timespec __user *tp)
 {

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Posix compliant CLOCK_PROCESS/THREAD_CPUTIME_ID V4
  2004-09-29  3:25               ` Posix compliant CLOCK_PROCESS/THREAD_CPUTIME_ID V4 Christoph Lameter
@ 2004-09-29 17:45                 ` George Anzinger
  2004-09-29 18:14                   ` Christoph Lameter
                                     ` (3 more replies)
  0 siblings, 4 replies; 57+ messages in thread
From: George Anzinger @ 2004-09-29 17:45 UTC (permalink / raw)
  To: Christoph Lameter
  Cc: Ulrich Drepper, johnstul, Ulrich.Windl, jbarnes, linux-kernel,
	libc-alpha

Christoph Lameter wrote:
> George asked for a test program so I wrote one and debugged the patch.
> The test program uses syscall to bypass glibc processing. I have been
> working on a patch for glibc but that gets a bit complicated
> because backwards compatibility has to be kept. Maybe tomorrow.
> Found also that glibc allows the setting of these clocks so I also
> implemented that and used it in the test program.  Setting these
> clocks modifies stime and utime directly, which may not be such a good
> idea. Do we really need to be able to set these clocks?

Another way of doing this is to save these values in the task structure.  If 
null, use the direct value of stime, utime, if not, adjust by the saved value 
(i.e. saved value would represent time zero).
> 
> So it actually works now. Test output, test program and revised patch:

Please, when sending patches, attach them.  This avoids problems with mailers, 
on both ends, messing with white space.  They still appear in line, at least in 
some mailers (mozilla in my case).

As to the test program, what happens when you attempt to set up a timer on these 
clocks?  (No, I don't think it should work, but we DO want to properly error 
out.  And the test should verify that this happens.)  By the way, if you use the 
support package from sourceforge, you will find a lot of test harness stuff.


~
-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Posix compliant CLOCK_PROCESS/THREAD_CPUTIME_ID V4
  2004-09-29 17:45                 ` George Anzinger
@ 2004-09-29 18:14                   ` Christoph Lameter
  2004-09-29 19:27                     ` George Anzinger
  2004-09-29 19:32                   ` Posix compliant CLOCK_PROCESS/THREAD_CPUTIME_ID V5 Christoph Lameter
                                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 57+ messages in thread
From: Christoph Lameter @ 2004-09-29 18:14 UTC (permalink / raw)
  To: George Anzinger
  Cc: Ulrich Drepper, johnstul, Ulrich.Windl, jbarnes, linux-kernel,
	libc-alpha

On Wed, 29 Sep 2004, George Anzinger wrote:

> Christoph Lameter wrote:
> > George asked for a test program so I wrote one and debugged the patch.
> > The test program uses syscall to bypass glibc processing. I have been
> > working on a patch for glibc but that gets a bit complicated
> > because backwards compatibility has to be kept. Maybe tomorrow.
> > Found also that glibc allows the setting of these clocks so I also
> > implemented that and used it in the test program.  Setting these
> > clocks modifies stime and utime directly, which may not be such a good
> > idea. Do we really need to be able to set these clocks?
>
> Another way of doing this is to save these values in the task structure.  If
> null, use the direct value of stime, utime, if not, adjust by the saved value
> (i.e. saved value would represent time zero).

But this would require two additional int field in task_t just for that
rarely used functionality.

> Please, when sending patches, attach them.  This avoids problems with mailers,
> on both ends, messing with white space.  They still appear in line, at least in
> some mailers (mozilla in my case).

The custom on lkml, for Linus and Andrew is to send them inline. I also
prefer them inline. Will try to remember sending attachments when sending a
patch to you.

> As to the test program, what happens when you attempt to set up a timer on these
> clocks?  (No, I don't think it should work, but we DO want to properly error
> out.  And the test should verify that this happens.)  By the way, if you use the
> support package from sourceforge, you will find a lot of test harness stuff.

That is an interesting issue. If that would work correctly one could
trigger an signal if more than a certain amount of cputime is used.
It looks though that it will create an interrupt based on real time.

SuS says:

 Each implementation defines a set of clocks that can be used as timing
 bases for per-process timers. All implementations support a clock_id of
 CLOCK_REALTIME.

So restrict timer_create to CLOCK_REALTIME and CLOCK_MONOTONIC? Is it
necessary to be able to derive a timer from a timer derives from those
two?

something like the following (just inlined for the discussion ...)?

--- linux-2.6.9-rc2.orig/kernel/posix-timers.c  2004-09-28 20:29:28.000000000 -0700
+++ linux-2.6.9-rc2/kernel/posix-timers.c       2004-09-29 11:12:37.814713085 -0700
@@ -585,8 +585,8 @@
        sigevent_t event;
        int it_id_set = IT_ID_NOT_SET;

-       if ((unsigned) which_clock >= MAX_CLOCKS ||
-                               !posix_clocks[which_clock].res)
+       if ((unsigned) which_clock != CLOCK_REALTIME &&
+           (unsigned) which_clock != CLOCK_MONOTONIC)
                return -EINVAL;

        new_timer = alloc_posix_timer();


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Posix compliant CLOCK_PROCESS/THREAD_CPUTIME_ID V4
  2004-09-29 18:14                   ` Christoph Lameter
@ 2004-09-29 19:27                     ` George Anzinger
  2004-09-29 19:34                       ` Christoph Lameter
  2004-09-29 19:52                       ` Jesper Juhl
  0 siblings, 2 replies; 57+ messages in thread
From: George Anzinger @ 2004-09-29 19:27 UTC (permalink / raw)
  To: Christoph Lameter
  Cc: Ulrich Drepper, johnstul, Ulrich.Windl, jbarnes, linux-kernel,
	libc-alpha

Christoph Lameter wrote:
> On Wed, 29 Sep 2004, George Anzinger wrote:
> 
> 
>>Christoph Lameter wrote:
>>
>>>George asked for a test program so I wrote one and debugged the patch.
>>>The test program uses syscall to bypass glibc processing. I have been
>>>working on a patch for glibc but that gets a bit complicated
>>>because backwards compatibility has to be kept. Maybe tomorrow.
>>>Found also that glibc allows the setting of these clocks so I also
>>>implemented that and used it in the test program.  Setting these
>>>clocks modifies stime and utime directly, which may not be such a good
>>>idea. Do we really need to be able to set these clocks?
>>
>>Another way of doing this is to save these values in the task structure.  If
>>null, use the direct value of stime, utime, if not, adjust by the saved value
>>(i.e. saved value would represent time zero).
> 
> 
> But this would require two additional int field in task_t just for that
> rarely used functionality.

Exactly.  What does the community want?  An alternative is to allocate a small 
block of memory for this and managed it from the posix-timers.c code.  It would 
only be referenced by get_clock and set_clock.  And be released by the 
exit_itimers() code.
> 
> 
>>Please, when sending patches, attach them.  This avoids problems with mailers,
>>on both ends, messing with white space.  They still appear in line, at least in
>>some mailers (mozilla in my case).
> 
> 
> The custom on lkml, for Linus and Andrew is to send them inline. I also
> prefer them inline. Will try to remember sending attachments when sending a
> patch to you.

I think they WILL be inline as well as attached if you attach them.  The 
difference is that in both presentations neither mailer will mess with white 
space.  This means that long lines will not be wrapped and tabs vs space will 
not be changed.

Try sending yourself one and see it this is not true for your mailer.

> 
>>As to the test program, what happens when you attempt to set up a timer on these
>>clocks?  (No, I don't think it should work, but we DO want to properly error
>>out.  And the test should verify that this happens.)  By the way, if you use the
>>support package from sourceforge, you will find a lot of test harness stuff.
> 
> 
> That is an interesting issue. If that would work correctly one could
> trigger an signal if more than a certain amount of cputime is used.
> It looks though that it will create an interrupt based on real time.
> 
> SuS says:
> 
>  Each implementation defines a set of clocks that can be used as timing
>  bases for per-process timers. All implementations support a clock_id of
>  CLOCK_REALTIME.
> 
> So restrict timer_create to CLOCK_REALTIME and CLOCK_MONOTONIC? Is it
> necessary to be able to derive a timer from a timer derives from those
> two?
> 
> something like the following (just inlined for the discussion ...)?

NO.  This is handled through the dispatch table (as set up when you register the 
clock).  You just supply a timer_create() function that returns the right error. 
  Likewise, attempts to use clock_nanosleep().  The issue with clock_nanosleep, 
however, is that it, at this time, is not sent through the dispatch table.  This 
should be changed to, again call the same error function.
> 
> --- linux-2.6.9-rc2.orig/kernel/posix-timers.c  2004-09-28 20:29:28.000000000 -0700
> +++ linux-2.6.9-rc2/kernel/posix-timers.c       2004-09-29 11:12:37.814713085 -0700
> @@ -585,8 +585,8 @@
>         sigevent_t event;
>         int it_id_set = IT_ID_NOT_SET;
> 
> -       if ((unsigned) which_clock >= MAX_CLOCKS ||
> -                               !posix_clocks[which_clock].res)
> +       if ((unsigned) which_clock != CLOCK_REALTIME &&
> +           (unsigned) which_clock != CLOCK_MONOTONIC)
>                 return -EINVAL;
> 
>         new_timer = alloc_posix_timer();
> 

-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Posix compliant CLOCK_PROCESS/THREAD_CPUTIME_ID V5
  2004-09-29 17:45                 ` George Anzinger
  2004-09-29 18:14                   ` Christoph Lameter
@ 2004-09-29 19:32                   ` Christoph Lameter
  2004-10-01 19:57                   ` Posix compliant cpu clocks V6 [0/3]: Rationale and test program Christoph Lameter
       [not found]                   ` <B6E8046E1E28D34EB815A11AC8CA31290322B307@mtv-atc-605e--n.corp.sgi.com>
  3 siblings, 0 replies; 57+ messages in thread
From: Christoph Lameter @ 2004-09-29 19:32 UTC (permalink / raw)
  To: George Anzinger
  Cc: Ulrich Drepper, johnstul, Ulrich.Windl, jbarnes, linux-kernel,
	libc-alpha

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1603 bytes --]

This version uses an offset field in the task and signal structs
to store offsets for the thread and process clock. It also includes
the check in timer_create for REALTIME or MONOTONIC. The
clocks are now independent and therefore the thread clock is not
clearedby clock_settime(CLOCK_PROCESS_CPUTIME_ID) in the testrun:

Single Thread Testing
  CLOCK_THREAD_CPUTIME_ID=          0.374943000 resolution= 0.000999848
 CLOCK_PROCESS_CPUTIME_ID=          0.374943000 resolution= 0.000999848
Multi Thread Testing
Starting Thread: 0 1 2 3 4 5 6 7 8 9
 Joining Thread: 0 1 2 3 4 5 6 7 8 9
0 Cycles=      0 Thread=  0.000000000ns Process=  0.000999848ns
1 Cycles=1000000 Thread=  0.036994376ns Process=  0.315951968ns
2 Cycles=2000000 Thread=  0.073988752ns Process=  0.086986776ns
3 Cycles=3000000 Thread=  0.109983280ns Process=  0.517921264ns
4 Cycles=4000000 Thread=  0.146977656ns Process=  0.563914272ns
5 Cycles=5000000 Thread=  0.180972488ns Process=  1.043841312ns
6 Cycles=6000000 Thread=  0.218966712ns Process=  1.112830824ns
7 Cycles=7000000 Thread=  0.254961240ns Process=  1.620753608ns
8 Cycles=8000000 Thread=  0.290955768ns Process=  1.490773368ns
9 Cycles=9000000 Thread=  0.326950296ns Process=  1.641750416ns

Clock status at the end of the timer tests:
          Gettimeofday() = 1096484938.561351000
           CLOCK_REALTIME= 1096484938.561363000 resolution= 0.000999848
          CLOCK_MONOTONIC=        157.633669432 resolution= 0.000999848
 CLOCK_PROCESS_CPUTIME_ID=          1.641750416 resolution= 0.000999848
  CLOCK_THREAD_CPUTIME_ID=          0.375942848 resolution= 0.000999848

[-- Attachment #2: V5 of patch --]
[-- Type: TEXT/PLAIN, Size: 7268 bytes --]

Index: linux-2.6.9-rc2/kernel/posix-timers.c
===================================================================
--- linux-2.6.9-rc2.orig/kernel/posix-timers.c	2004-09-12 22:32:48.000000000 -0700
+++ linux-2.6.9-rc2/kernel/posix-timers.c	2004-09-29 11:48:54.000000000 -0700
@@ -10,6 +10,10 @@
  * 2004-06-01  Fix CLOCK_REALTIME clock/timer TIMER_ABSTIME bug.
  *			     Copyright (C) 2004 Boris Hu
  *
+ * 2004-07-27 Provide POSIX compliant clocks
+ *		CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID.
+ *		by Christoph Lameter
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or (at
@@ -133,18 +137,10 @@
  *	    resolution.	 Here we define the standard CLOCK_REALTIME as a
  *	    1/HZ resolution clock.
  *
- * CPUTIME & THREAD_CPUTIME: We are not, at this time, definding these
- *	    two clocks (and the other process related clocks (Std
- *	    1003.1d-1999).  The way these should be supported, we think,
- *	    is to use large negative numbers for the two clocks that are
- *	    pinned to the executing process and to use -pid for clocks
- *	    pinned to particular pids.	Calls which supported these clock
- *	    ids would split early in the function.
- *
  * RESOLUTION: Clock resolution is used to round up timer and interval
  *	    times, NOT to report clock times, which are reported with as
  *	    much resolution as the system can muster.  In some cases this
- *	    resolution may depend on the underlaying clock hardware and
+ *	    resolution may depend on the underlying clock hardware and
  *	    may not be quantifiable until run time, and only then is the
  *	    necessary code is written.	The standard says we should say
  *	    something about this issue in the documentation...
@@ -162,7 +158,7 @@
  *
  *          At this time all functions EXCEPT clock_nanosleep can be
  *          redirected by the CLOCKS structure.  Clock_nanosleep is in
- *          there, but the code ignors it.
+ *          there, but the code ignores it.
  *
  * Permissions: It is assumed that the clock_settime() function defined
  *	    for each clock will take care of permission checks.	 Some
@@ -198,6 +194,10 @@
 	struct timespec *tp, struct timespec *mo);
 int do_posix_clock_monotonic_gettime(struct timespec *tp);
 int do_posix_clock_monotonic_settime(struct timespec *tp);
+int do_posix_clock_process_gettime(struct timespec *tp);
+int do_posix_clock_process_settime(struct timespec *tp);
+int do_posix_clock_thread_gettime(struct timespec *tp);
+int do_posix_clock_thread_settime(struct timespec *tp);
 static struct k_itimer *lock_timer(timer_t timer_id, unsigned long *flags);
 
 static inline void unlock_timer(struct k_itimer *timr, unsigned long flags)
@@ -218,6 +218,16 @@
 		.clock_get = do_posix_clock_monotonic_gettime,
 		.clock_set = do_posix_clock_monotonic_settime
 	};
+	struct k_clock clock_thread = {.res = CLOCK_REALTIME_RES,
+		.abs_struct = NULL,
+		.clock_get = do_posix_clock_thread_gettime,
+		.clock_set = do_posix_clock_thread_settime
+	};
+	struct k_clock clock_process = {.res = CLOCK_REALTIME_RES,
+		.abs_struct = NULL,
+		.clock_get = do_posix_clock_process_gettime,
+		.clock_set = do_posix_clock_process_settime
+	};
 
 #ifdef CONFIG_TIME_INTERPOLATION
 	/* Clocks are more accurate with time interpolators */
@@ -226,6 +236,8 @@
 
 	register_posix_clock(CLOCK_REALTIME, &clock_realtime);
 	register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
+	register_posix_clock(CLOCK_PROCESS_CPUTIME_ID, &clock_process);
+	register_posix_clock(CLOCK_THREAD_CPUTIME_ID, &clock_thread);
 
 	posix_timers_cache = kmem_cache_create("posix_timers_cache",
 					sizeof (struct k_itimer), 0, 0, NULL, NULL);
@@ -573,8 +585,8 @@
 	sigevent_t event;
 	int it_id_set = IT_ID_NOT_SET;
 
-	if ((unsigned) which_clock >= MAX_CLOCKS ||
-				!posix_clocks[which_clock].res)
+	if ((unsigned) which_clock != CLOCK_REALTIME &&
+	    (unsigned) which_clock != CLOCK_MONOTONIC)
 		return -EINVAL;
 
 	new_timer = alloc_posix_timer();
@@ -1227,6 +1239,69 @@
 	return -EINVAL;
 }
 
+/*
+ * Single Unix Specification V3:
+ *
+ * Implementations shall also support the special clockid_t value
+ * CLOCK_THREAD_CPUTIME_ID, which represents the CPU-time clock of the calling
+ * thread when invoking one of the clock_*() or timer_*() functions. For these
+ * clock IDs, the values returned by clock_gettime() and specified by
+ * clock_settime() shall represent the amount of execution time of the thread
+ * associated with the clock. 
+ */
+int do_posix_clock_thread_gettime(struct timespec *tp)
+{
+	jiffies_to_timespec(current->utime + current->stime
+			+ current->thread_clock_offset, tp);
+	return 0;
+}
+
+int do_posix_clock_thread_settime(struct timespec *tp)
+{
+	current->thread_clock_offset = timespec_to_jiffies(tp)
+		- current->utime - current->stime;
+	return 0;
+}
+
+/*
+ * Single Unix Specification V3:
+ *
+ * Implementations shall also support the special clockid_t value
+ * CLOCK_PROCESS_CPUTIME_ID, which represents the CPU-time clock of the
+ * calling process when invoking one of the clock_*() or timer_*() functions.
+ * For these clock IDs, the values returned by clock_gettime() and specified
+ * by clock_settime() represent the amount of execution time of the process
+ * associated with the clock.
+ */
+
+unsigned long process_ticks(void) {
+	unsigned long ticks;
+	task_t *t;
+	
+	/* The signal structure is shared between all threads */
+	ticks = current->signal->utime + current->signal->stime;
+
+	/* Add up the cpu time for all the still running threads of this process */
+	t = current;
+	do {
+		ticks += t->utime + t->stime;
+		t = next_thread(t);
+	} while (t != current);
+	return ticks;
+}
+
+int do_posix_clock_process_gettime(struct timespec *tp)
+{
+	jiffies_to_timespec(current->signal->process_clock_offset + process_ticks(), tp);
+	return 0;
+}
+
+int do_posix_clock_process_settime(struct timespec *tp)
+{
+	current->signal->process_clock_offset = timespec_to_jiffies(tp) - process_ticks();
+	return 0;
+}
+
 asmlinkage long
 sys_clock_settime(clockid_t which_clock, const struct timespec __user *tp)
 {
Index: linux-2.6.9-rc2/include/linux/sched.h
===================================================================
--- linux-2.6.9-rc2.orig/include/linux/sched.h	2004-09-28 17:20:55.000000000 -0700
+++ linux-2.6.9-rc2/include/linux/sched.h	2004-09-29 11:41:27.000000000 -0700
@@ -293,6 +293,7 @@
 
 	/* POSIX.1b Interval Timers */
 	struct list_head posix_timers;
+	int			process_clock_offset;	/* for CLOCK_PROCESS_CPUTIME_ID */
 
 	/* job control IDs */
 	pid_t pgrp;
@@ -509,6 +510,7 @@
 	unsigned long utime, stime;
 	unsigned long nvcsw, nivcsw; /* context switch counts */
 	u64 start_time;
+	int thread_clock_offset;	/* offset to thread_clock for CLOCK_THREAD_CPUTIME_ID */
 /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
 	unsigned long min_flt, maj_flt;
 /* process credentials */

[-- Attachment #3: Test program --]
[-- Type: TEXT/x-csrc, Size: 2517 bytes --]

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <asm/unistd.h>
#include <pthread.h>

#define clock_getres(x,y) syscall(__NR_clock_getres, x,y)
#define clock_gettime(x,y) syscall(__NR_clock_gettime, x, y)
#define clock_settime(x,y) syscall(__NR_clock_settime, x, y)

void pr(int clock,const char *n)
{
	struct timespec tv = {1,2};
	struct timespec res = {3,4};
	int rc;


	rc=clock_getres(clock,&res);
	if (rc) {
		printf("getres return code on %s=%d errno=%d\n",n,rc,errno);
	}
	rc=clock_gettime(clock,&tv);
	if (rc) {
		printf("gettime return code on %s=%d errno=%d\n",n,rc, errno);
	} 
	else 
	printf("%25s=% 11d.%09d resolution=% 2d.%09d\n",n,tv.tv_sec,tv.tv_nsec,res.tv_sec,res.tv_nsec);
}

int y;

void kx(long long x) {
	y=x;
};

struct timespec zero;

pthread_t thread[10];

struct tinfo {
	int i;
	struct timespec ttime,ptime;
} tinf[10];

void *thread_function(void *x) {
	struct tinfo *t=x;
	int i;
	
	for(i=1;i< t->i;i++) kx(1000000000000LL/i);
	clock_gettime(CLOCK_THREAD_CPUTIME_ID,&t->ttime);
	clock_gettime(CLOCK_PROCESS_CPUTIME_ID,&t->ptime);
}

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

	/* Waste some time */
	printf("Single Thread Testing\n");
	
	for(i=1;i<10000000;i++) kx(1000000000000LL/i);
	pr(CLOCK_THREAD_CPUTIME_ID,"CLOCK_THREAD_CPUTIME_ID");
	pr(CLOCK_PROCESS_CPUTIME_ID,"CLOCK_PROCESS_CPUTIME_ID");
	/* Waste some more time in threads */
	printf("Multi Thread Testing\nStarting Thread:");
	clock_settime(CLOCK_PROCESS_CPUTIME_ID,&zero);
	for(i=0;i<10;i++) {
		tinf[i].i=i*1000000;
		if (pthread_create(&thread[i], NULL, thread_function, tinf+i))
			perror("thread");
		else
			printf(" %d",i);
	}
	printf("\n Joining Thread:");
	for(i=0;i<10;i++) if (pthread_join( thread[i], NULL)) perror("join"); else printf(" %d",i);
	printf("\n");
	for(i=0;i<10;i++) {
		printf("%d Cycles=%7d Thread=% 3d.%09dns Process=% 3d.%09dns\n",i,tinf[i].i,tinf[i].ttime.tv_sec,tinf[i].ttime.tv_nsec,tinf[i].ptime.tv_sec,tinf[i].ptime.tv_nsec);
	}	
	gettimeofday((struct timeval *)&tv);
	tv.tv_nsec = tv.tv_nsec*1000;
	printf("\nClock status at the end of the timer tests:\n");
	printf("          Gettimeofday() =% 11d.%09d\n",tv.tv_sec,tv.tv_nsec);
	pr(CLOCK_REALTIME,"CLOCK_REALTIME");
	pr(CLOCK_MONOTONIC,"CLOCK_MONOTONIC");
	pr(CLOCK_PROCESS_CPUTIME_ID,"CLOCK_PROCESS_CPUTIME_ID");
	pr(CLOCK_THREAD_CPUTIME_ID,"CLOCK_THREAD_CPUTIME_ID");
	printf("\n");
}

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Posix compliant CLOCK_PROCESS/THREAD_CPUTIME_ID V4
  2004-09-29 19:27                     ` George Anzinger
@ 2004-09-29 19:34                       ` Christoph Lameter
  2004-09-29 19:52                       ` Jesper Juhl
  1 sibling, 0 replies; 57+ messages in thread
From: Christoph Lameter @ 2004-09-29 19:34 UTC (permalink / raw)
  To: George Anzinger
  Cc: Ulrich Drepper, johnstul, Ulrich.Windl, jbarnes, linux-kernel,
	libc-alpha

On Wed, 29 Sep 2004, George Anzinger wrote:

> > So restrict timer_create to CLOCK_REALTIME and CLOCK_MONOTONIC? Is it
> > necessary to be able to derive a timer from a timer derives from those
> > two?
> >
> > something like the following (just inlined for the discussion ...)?
>
> NO.  This is handled through the dispatch table (as set up when you register the
> clock).  You just supply a timer_create() function that returns the right error.
>   Likewise, attempts to use clock_nanosleep().  The issue with clock_nanosleep,
> however, is that it, at this time, is not sent through the dispatch table.  This
> should be changed to, again call the same error function.

Ok. I gotta look at this again.


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Posix compliant CLOCK_PROCESS/THREAD_CPUTIME_ID V4
  2004-09-29 19:27                     ` George Anzinger
  2004-09-29 19:34                       ` Christoph Lameter
@ 2004-09-29 19:52                       ` Jesper Juhl
  2004-09-30  0:14                         ` patches inline in mail George Anzinger
  1 sibling, 1 reply; 57+ messages in thread
From: Jesper Juhl @ 2004-09-29 19:52 UTC (permalink / raw)
  To: George Anzinger
  Cc: Christoph Lameter, Ulrich Drepper, johnstul, Ulrich.Windl,
	jbarnes, linux-kernel, libc-alpha


Unrelated to the CLOCK_PROCESS/THREAD_CPUTIME_ID discussion, just wanted 
to comment on the 'patches inline vs attached' bit.

On Wed, 29 Sep 2004, George Anzinger wrote:

> Christoph Lameter wrote:
> > On Wed, 29 Sep 2004, George Anzinger wrote:
> > 
> > > Christoph Lameter wrote:
> > > 
> > > Please, when sending patches, attach them.  This avoids problems with
> > > mailers,
> > > on both ends, messing with white space.  They still appear in line, at
> > > least in
> > > some mailers (mozilla in my case).
> > 
> > 
> > The custom on lkml, for Linus and Andrew is to send them inline. I also
> > prefer them inline. Will try to remember sending attachments when sending a
> > patch to you.
> 
> I think they WILL be inline as well as attached if you attach them.  The
> difference is that in both presentations neither mailer will mess with white
> space.  This means that long lines will not be wrapped and tabs vs space will
> not be changed.
> 
Not all mailers show attachments inline. Mailers that do usually depend on 
the mimetype of the attachment when choosing to show inline or not. pine 
(my personal favorite) show attachments with a text/plain and similar 
mime-type inline, but a not all mailers use that (I see a lot of attached 
patches on lkml that don't show inline, and that's somewhat annoying).

It's also harder to reply and comment on bits of a patch when your mailer 
does not include attachments inline in a reply (even if it did show them 
inline while reading the mail).
Having to save the patch, open it in a text editor and then cut'n'paste 
bits of it into the reply mail is a pain. Same goes for having to save & 
open it in order to read it in the first place.

--
Jesper Juhl


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: patches inline in mail
  2004-09-29 19:52                       ` Jesper Juhl
@ 2004-09-30  0:14                         ` George Anzinger
  2004-09-30  3:24                           ` Paul Jackson
                                             ` (2 more replies)
  0 siblings, 3 replies; 57+ messages in thread
From: George Anzinger @ 2004-09-30  0:14 UTC (permalink / raw)
  To: Jesper Juhl
  Cc: Christoph Lameter, Ulrich Drepper, johnstul, Ulrich.Windl,
	jbarnes, linux-kernel, libc-alpha

Jesper Juhl wrote:
> Unrelated to the CLOCK_PROCESS/THREAD_CPUTIME_ID discussion, just wanted 
> to comment on the 'patches inline vs attached' bit.
> 
> On Wed, 29 Sep 2004, George Anzinger wrote:
> 
> 
>>Christoph Lameter wrote:
>>
>>>On Wed, 29 Sep 2004, George Anzinger wrote:
>>>
>>>
>>>>Christoph Lameter wrote:
>>>>
>>>>Please, when sending patches, attach them.  This avoids problems with
>>>>mailers,
>>>>on both ends, messing with white space.  They still appear in line, at
>>>>least in
>>>>some mailers (mozilla in my case).
>>>
>>>
>>>The custom on lkml, for Linus and Andrew is to send them inline. I also
>>>prefer them inline. Will try to remember sending attachments when sending a
>>>patch to you.
>>
>>I think they WILL be inline as well as attached if you attach them.  The
>>difference is that in both presentations neither mailer will mess with white
>>space.  This means that long lines will not be wrapped and tabs vs space will
>>not be changed.
>>
> 
> Not all mailers show attachments inline. Mailers that do usually depend on 
> the mimetype of the attachment when choosing to show inline or not. pine 
> (my personal favorite) show attachments with a text/plain and similar 
> mime-type inline, but a not all mailers use that (I see a lot of attached 
> patches on lkml that don't show inline, and that's somewhat annoying).

So we should make sure that the mailer uses the right mime-type.  I suppose that 
depends on the mailer?
> 
> It's also harder to reply and comment on bits of a patch when your mailer 
> does not include attachments inline in a reply (even if it did show them 
> inline while reading the mail).
> Having to save the patch, open it in a text editor and then cut'n'paste 
> bits of it into the reply mail is a pain. Same goes for having to save & 
> open it in order to read it in the first place.

We agree.  Still, I have been bitten too many times by misshandled white space 
to trust pure inlineing.  Likewise on picking it up one would usually past it in 
the mail (I suppose) where as the attachment is through the mailer and less 
prone to missing a character.

The best answer, I think, is attachments that show as inline AND stay that way 
on the reply.

Guild lines on how to insure this are welcome.
-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: patches inline in mail
  2004-09-30  0:14                         ` patches inline in mail George Anzinger
@ 2004-09-30  3:24                           ` Paul Jackson
  2004-10-01  5:29                           ` Andrew Morton
  2004-10-01  9:04                           ` Jesper Juhl
  2 siblings, 0 replies; 57+ messages in thread
From: Paul Jackson @ 2004-09-30  3:24 UTC (permalink / raw)
  To: george
  Cc: juhl-lkml, clameter, drepper, johnstul, Ulrich.Windl, jbarnes,
	linux-kernel, libc-alpha

George wrote:
> Still, I have been bitten too many times by misshandled white space 
> to trust pure inlineing. 

I use a script to send any patches I care much about, rather than my
email client.  The script sends the file directly to my SMTP server.

Especially when sending more than one related patch, I find it much more
accurate to prepare the small text file indicating To, Cc, Bcc, Subject,
local-patch-pathname for each patch in the set at my leisure, in my text
editor, until it all looks right, then issue a single command to send it
all off.

Email clients, especially the gui ones I'm fond of, are not well
suited to such work.

There are various such 'patch-bomb' scripts out there - mine is
available at:

	http://www.speakeasy.org/~pj99/sgi/sendpatchset

See the embedded Usage string for documentation.

The script checks out everything it can, including file paths and email
addresses (by verifying them with the SMTP server) before it sends
anything, further increasing the chance that if something is sent, it's
all sent and correctly so.

-- 
                          I won't rest till it's the best ...
                          Programmer, Linux Scalability
                          Paul Jackson <pj@sgi.com> 1.650.933.1373

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: patches inline in mail
  2004-09-30  0:14                         ` patches inline in mail George Anzinger
  2004-09-30  3:24                           ` Paul Jackson
@ 2004-10-01  5:29                           ` Andrew Morton
  2004-10-01 12:28                             ` Alan Cox
  2004-10-01  9:04                           ` Jesper Juhl
  2 siblings, 1 reply; 57+ messages in thread
From: Andrew Morton @ 2004-10-01  5:29 UTC (permalink / raw)
  To: george
  Cc: juhl-lkml, clameter, drepper, johnstul, Ulrich.Windl, jbarnes,
	linux-kernel, libc-alpha

George Anzinger <george@mvista.com> wrote:
>
> We agree.  Still, I have been bitten too many times by misshandled white space 
>  to trust pure inlineing.  Likewise on picking it up one would usually past it in 
>  the mail (I suppose) where as the attachment is through the mailer and less 
>  prone to missing a character.
> 
>  The best answer, I think, is attachments that show as inline AND stay that way 
>  on the reply.
> 
>  Guild lines on how to insure this are welcome.

Send angry email to everyone@mozilla.org.  AFAICT it's impossible with
recent mailnews.

Slightly more on-topic:

+int do_posix_clock_process_gettime(struct timespec *tp);
+int do_posix_clock_process_settime(struct timespec *tp);
+int do_posix_clock_thread_gettime(struct timespec *tp);
+int do_posix_clock_thread_settime(struct timespec *tp);

These should all be given static scope.

And it would be nice to structure the code so the forward decl isn't
needed, if poss.


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: patches inline in mail
  2004-09-30  0:14                         ` patches inline in mail George Anzinger
  2004-09-30  3:24                           ` Paul Jackson
  2004-10-01  5:29                           ` Andrew Morton
@ 2004-10-01  9:04                           ` Jesper Juhl
  2 siblings, 0 replies; 57+ messages in thread
From: Jesper Juhl @ 2004-10-01  9:04 UTC (permalink / raw)
  To: George Anzinger
  Cc: Christoph Lameter, Ulrich Drepper, johnstul, Ulrich.Windl,
	jbarnes, linux-kernel, libc-alpha

On Wed, 29 Sep 2004, George Anzinger wrote:

> Date: Wed, 29 Sep 2004 17:14:38 -0700
> From: George Anzinger <george@mvista.com>
> To: Jesper Juhl <juhl-lkml@dif.dk>
> Cc: Christoph Lameter <clameter@sgi.com>, Ulrich Drepper <drepper@redhat.com>,
>     johnstul@us.ibm.com, Ulrich.Windl@rz.uni-regensburg.de, jbarnes@sgi.com,
>     linux-kernel@vger.kernel.org, libc-alpha@sources.redhat.com
> Subject: Re: patches inline in mail
> 
> Jesper Juhl wrote:
> > Unrelated to the CLOCK_PROCESS/THREAD_CPUTIME_ID discussion, just wanted to
> > comment on the 'patches inline vs attached' bit.
> > 
> > On Wed, 29 Sep 2004, George Anzinger wrote:
> > 
> > 
> > > Christoph Lameter wrote:
> > > 
> > > > On Wed, 29 Sep 2004, George Anzinger wrote:
> > > > 
> > > > 
> > > > > Christoph Lameter wrote:
> > > > > 
> > > > > Please, when sending patches, attach them.  This avoids problems with
> > > > > mailers,
> > > > > on both ends, messing with white space.  They still appear in line, at
> > > > > least in
> > > > > some mailers (mozilla in my case).
> > > > 
> > > > 
> > > > The custom on lkml, for Linus and Andrew is to send them inline. I also
> > > > prefer them inline. Will try to remember sending attachments when
> > > > sending a
> > > > patch to you.
> > > 
> > > I think they WILL be inline as well as attached if you attach them.  The
> > > difference is that in both presentations neither mailer will mess with
> > > white
> > > space.  This means that long lines will not be wrapped and tabs vs space
> > > will
> > > not be changed.
> > > 
> > 
> > Not all mailers show attachments inline. Mailers that do usually depend on
> > the mimetype of the attachment when choosing to show inline or not. pine (my
> > personal favorite) show attachments with a text/plain and similar mime-type
> > inline, but a not all mailers use that (I see a lot of attached patches on
> > lkml that don't show inline, and that's somewhat annoying).
> 
> So we should make sure that the mailer uses the right mime-type.  I suppose
> that depends on the mailer?
> > 
> > It's also harder to reply and comment on bits of a patch when your mailer
> > does not include attachments inline in a reply (even if it did show them
> > inline while reading the mail).
> > Having to save the patch, open it in a text editor and then cut'n'paste bits
> > of it into the reply mail is a pain. Same goes for having to save & open it
> > in order to read it in the first place.
> 
> We agree.  Still, I have been bitten too many times by misshandled white space
> to trust pure inlineing.  Likewise on picking it up one would usually past it
> in the mail (I suppose) where as the attachment is through the mailer and less
> prone to missing a character.
> 

When I include patches inline in mails I use pine's "Read File" 
functionality. Pressing CTRL+R and then specifying a filename causes pine 
to read the file and place it inline exactely as read from the file. So no 
whitespace damage by cut'n'paste. 
I don't know, but I would suspect that other mailers would have similar 
functionality.??


> The best answer, I think, is attachments that show as inline AND stay that way
> on the reply.
> 
That would be just as fine as plain inline, but I think it'll be difficult 
to find a way to do that that works universally with all mailers.


--
Jesper Juhl



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: patches inline in mail
  2004-10-01  5:29                           ` Andrew Morton
@ 2004-10-01 12:28                             ` Alan Cox
  2004-10-01 13:42                               ` Paul Fulghum
  2004-10-01 21:58                               ` George Anzinger
  0 siblings, 2 replies; 57+ messages in thread
From: Alan Cox @ 2004-10-01 12:28 UTC (permalink / raw)
  To: Andrew Morton
  Cc: george, juhl-lkml, clameter, drepper, johnstul, Ulrich.Windl,
	jbarnes, Linux Kernel Mailing List, libc-alpha

On Gwe, 2004-10-01 at 06:29, Andrew Morton wrote:
> >  Guild lines on how to insure this are welcome.
> 
> Send angry email to everyone@mozilla.org.  AFAICT it's impossible with
> recent mailnews.

The mozilla behaviour is RFC compliant[1]. Use text/plain attachments
and mark them "to view" and it should do happier things. (Except with
Linus cos Mr Dinosaur[2] doesn't believe in MIME yet)

I've not been able to coax Evolution into not chewing on non attached
text either (again RFC compliant but not useful). If anyone knows a
magic incantation for it I'd love to know.

(and it might be a good addition to the lkml faq)

Alan
[1] Yes the RFC is stupid but its the spec nowdays
[2] Thankfully not purple and singing


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: patches inline in mail
  2004-10-01 12:28                             ` Alan Cox
@ 2004-10-01 13:42                               ` Paul Fulghum
  2004-10-01 19:53                                 ` Lee Revell
  2004-10-01 21:58                               ` George Anzinger
  1 sibling, 1 reply; 57+ messages in thread
From: Paul Fulghum @ 2004-10-01 13:42 UTC (permalink / raw)
  To: Alan Cox
  Cc: Andrew Morton, george, juhl-lkml, clameter, drepper, johnstul,
	Ulrich.Windl, jbarnes, Linux Kernel Mailing List, libc-alpha

On Fri, 2004-10-01 at 07:28, Alan Cox wrote:
> I've not been able to coax Evolution into not chewing on non attached
> text either (again RFC compliant but not useful). If anyone knows a
> magic incantation for it I'd love to know.

Select 'Preformat' instead of 'Normal' style and
do Insert->Text File. That works for me.

-- 
Paul Fulghum
paulkf@microgate.com


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: patches inline in mail
  2004-10-01 13:42                               ` Paul Fulghum
@ 2004-10-01 19:53                                 ` Lee Revell
  0 siblings, 0 replies; 57+ messages in thread
From: Lee Revell @ 2004-10-01 19:53 UTC (permalink / raw)
  To: Paul Fulghum
  Cc: Alan Cox, Andrew Morton, george, juhl-lkml, clameter, drepper,
	johnstul, Ulrich.Windl, jbarnes, Linux Kernel Mailing List,
	libc-alpha

On Fri, 2004-10-01 at 09:42, Paul Fulghum wrote:
> On Fri, 2004-10-01 at 07:28, Alan Cox wrote:
> > I've not been able to coax Evolution into not chewing on non attached
> > text either (again RFC compliant but not useful). If anyone knows a
> > magic incantation for it I'd love to know.
> 
> Select 'Preformat' instead of 'Normal' style and
> do Insert->Text File. That works for me.

You can also just copy and paste into Evolution as long as 'Preformat'
is set.  I just use 'diff -Nru foo bar | xclip'.  The problem is that
'Preformat' is a property of a given text range in the message; there is
no way to set 'Preformat' for all input.  So, if you paste with the
mouse and you don't hit the cursor exactly, Evolution will use 'Normal'
style and mangle the text.

It would be better if you could right click anywhere in the message and
have a 'Paste as preformatted' option.

Anyway this is OT, so LKML should be removed from any followups.

Lee


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Posix compliant cpu clocks V6 [0/3]: Rationale and test program
  2004-09-29 17:45                 ` George Anzinger
  2004-09-29 18:14                   ` Christoph Lameter
  2004-09-29 19:32                   ` Posix compliant CLOCK_PROCESS/THREAD_CPUTIME_ID V5 Christoph Lameter
@ 2004-10-01 19:57                   ` Christoph Lameter
       [not found]                   ` <B6E8046E1E28D34EB815A11AC8CA31290322B307@mtv-atc-605e--n.corp.sgi.com>
  3 siblings, 0 replies; 57+ messages in thread
From: Christoph Lameter @ 2004-10-01 19:57 UTC (permalink / raw)
  To: George Anzinger
  Cc: Ulrich Drepper, johnstul, Ulrich.Windl, jbarnes, akpm,
	linux-kernel, libc-alpha

Signed-off-by: Christoph Lameter <clameter@sgi.com>

Changes from V5: Add glibc patch, mmtimer patch, error checking.

POSIX clocks are to be implemented in the following way according
to V3 of the Single Unix Specification:

1. CLOCK_PROCESS_CPUTIME_ID

  Implementations shall also support the special clockid_t value
  CLOCK_PROCESS_CPUTIME_ID, which represents the CPU-time clock of the
  calling process when invoking one of the clock_*() or timer_*()
  functions. For these clock IDs, the values returned by clock_gettime() and
  specified by clock_settime() represent the amount of execution time of the
  process associated with the clock.

2. CLOCK_THREAD_CPUTIME_ID

  Implementations shall also support the special clockid_t value
  CLOCK_THREAD_CPUTIME_ID, which represents the CPU-time clock of the
  calling thread when invoking one of the clock_*() or timer_*()
  functions. For these clock IDs, the values returned by clock_gettime()
  and specified by clock_settime() shall represent the amount of
  execution time of the thread associated with the clock.

These times mentioned are CPU processing times and not the time that has
passed since the startup of a process. Glibc currently provides its own
implementation of these two clocks which is designed to return the time
that passed since the startup of a process or a thread.

Moreover Glibc's clocks are bound to CPU timers which is problematic when the
frequency of the clock changes or the process is moved to a different
processor whose cpu timer may not be fully synchronized to the cpu timer
of the current CPU. This patchset results in a both clocks working reliably.

The patchset consists of the following components:

[0/3] Contains an explanation as to why these patches are necessary
      as well as a test program and the output of a sample run.

[1/3] Linux Kernel Patch: Implements the two clocks and enhances some
      pieces of the posix-timers implementation in the kernel for these
      clocks and also makes it possible for device drivers to define
      additional clocks.

[2/3] Glibc patch: Makes glibc not provide its own clocks if the kernel
      provides them and also makes glibc able to use any posix clock provided
      by the kernel so that posix clocks by driver may be accessed.

[3/3] Kernel patch for mmtimer. Sets up a posix clock CLOCK_SGI_CYCLE
      that can currently only provide time but the clock will be used in the
      future to generate signals using timer_create and friends.

Test program output
==================

Single Thread Testing
  CLOCK_THREAD_CPUTIME_ID=          0.495117441 resolution= 0.000976563
 CLOCK_PROCESS_CPUTIME_ID=         32.496110388 resolution= 0.000976563
Multi Thread Testing
Starting Thread: 0 1 2 3 4 5 6 7 8 9
 Joining Thread: 0 1 2 3 4 5 6 7 8 9
0 Cycles=      0 Thread=  0.000000000ns Process=  0.000976563ns
1 Cycles=1000000 Thread=  1.368164763ns Process= 11.063482227ns
2 Cycles=2000000 Thread=  0.748047258ns Process=  6.340823559ns
3 Cycles=3000000 Thread=  0.672851907ns Process=  5.271487074ns
4 Cycles=4000000 Thread=  1.352539755ns Process= 10.551763215ns
5 Cycles=5000000 Thread=  2.007813528ns Process= 13.094733267ns
6 Cycles=6000000 Thread=  1.479492945ns Process= 12.622076775ns
7 Cycles=7000000 Thread=  1.733399325ns Process= 12.136724964ns
8 Cycles=8000000 Thread=  2.012696343ns Process= 13.690436697ns
9 Cycles=9000000 Thread=  2.331055881ns Process= 13.708991394ns

Clock status at the end of the timer tests:
          Gettimeofday() = 1096659625.612416000
           CLOCK_REALTIME= 1096659625.612603129 resolution= 0.000000040
          CLOCK_MONOTONIC=       9024.882157828 resolution= 0.000000040
 CLOCK_PROCESS_CPUTIME_ID=         13.709967957 resolution= 0.000976563
  CLOCK_THREAD_CPUTIME_ID=          0.498047130 resolution= 0.000976563
          CLOCK_SGI_CYCLE=       9077.595920640 resolution= 0.000000040


Test program
============

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <asm/unistd.h>
#include <pthread.h>

#define clock_getres(x,y) syscall(__NR_clock_getres, x,y)
#define clock_gettime(x,y) syscall(__NR_clock_gettime, x, y)
#define clock_settime(x,y) syscall(__NR_clock_settime, x, y)

void pr(int clock,const char *n)
{
	struct timespec tv = {1,2};
	struct timespec res = {3,4};
	int rc;


	rc=clock_getres(clock,&res);
	if (rc) {
		printf("getres return code on %s=%d errno=%d\n",n,rc,errno);
	}
	rc=clock_gettime(clock,&tv);
	if (rc) {
		printf("gettime return code on %s=%d errno=%d\n",n,rc, errno);
	}
	else
	printf("%25s=% 11d.%09d resolution=% 2d.%09d\n",n,tv.tv_sec,tv.tv_nsec,res.tv_sec,res.tv_nsec);
}

int y;

void kx(long long x) {
	y=x;
};

struct timespec zero;

pthread_t thread[10];

struct tinfo {
	int i;
	struct timespec ttime,ptime;
} tinf[10];

void *thread_function(void *x) {
	struct tinfo *t=x;
	int i;

	for(i=1;i< t->i;i++) kx(1000000000000LL/i);
	clock_gettime(CLOCK_THREAD_CPUTIME_ID,&t->ttime);
	clock_gettime(CLOCK_PROCESS_CPUTIME_ID,&t->ptime);
}

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

	/* Waste some time */
	printf("Single Thread Testing\n");

	for(i=1;i<10000000;i++) kx(1000000000000LL/i);
	pr(CLOCK_THREAD_CPUTIME_ID,"CLOCK_THREAD_CPUTIME_ID");
	pr(CLOCK_PROCESS_CPUTIME_ID,"CLOCK_PROCESS_CPUTIME_ID");
	/* Waste some more time in threads */
	printf("Multi Thread Testing\nStarting Thread:");
	clock_settime(CLOCK_PROCESS_CPUTIME_ID,&zero);
	for(i=0;i<10;i++) {
		tinf[i].i=i*1000000;
		if (pthread_create(&thread[i], NULL, thread_function, tinf+i))
			perror("thread");
		else
			printf(" %d",i);
	}
	printf("\n Joining Thread:");
	for(i=0;i<10;i++) if (pthread_join( thread[i], NULL)) perror("join"); else printf(" %d",i);
	printf("\n");
	for(i=0;i<10;i++) {
		printf("%d Cycles=%7d Thread=% 3d.%09dns Process=% 3d.%09dns\n",i,tinf[i].i,tinf[i].ttime.tv_sec,tinf[i].ttime.tv_nsec,tinf[i].ptime.tv_sec,tinf[i].ptime.tv_nsec);
	}
	gettimeofday((struct timeval *)&tv);
	tv.tv_nsec = tv.tv_nsec*1000;
	printf("\nClock status at the end of the timer tests:\n");
	printf("          Gettimeofday() =% 11d.%09d\n",tv.tv_sec,tv.tv_nsec);
	pr(CLOCK_REALTIME,"CLOCK_REALTIME");
	pr(CLOCK_MONOTONIC,"CLOCK_MONOTONIC");
	pr(CLOCK_PROCESS_CPUTIME_ID,"CLOCK_PROCESS_CPUTIME_ID");
	pr(CLOCK_THREAD_CPUTIME_ID,"CLOCK_THREAD_CPUTIME_ID");
	pr(10,"CLOCK_SGI_CYCLE");
	printf("\n");
}

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Posix compliant cpu clocks V6 [1/3]: Generic Kernel patch
       [not found]                   ` <B6E8046E1E28D34EB815A11AC8CA31290322B307@mtv-atc-605e--n.corp.sgi.com>
@ 2004-10-01 19:59                     ` Christoph Lameter
  2004-10-01 21:03                       ` Andrew Morton
  2004-10-01 20:01                     ` Posix compliant cpu clocks V6 [2/3]: Glibc patch Christoph Lameter
                                       ` (3 subsequent siblings)
  4 siblings, 1 reply; 57+ messages in thread
From: Christoph Lameter @ 2004-10-01 19:59 UTC (permalink / raw)
  To: George Anzinger
  Cc: Ulrich Drepper, johnstul, Ulrich.Windl, jbarnes, akpm,
	linux-kernel, libc-alpha

Changelog
	* Add CLOCK_THREAD_CPUTIME and CLOCK_PROCESS_CPUTIME_ID processing
	* Add timer_create override for posix clocks
	* Complete implementation of nanosleep overrride for posix clocks
	* export posix clock registration in include/linux/posix-timers.h
	* Allow up to 16 posix clocks

Signed-off-by: Christoph Lameter <clameter@sgi.com>

Index: linux-2.6.9-rc3/kernel/posix-timers.c
===================================================================
--- linux-2.6.9-rc3.orig/kernel/posix-timers.c	2004-09-29 20:04:47.000000000 -0700
+++ linux-2.6.9-rc3/kernel/posix-timers.c	2004-10-01 12:48:55.000000000 -0700
@@ -10,6 +10,10 @@
  * 2004-06-01  Fix CLOCK_REALTIME clock/timer TIMER_ABSTIME bug.
  *			     Copyright (C) 2004 Boris Hu
  *
+ * 2004-07-27 Provide POSIX compliant clocks
+ *		CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID.
+ *		by Christoph Lameter
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or (at
@@ -133,18 +137,10 @@
  *	    resolution.	 Here we define the standard CLOCK_REALTIME as a
  *	    1/HZ resolution clock.
  *
- * CPUTIME & THREAD_CPUTIME: We are not, at this time, definding these
- *	    two clocks (and the other process related clocks (Std
- *	    1003.1d-1999).  The way these should be supported, we think,
- *	    is to use large negative numbers for the two clocks that are
- *	    pinned to the executing process and to use -pid for clocks
- *	    pinned to particular pids.	Calls which supported these clock
- *	    ids would split early in the function.
- *
  * RESOLUTION: Clock resolution is used to round up timer and interval
  *	    times, NOT to report clock times, which are reported with as
  *	    much resolution as the system can muster.  In some cases this
- *	    resolution may depend on the underlaying clock hardware and
+ *	    resolution may depend on the underlying clock hardware and
  *	    may not be quantifiable until run time, and only then is the
  *	    necessary code is written.	The standard says we should say
  *	    something about this issue in the documentation...
@@ -162,7 +158,7 @@
  *
  *          At this time all functions EXCEPT clock_nanosleep can be
  *          redirected by the CLOCKS structure.  Clock_nanosleep is in
- *          there, but the code ignors it.
+ *          there, but the code ignores it.
  *
  * Permissions: It is assumed that the clock_settime() function defined
  *	    for each clock will take care of permission checks.	 Some
@@ -197,8 +193,16 @@
 static u64 do_posix_clock_monotonic_gettime_parts(
 	struct timespec *tp, struct timespec *mo);
 int do_posix_clock_monotonic_gettime(struct timespec *tp);
-int do_posix_clock_monotonic_settime(struct timespec *tp);
+static int do_posix_clock_monotonic_settime(struct timespec *tp);
+static int do_posix_clock_process_gettime(struct timespec *tp);
+static int do_posix_clock_process_settime(struct timespec *tp);
+static int do_posix_clock_thread_gettime(struct timespec *tp);
+static int do_posix_clock_thread_settime(struct timespec *tp);
 static struct k_itimer *lock_timer(timer_t timer_id, unsigned long *flags);
+int do_posix_clock_notimer_create(int which_clock,
+		struct sigevent __user *time_event_spec,
+		timer_t __user *created_timer_id);
+int do_posix_clock_nonanosleep(int which_clock, int flags, struct timespec * t);

 static inline void unlock_timer(struct k_itimer *timr, unsigned long flags)
 {
@@ -218,6 +222,20 @@
 		.clock_get = do_posix_clock_monotonic_gettime,
 		.clock_set = do_posix_clock_monotonic_settime
 	};
+	struct k_clock clock_thread = {.res = CLOCK_REALTIME_RES,
+		.abs_struct = NULL,
+		.clock_get = do_posix_clock_thread_gettime,
+		.clock_set = do_posix_clock_thread_settime,
+		.timer_create = do_posix_clock_notimer_create,
+		.nsleep = do_posix_clock_nonanosleep
+	};
+	struct k_clock clock_process = {.res = CLOCK_REALTIME_RES,
+		.abs_struct = NULL,
+		.clock_get = do_posix_clock_process_gettime,
+		.clock_set = do_posix_clock_process_settime,
+		.timer_create = do_posix_clock_notimer_create,
+		.nsleep = do_posix_clock_nonanosleep
+	};

 #ifdef CONFIG_TIME_INTERPOLATION
 	/* Clocks are more accurate with time interpolators */
@@ -226,6 +244,8 @@

 	register_posix_clock(CLOCK_REALTIME, &clock_realtime);
 	register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
+	register_posix_clock(CLOCK_PROCESS_CPUTIME_ID, &clock_process);
+	register_posix_clock(CLOCK_THREAD_CPUTIME_ID, &clock_thread);

 	posix_timers_cache = kmem_cache_create("posix_timers_cache",
 					sizeof (struct k_itimer), 0, 0, NULL, NULL);
@@ -577,6 +597,10 @@
 				!posix_clocks[which_clock].res)
 		return -EINVAL;

+	if (posix_clocks[which_clock].timer_create)
+		return posix_clocks[which_clock].timer_create(which_clock,
+				timer_event_spec, created_timer_id);
+
 	new_timer = alloc_posix_timer();
 	if (unlikely(!new_timer))
 		return -EAGAIN;
@@ -1222,11 +1246,88 @@
 	return 0;
 }

-int do_posix_clock_monotonic_settime(struct timespec *tp)
+static int do_posix_clock_monotonic_settime(struct timespec *tp)
 {
 	return -EINVAL;
 }

+int do_posix_clock_notimer_create(int which_clock,
+		struct sigevent __user *timer_event_spec,
+		timer_t __user *created_timer_id) {
+	return -EINVAL;
+}
+
+int do_posix_clock_nonanosleep(int which_lock, int flags,struct timespec * t) {
+/* Single Unix specficiation says to return ENOTSUP but we do not have that */
+	return -EINVAL;
+}
+
+/*
+ * Single Unix Specification V3:
+ *
+ * Implementations shall also support the special clockid_t value
+ * CLOCK_THREAD_CPUTIME_ID, which represents the CPU-time clock of the calling
+ * thread when invoking one of the clock_*() or timer_*() functions. For these
+ * clock IDs, the values returned by clock_gettime() and specified by
+ * clock_settime() shall represent the amount of execution time of the thread
+ * associated with the clock.
+ */
+static int do_posix_clock_thread_gettime(struct timespec *tp)
+{
+	jiffies_to_timespec(current->utime + current->stime
+			+ current->thread_clock_offset, tp);
+	return 0;
+}
+
+static int do_posix_clock_thread_settime(struct timespec *tp)
+{
+	current->thread_clock_offset = timespec_to_jiffies(tp)
+		- current->utime - current->stime;
+	return 0;
+}
+
+/*
+ * Single Unix Specification V3:
+ *
+ * Implementations shall also support the special clockid_t value
+ * CLOCK_PROCESS_CPUTIME_ID, which represents the CPU-time clock of the
+ * calling process when invoking one of the clock_*() or timer_*() functions.
+ * For these clock IDs, the values returned by clock_gettime() and specified
+ * by clock_settime() represent the amount of execution time of the process
+ * associated with the clock.
+ */
+
+static unsigned long process_ticks(void) {
+	unsigned long ticks;
+	task_t *t;
+
+	spin_lock(&current->sighand->siglock);
+	/* The signal structure is shared between all threads */
+	ticks = current->signal->utime + current->signal->stime;
+
+	/* Add up the cpu time for all the still running threads of this process */
+	t = current;
+	do {
+		ticks += t->utime + t->stime;
+		t = next_thread(t);
+	} while (t != current);
+
+	spin_unlock(&current->sighand->siglock);
+	return ticks;
+}
+
+static int do_posix_clock_process_gettime(struct timespec *tp)
+{
+	jiffies_to_timespec(current->signal->process_clock_offset + process_ticks(), tp);
+	return 0;
+}
+
+static int do_posix_clock_process_settime(struct timespec *tp)
+{
+	current->signal->process_clock_offset = timespec_to_jiffies(tp) - process_ticks();
+	return 0;
+}
+
 asmlinkage long
 sys_clock_settime(clockid_t which_clock, const struct timespec __user *tp)
 {
@@ -1413,7 +1514,10 @@
 	if ((unsigned) t.tv_nsec >= NSEC_PER_SEC || t.tv_sec < 0)
 		return -EINVAL;

-	ret = do_clock_nanosleep(which_clock, flags, &t);
+	if (posix_clocks[which_clock].nsleep)
+		ret = posix_clocks[which_clock].nsleep(which_clock, flags, &t);
+	else
+		ret = do_clock_nanosleep(which_clock, flags, &t);
 	/*
 	 * Do this here as do_clock_nanosleep does not have the real address
 	 */
Index: linux-2.6.9-rc3/include/linux/sched.h
===================================================================
--- linux-2.6.9-rc3.orig/include/linux/sched.h	2004-09-29 20:03:54.000000000 -0700
+++ linux-2.6.9-rc3/include/linux/sched.h	2004-10-01 08:40:30.000000000 -0700
@@ -293,6 +293,7 @@

 	/* POSIX.1b Interval Timers */
 	struct list_head posix_timers;
+	int			process_clock_offset;	/* for CLOCK_PROCESS_CPUTIME_ID */

 	/* job control IDs */
 	pid_t pgrp;
@@ -509,6 +510,7 @@
 	unsigned long utime, stime;
 	unsigned long nvcsw, nivcsw; /* context switch counts */
 	u64 start_time;
+	int thread_clock_offset;	/* offset to thread_clock for CLOCK_THREAD_CPUTIME_ID */
 /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
 	unsigned long min_flt, maj_flt;
 /* process credentials */
Index: linux-2.6.9-rc3/include/linux/posix-timers.h
===================================================================
--- linux-2.6.9-rc3.orig/include/linux/posix-timers.h	2004-09-29 20:04:46.000000000 -0700
+++ linux-2.6.9-rc3/include/linux/posix-timers.h	2004-10-01 08:40:30.000000000 -0700
@@ -13,9 +13,10 @@
 	struct k_clock_abs *abs_struct;
 	int (*clock_set) (struct timespec * tp);
 	int (*clock_get) (struct timespec * tp);
-	int (*nsleep) (int flags,
-		       struct timespec * new_setting,
-		       struct itimerspec * old_setting);
+	int (*timer_create) (int which_clock, struct sigevent __user *timer_event_spec,
+			timer_t __user * created_timer_id);
+	int (*nsleep) (int which_clock, int flags,
+		       struct timespec * t);
 	int (*timer_set) (struct k_itimer * timr, int flags,
 			  struct itimerspec * new_setting,
 			  struct itimerspec * old_setting);
@@ -23,6 +24,16 @@
 	void (*timer_get) (struct k_itimer * timr,
 			   struct itimerspec * cur_setting);
 };
+
+void register_posix_clock(int clock_id, struct k_clock *new_clock);
+
+/* Error handlers for timer_create and nanosleep */
+int do_posix_clock_notimer_create(int which_clock,
+                struct sigevent __user *time_event_spec,
+                timer_t __user *created_timer_id);
+
+int do_posix_clock_nonanosleep(int which_clock, int flags, struct timespec * t);
+
 struct now_struct {
 	unsigned long jiffies;
 };
@@ -42,3 +53,4 @@
               }								\
             }while (0)
 #endif
+
Index: linux-2.6.9-rc3/include/linux/time.h
===================================================================
--- linux-2.6.9-rc3.orig/include/linux/time.h	2004-09-29 20:05:18.000000000 -0700
+++ linux-2.6.9-rc3/include/linux/time.h	2004-10-01 08:40:30.000000000 -0700
@@ -413,7 +413,12 @@
 #define CLOCK_REALTIME_HR	 4
 #define CLOCK_MONOTONIC_HR	  5

-#define MAX_CLOCKS 6
+/*
+ * The IDs of various hardware clocks
+ */
+
+
+#define MAX_CLOCKS 16
 #define CLOCKS_MASK  (CLOCK_REALTIME | CLOCK_MONOTONIC | \
                      CLOCK_REALTIME_HR | CLOCK_MONOTONIC_HR)
 #define CLOCKS_MONO (CLOCK_MONOTONIC & CLOCK_MONOTONIC_HR)

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Posix compliant cpu clocks V6 [2/3]: Glibc patch
       [not found]                   ` <B6E8046E1E28D34EB815A11AC8CA31290322B307@mtv-atc-605e--n.corp.sgi.com>
  2004-10-01 19:59                     ` Posix compliant cpu clocks V6 [1/3]: Generic Kernel patch Christoph Lameter
@ 2004-10-01 20:01                     ` Christoph Lameter
  2004-10-02  5:32                       ` Ulrich Drepper
  2004-10-01 20:02                     ` Posix compliant cpu clocks V6 [3/3]: mmtimer provides CLOCK_SGI_CYCLE Christoph Lameter
                                       ` (2 subsequent siblings)
  4 siblings, 1 reply; 57+ messages in thread
From: Christoph Lameter @ 2004-10-01 20:01 UTC (permalink / raw)
  To: George Anzinger
  Cc: Ulrich Drepper, johnstul, Ulrich.Windl, jbarnes, akpm,
	linux-kernel, libc-alpha

The following patch makes glibc not provide the above clocks and use the
kernel clocks instead if either of the following condition is met:

1. __ASSUME_POSIX_TIMERS is set

2. A call to probe the posix function is made if the corresponding
   __NR_clock_* is defined. If the call is successful then the kernel clocks
   will be used. Otherwise glibc will fall back to its own implementation of
   the clocks.

The clock_gettime clock_settime and clock_res calls will use the corresponding
system calls for other clocks than CLOCK_REALTIME, CLOCK_MONOTONIC,
CLOCK_THREAD_CPUTIME_ID and CLOCK_PROCESS_CPUTIME_ID.

Patch needs some additional testing....

Signed-off-by: Christoph Lameter <clameter@sgi.com>

Index: libc/sysdeps/unix/sysv/linux/clock_gettime.c
===================================================================
--- libc.orig/sysdeps/unix/sysv/linux/clock_gettime.c	2004-09-28 15:22:02.359949008 -0700
+++ libc/sysdeps/unix/sysv/linux/clock_gettime.c	2004-10-01 08:57:51.025894976 -0700
@@ -16,61 +16,174 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */

+#include <errno.h>
+#include <stdint.h>
+#include <time.h>
+#include <sys/time.h>
+#include <libc-internal.h>
 #include <sysdep.h>
+#include <ldsodefs.h>

 #include "kernel-features.h"


 #ifdef __ASSUME_POSIX_TIMERS
-/* This means the REALTIME and MONOTONIC clock are definitely
-   supported in the kernel.  */
-# define SYSDEP_GETTIME \
-  case CLOCK_REALTIME:							      \
-  case CLOCK_MONOTONIC:							      \
-    retval = INLINE_SYSCALL (clock_gettime, 2, clock_id, tp);		      \
-    break
-#elif defined __NR_clock_gettime
-/* Is the syscall known to exist?  */
-int __libc_missing_posix_timers attribute_hidden;
-
-/* The REALTIME and MONOTONIC clock might be available.  Try the
-   syscall first.  */
-# define SYSDEP_GETTIME \
-  case CLOCK_REALTIME:							      \
-  case CLOCK_MONOTONIC:							      \
-    {									      \
-      int e = EINVAL;							      \
-									      \
-      if (!__libc_missing_posix_timers)					      \
-	{								      \
-	  INTERNAL_SYSCALL_DECL (err);					      \
-	  int r = INTERNAL_SYSCALL (clock_gettime, err, 2, clock_id, tp);     \
-	  if (!INTERNAL_SYSCALL_ERROR_P (r, err))			      \
-	    {								      \
-	      retval = 0;						      \
-	      break;							      \
-	    }								      \
-									      \
-	  e = INTERNAL_SYSCALL_ERRNO (r, err);				      \
-	  if (e == ENOSYS)						      \
-	    {								      \
-	      __libc_missing_posix_timers = 1;				      \
-	      e = EINVAL;						      \
-	    }								      \
-	}								      \
-									      \
-      /* Fallback code.  */						      \
-      if (e == EINVAL && clock_id == CLOCK_REALTIME)			      \
-	HANDLE_REALTIME;						      \
-      else								      \
-	__set_errno (e);						      \
-    }									      \
-    break
+/* This means all clocks are definitely supported in the kernel.  */
+int
+clock_gettime (clockid_t clock_id, struct timespec *tp)
+{
+  INTERNAL_SYSCALL_DECL (err);
+  int r = INTERNAL_SYSCALL (clock_gettime, err, 2, clock_id, tp);
+  if (!INTERNAL_SYSCALL_ERROR_P (r, err))
+    return 0;
+  return -1;
+}
+
+#else
+
+/*
+ * Need to deal with multiple complex fallback and legacy scenarios
+ *
+ * Give priority to the clock_gettime syscall but fall back if
+ * certain clocks are not available
+ * for CLOCK_REALTIME fall back to gettimeofday
+ * for CLOCK_PROCESS_CPUTIME_ID fall back to HP_TIMING
+ * for CLOCK_THREAD_CPUTIME_ID fall back to pthreads
+ */
+
+int __libc_missing_posix_stdtimers attribute_hidden;
+int __libc_missing_posix_cputimers attribute_hidden;
+
+int
+clock_gettime (clockid_t clock_id, struct timespec *tp)
+{
+  int retval = -1;
+
+  switch (clock_id)
+    {
+#if defined __NR_clock_gettime
+    case CLOCK_REALTIME: case CLOCK_MONOTONIC:
+      {
+	int e = EINVAL;
+
+	if (!__libc_missing_posix_stdtimers)
+	{
+	  INTERNAL_SYSCALL_DECL (err);
+	  int r = INTERNAL_SYSCALL (clock_gettime, err, 2, clock_id, tp);
+	  if (!INTERNAL_SYSCALL_ERROR_P (r, err))
+	    {
+	      retval = 0;
+	      break;
+	    }
+
+	  e = INTERNAL_SYSCALL_ERRNO (r, err);
+	  if (e == ENOSYS)
+	    {
+	      __libc_missing_posix_stdtimers = 1;
+	      e = EINVAL;
+	    }
+	}
+
+        /* Fallback code.  */
+        if (e != EINVAL || clock_id != CLOCK_REALTIME)
+        {
+	   __set_errno (e);
+	   break;
+         }
+      }
+      /* Fall through */
+#else
+    case CLOCK_REALTIME:
 #endif
+      struct timeval tv;
+      retval = gettimeofday (&tv, NULL);
+      if (retval == 0)
+        /* Convert into `timespec'.  */
+        TIMEVAL_TO_TIMESPEC (&tv, tp);
+      break;
+
+    case CLOCK_PROCESS_CPUTIME_ID: case CLOCK_THREAD_CPUTIME_ID:
+#if defined __NR_clock_gettime
+      if (!__libc_missing_posix_cputimers)
+	{
+	  INTERNAL_SYSCALL_DECL (err);
+	  int r = INTERNAL_SYSCALL (clock_gettime, err, 2, clock_id, tp);
+	  if (!INTERNAL_SYSCALL_ERROR_P (r, err))
+	    {
+	      retval = 0;
+	      break;
+	    }
+
+	  if (INTERNAL_SYSCALL_ERRNO (r, err) == ENOSYS)
+	      __libc_missing_posix_cputimers = 1;
+	}
+
+#if HP_TIMING_AVAIL
+      /* Fallback code.  */
+      {
+/* Clock frequency of the processor.  We make it a 64-bit variable
+   because some jokers are already playing with processors with more
+   than 4GHz.  */
+static hp_timing_t freq;
+
+
+/* This function is defined in the thread library.  */
+extern int __pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq,
+				    struct timespec *tp)
+     __attribute__ ((__weak__));
+
+	hp_timing_t tsc;
+
+	if (__builtin_expect (freq == 0, 0))
+	  {
+	    /* This can only happen if we haven't initialized the `freq'
+	       variable yet.  Do this now. We don't have to protect this
+	       code against multiple execution since all of them should
+	       lead to the same result.  */
+	    freq = __get_clockfreq ();
+	    if (__builtin_expect (freq == 0, 0))
+	      /* Something went wrong.  */
+	      break;
+	  }
+
+	if (clock_id != CLOCK_PROCESS_CPUTIME_ID
+	    && __pthread_clock_gettime != NULL)
+	  {
+	    retval = __pthread_clock_gettime (clock_id, freq, tp);
+	    break;
+	  }
+
+	/* Get the current counter.  */
+	HP_TIMING_NOW (tsc);
+
+	/* Compute the offset since the start time of the process.  */
+	tsc -= GL(dl_cpuclock_offset);
+
+	/* Compute the seconds.  */
+	tp->tv_sec = tsc / freq;
+
+	/* And the nanoseconds.  This computation should be stable until
+	   we get machines with about 16GHz frequency.  */
+	tp->tv_nsec = ((tsc % freq) * UINT64_C (1000000000)) / freq;
+
+	retval = 0;
+      }
+#endif
+#endif
+      break;
+
+    default:
+#if defined __NR_clock_gettime
+      INTERNAL_SYSCALL_DECL (err);
+      int r = INTERNAL_SYSCALL (clock_gettime, err, 2, clock_id, tp);
+      if (!INTERNAL_SYSCALL_ERROR_P (r, err))
+        retval = 0;
+#else
+      __set_errno(EINVAL);
+#endif
+    }
+    return retval;
+}

-#ifdef __NR_clock_gettime
-/* We handled the REALTIME clock here.  */
-# define HANDLED_REALTIME	1
 #endif

-#include <sysdeps/unix/clock_gettime.c>
Index: libc/sysdeps/unix/sysv/linux/clock_settime.c
===================================================================
--- libc.orig/sysdeps/unix/sysv/linux/clock_settime.c	2004-10-01 10:27:15.007445832 -0700
+++ libc/sysdeps/unix/sysv/linux/clock_settime.c	2004-10-01 11:09:40.938405496 -0700
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.

    The GNU C Library is free software; you can redistribute it and/or
@@ -16,61 +16,160 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */

-#include <sysdep.h>
-
+#include <errno.h>
+#include <time.h>
+#include <sys/time.h>
+#include <libc-internal.h>
+#include <ldsodefs.h>
 #include "kernel-features.h"

-
 #ifdef __ASSUME_POSIX_TIMERS
-/* This means the REALTIME clock is definitely supported in the
-   kernel.  */
-# define SYSDEP_SETTIME \
-  case CLOCK_REALTIME:							      \
-    retval = INLINE_SYSCALL (clock_settime, 2, clock_id, tp);		      \
-    break
-#elif defined __NR_clock_settime
-/* Is the syscall known to exist?  */
-extern int __libc_missing_posix_timers attribute_hidden;
-
-/* The REALTIME clock might be available.  Try the syscall first.  */
-# define SYSDEP_SETTIME \
-  case CLOCK_REALTIME:							      \
-    {									      \
-      int e = EINVAL;							      \
-									      \
-      if (!__libc_missing_posix_timers)					      \
-	{								      \
-	  INTERNAL_SYSCALL_DECL (err);					      \
-	  int r = INTERNAL_SYSCALL (clock_settime, err, 2, clock_id, tp);     \
-	  if (!INTERNAL_SYSCALL_ERROR_P (r, err))			      \
-	    {								      \
-	      retval = 0;						      \
-	      break;							      \
-	    }								      \
-									      \
-	  e = INTERNAL_SYSCALL_ERRNO (r, err);				      \
-	  if (e == ENOSYS)						      \
-	    {								      \
-	      __libc_missing_posix_timers = 1;				      \
-	      e = EINVAL;						      \
-	    }								      \
-	}								      \
-									      \
-      /* Fallback code.  */						      \
-      if (e == EINVAL && clock_id == CLOCK_REALTIME)			      \
-	HANDLE_REALTIME;						      \
-      else								      \
-	{								      \
-	  __set_errno (e);						      \
-	  retval = -1;							      \
-	}								      \
-    }									      \
-    break
+/* This means all clocks are definitely supported in the kernel.  */
+int
+clock_settime (clockid_t clock_id, struct timespec *tp)
+{
+	  INTERNAL_SYSCALL_DECL (err);
+	    int r = INTERNAL_SYSCALL (clock_settime, err, 2, clock_id, tp);
+	      if (!INTERNAL_SYSCALL_ERROR_P (r, err))
+		          return 0;
+	        return -1;
+}
+
+#else
+/*
+ * Need to deal with multiple complex fallback and legacy scenarios
+ *
+ * Give priority to the clock_gettime syscall but fall back if
+ * certain clocks are not available
+ * for CLOCK_REALTIME fall back to gettimeofday
+ * for CLOCK_PROCESS_CPUTIME_ID fall back to HP_TIMING
+ * for CLOCK_THREAD_CPUTIME_ID fall back to pthreads
+ */
+
+int __libc_missing_posix_stdtimers attribute_hidden;
+int __libc_missing_posix_cputimers attribute_hidden;
+
+int
+clock_settime (clockid_t clock_id,const struct timespec *tp)
+{
+  int retval = -1;
+
+  switch (clock_id)
+    {
+#if defined __NR_clock_gettime
+    case CLOCK_REALTIME: case CLOCK_MONOTONIC:
+      {
+        int e = EINVAL;
+
+        if (!__libc_missing_posix_stdtimers)
+        {
+          INTERNAL_SYSCALL_DECL (err);
+          int r = INTERNAL_SYSCALL (clock_settime, err, 2, clock_id, tp);
+          if (!INTERNAL_SYSCALL_ERROR_P (r, err))
+            {
+              retval = 0;
+              break;
+            }
+
+          e = INTERNAL_SYSCALL_ERRNO (r, err);
+          if (e == ENOSYS)
+            {
+              __libc_missing_posix_stdtimers = 1;
+              e = EINVAL;
+            }
+        }
+
+        /* Fallback code.  */
+        if (e != EINVAL || clock_id != CLOCK_REALTIME)
+        {
+           __set_errno (e);
+           break;
+         }
+      }
+      /* Fall through */
+#else
+    case CLOCK_REALTIME:
+#endif
+      struct timeval tv;
+      TIMESPEC_TO_TIMEVAL (&tv, tp);
+      retval = settimeofday (&tv, NULL);
+      break;
+
+    case CLOCK_PROCESS_CPUTIME_ID: case CLOCK_THREAD_CPUTIME_ID:
+#if defined __NR_clock_gettime
+      if (!__libc_missing_posix_cputimers)
+        {
+          INTERNAL_SYSCALL_DECL (err);
+          int r = INTERNAL_SYSCALL (clock_settime, err, 2, clock_id, tp);
+          if (!INTERNAL_SYSCALL_ERROR_P (r, err))
+            {
+              retval = 0;
+              break;
+            }
+
+          if (INTERNAL_SYSCALL_ERRNO (r, err) == ENOSYS)
+              __libc_missing_posix_cputimers = 1;
+        }
+
+#if HP_TIMING_AVAIL
+      /* Fallback code.  */
+      {
+/* Clock frequency of the processor.  We make it a 64-bit variable
+   because some jokers are already playing with processors with more
+   than 4GHz.  */
+static hp_timing_t freq;
+
+
+/* This function is defined in the thread library.  */
+extern int __pthread_clock_settime (clockid_t clock_id, hp_timing_t offset)
+     __attribute__ ((__weak__));
+
+        hp_timing_t tsc;
+	hp_timing_t usertime;
+
+        if (__builtin_expect (freq == 0, 0))
+          {
+            /* This can only happen if we haven't initialized the `freq'
+               variable yet.  Do this now. We don't have to protect this
+               code against multiple execution since all of them should
+               lead to the same result.  */
+            freq = __get_clockfreq ();
+            if (__builtin_expect (freq == 0, 0))
+              /* Something went wrong.  */
+              break;
+          }
+
+	/* Get the current counter.  */
+        HP_TIMING_NOW (tsc);
+
+	/* Convert the user-provided time into CPU ticks.  */
+	usertime = tp->tv_sec * freq + (tp->tv_nsec * freq) / 1000000000ull;
+
+	/* Determine the offset and use it as the new base value.  */
+	if (clock_id == CLOCK_PROCESS_CPUTIME_ID
+	    || __pthread_clock_settime == NULL)
+	  GL(dl_cpuclock_offset) = tsc - usertime;
+	else
+	  __pthread_clock_settime (clock_id, tsc - usertime);
+
+	retval = 0;
+      }
+#endif
+#endif
+      break;
+
+    default:
+#if defined __NR_clock_gettime
+      INTERNAL_SYSCALL_DECL (err);
+      int r = INTERNAL_SYSCALL (clock_gettime, err, 2, clock_id, tp);
+      if (!INTERNAL_SYSCALL_ERROR_P (r, err))
+        retval = 0;
+#else
+      __set_errno(EINVAL);
 #endif
+    }
+    return retval;
+}

-#ifdef __NR_clock_settime
-/* We handled the REALTIME clock here.  */
-# define HANDLED_REALTIME	1
 #endif

-#include <sysdeps/unix/clock_settime.c>
Index: libc/sysdeps/unix/sysv/linux/clock_getres.c
===================================================================
--- libc.orig/sysdeps/unix/sysv/linux/clock_getres.c	2004-09-28 15:22:02.351950224 -0700
+++ libc/sysdeps/unix/sysv/linux/clock_getres.c	2004-10-01 12:23:50.099030272 -0700
@@ -16,61 +16,159 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */

+#include <errno.h>
+#include <stdint.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <libc-internal.h>
 #include <sysdep.h>
+#include <ldsodefs.h>

 #include "kernel-features.h"


 #ifdef __ASSUME_POSIX_TIMERS
-/* This means the REALTIME and MONOTONIC clock are definitely
-   supported in the kernel.  */
-# define SYSDEP_GETRES \
-  case CLOCK_REALTIME:							      \
-  case CLOCK_MONOTONIC:							      \
-    retval = INLINE_SYSCALL (clock_getres, 2, clock_id, res);		      \
-    break
-#elif defined __NR_clock_getres
-/* Is the syscall known to exist?  */
-extern int __libc_missing_posix_timers attribute_hidden;
-
-/* The REALTIME and MONOTONIC clock might be available.  Try the
-   syscall first.  */
-# define SYSDEP_GETRES \
-  case CLOCK_REALTIME:							      \
-  case CLOCK_MONOTONIC:							      \
-    {									      \
-      int e = EINVAL;							      \
-									      \
-      if (!__libc_missing_posix_timers)					      \
-	{								      \
-	  INTERNAL_SYSCALL_DECL (err);					      \
-	  int r = INTERNAL_SYSCALL (clock_getres, err, 2, clock_id, res);     \
-	  if (!INTERNAL_SYSCALL_ERROR_P (r, err))			      \
-	    {								      \
-	      retval = 0;						      \
-	      break;							      \
-	    }								      \
-									      \
-	  e = INTERNAL_SYSCALL_ERRNO (r, err);				      \
-	  if (e == ENOSYS)						      \
-	    {								      \
-	      __libc_missing_posix_timers = 1;				      \
-	      e = EINVAL;						      \
-	    }								      \
-	}								      \
-									      \
-      /* Fallback code.  */						      \
-      if (e == EINVAL && clock_id == CLOCK_REALTIME)			      \
-	HANDLE_REALTIME;						      \
-      else								      \
-	__set_errno (e);						      \
-    }									      \
-    break
+/* This means all clocks are definitely supported in the kernel.  */
+int
+clock_getres (clockid_t clock_id, struct timespec *res)
+{
+  INTERNAL_SYSCALL_DECL (err);
+  int r = INTERNAL_SYSCALL (clock_getres, err, 2, clock_id, res);
+  if (!INTERNAL_SYSCALL_ERROR_P (r, err))
+    return 0;
+  return -1;
+}
+
+#else
+
+/*
+ * Need to deal with multiple complex fallback and legacy scenarios
+ *
+ * Give priority to the clock_gettime syscall but fall back if
+ * certain clocks are not available
+ * for CLOCK_REALTIME fall back to gettimeofday
+ * for CLOCK_PROCESS_CPUTIME_ID fall back to HP_TIMING
+ * for CLOCK_THREAD_CPUTIME_ID fall back to pthreads
+ */
+
+int __libc_missing_posix_stdtimers attribute_hidden;
+int __libc_missing_posix_cputimers attribute_hidden;
+
+int
+clock_getres (clockid_t clock_id, struct timespec *res)
+{
+  int retval = -1;
+
+  switch (clock_id)
+    {
+#if defined __NR_clock_gettime
+    case CLOCK_REALTIME: case CLOCK_MONOTONIC:
+      {
+	int e = EINVAL;
+
+	if (!__libc_missing_posix_stdtimers)
+	{
+	  INTERNAL_SYSCALL_DECL (err);
+	  int r = INTERNAL_SYSCALL (clock_getres, err, 2, clock_id, res);
+	  if (!INTERNAL_SYSCALL_ERROR_P (r, err))
+	    {
+	      retval = 0;
+	      break;
+	    }
+
+	  e = INTERNAL_SYSCALL_ERRNO (r, err);
+	  if (e == ENOSYS)
+	    {
+	      __libc_missing_posix_stdtimers = 1;
+	      e = EINVAL;
+	    }
+	}
+
+        /* Fallback code.  */
+        if (e != EINVAL || clock_id != CLOCK_REALTIME)
+        {
+	   __set_errno (e);
+	   break;
+         }
+      }
+      /* Fall through */
+#else
+    case CLOCK_REALTIME:
 #endif
+    {
+      long int clk_tck = sysconf (_SC_CLK_TCK);
+
+      if (__builtin_expect (clk_tck != -1, 1))
+      {
+        /* This implementation assumes that the realtime clock has a
+           resolution higher than 1 second.  This is the case for any
+           reasonable implementation.  */
+        res->tv_sec = 0;
+        res->tv_nsec = 1000000000 / clk_tck;
+
+        retval = 0;
+      }
+    }
+    break;
+
+    case CLOCK_PROCESS_CPUTIME_ID: case CLOCK_THREAD_CPUTIME_ID:
+#if defined __NR_clock_gettime
+      if (!__libc_missing_posix_cputimers)
+	{
+	  INTERNAL_SYSCALL_DECL (err);
+	  int r = INTERNAL_SYSCALL (clock_getres, err, 2, clock_id, res);
+	  if (!INTERNAL_SYSCALL_ERROR_P (r, err))
+	    {
+	      retval = 0;
+	      break;
+	    }
+
+	  if (INTERNAL_SYSCALL_ERRNO (r, err) == ENOSYS)
+	      __libc_missing_posix_cputimers = 1;
+	}
+
+#if HP_TIMING_AVAIL
+      /* Fallback code.  */
+      static long int nsec;
+      {
+	if (__builtin_expect (nsec == 0, 0))
+	  {
+	    hp_timing_t freq;
+
+	    /* This can only happen if we haven't initialized the `freq'
+	       variable yet.  Do this now. We don't have to protect this
+	       code against multiple execution since all of them should
+	       lead to the same result.  */
+	    freq = __get_clockfreq ();
+	    if (__builtin_expect (freq == 0, 0))
+	      /* Something went wrong.  */
+	      break;
+	    nsec = MAX (UINT64_C (1000000000) / freq, 1);
+	  }
+        /* File in the values.  The seconds are always zero (unless we
+           have a 1Hz machine).  */
+        res->tv_sec = 0;
+        res->tv_nsec = nsec;
+
+	retval = 0;
+      }
+#endif
+#endif
+      break;
+
+    default:
+#if defined __NR_clock_gettime
+      INTERNAL_SYSCALL_DECL (err);
+      int r = INTERNAL_SYSCALL (clock_getres, err, 2, clock_id, res);
+      if (!INTERNAL_SYSCALL_ERROR_P (r, err))
+        retval = 0;
+#else
+      __set_errno(EINVAL);
+#endif
+    }
+    return retval;
+}

-#ifdef __NR_clock_getres
-/* We handled the REALTIME clock here.  */
-# define HANDLED_REALTIME	1
 #endif

-#include <sysdeps/posix/clock_getres.c>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Posix compliant cpu clocks V6 [3/3]: mmtimer provides CLOCK_SGI_CYCLE
       [not found]                   ` <B6E8046E1E28D34EB815A11AC8CA31290322B307@mtv-atc-605e--n.corp.sgi.com>
  2004-10-01 19:59                     ` Posix compliant cpu clocks V6 [1/3]: Generic Kernel patch Christoph Lameter
  2004-10-01 20:01                     ` Posix compliant cpu clocks V6 [2/3]: Glibc patch Christoph Lameter
@ 2004-10-01 20:02                     ` Christoph Lameter
  2004-10-07  4:56                     ` Posix compliant cpu clocks V7 [0/2]: Rationale and test program Christoph Lameter
       [not found]                     ` <B6E8046E1E28D34EB815A11AC8CA31290322B331@mtv-atc-605e--n.corp.sgi.com>
  4 siblings, 0 replies; 57+ messages in thread
From: Christoph Lameter @ 2004-10-01 20:02 UTC (permalink / raw)
  To: George Anzinger
  Cc: Ulrich Drepper, johnstul, Ulrich.Windl, jbarnes, akpm,
	linux-kernel, libc-alpha

Changelog:
	* Add CLOCK_SGI_CYCLE provided by drivers/char/mmtimer

Index: linux-2.6.9-rc3/include/linux/time.h
===================================================================
--- linux-2.6.9-rc3.orig/include/linux/time.h	2004-10-01 08:40:30.000000000 -0700
+++ linux-2.6.9-rc3/include/linux/time.h	2004-10-01 09:09:28.000000000 -0700
@@ -416,7 +416,7 @@
 /*
  * The IDs of various hardware clocks
  */
-
+#define CLOCK_SGI_CYCLE 10

 #define MAX_CLOCKS 16
 #define CLOCKS_MASK  (CLOCK_REALTIME | CLOCK_MONOTONIC | \
Index: linux-2.6.9-rc3/drivers/char/mmtimer.c
===================================================================
--- linux-2.6.9-rc3.orig/drivers/char/mmtimer.c	2004-09-29 20:05:19.000000000 -0700
+++ linux-2.6.9-rc3/drivers/char/mmtimer.c	2004-10-01 10:07:11.000000000 -0700
@@ -28,6 +28,7 @@
 #include <asm/uaccess.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/clksupport.h>
+#include <linux/posix-timers.h>

 MODULE_AUTHOR("Jesse Barnes <jbarnes@sgi.com>");
 MODULE_DESCRIPTION("Multimedia timer support");
@@ -177,6 +178,45 @@
 	&mmtimer_fops
 };

+static struct timespec sgi_clock_offset;
+static int sgi_clock_period;
+
+static int sgi_clock_get(struct timespec *tp) {
+	u64 nsec;
+
+	nsec = readq(RTC_COUNTER_ADDR) * sgi_clock_period
+			+ sgi_clock_offset.tv_nsec;
+	tp->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &tp->tv_nsec)
+			+ sgi_clock_offset.tv_sec;
+	return 0;
+};
+
+static int sgi_clock_set(struct timespec *tp) {
+
+	u64 nsec;
+	u64 rem;
+
+	nsec = readq(RTC_COUNTER_ADDR) * sgi_clock_period;
+
+	sgi_clock_offset.tv_sec = tp->tv_sec - div_long_long_rem(nsec, NSEC_PER_SEC, &rem);
+
+	if (rem <= tp->tv_nsec)
+		sgi_clock_offset.tv_nsec = tp->tv_sec - rem;
+	else {
+		sgi_clock_offset.tv_nsec = tp->tv_sec + NSEC_PER_SEC - rem;
+		sgi_clock_offset.tv_sec--;
+	}
+	return 0;
+}
+
+static struct k_clock sgi_clock = {
+	.res = 0,
+	.clock_set = sgi_clock_set,
+	.clock_get = sgi_clock_get,
+	.timer_create = do_posix_clock_notimer_create,
+	.nsleep = do_posix_clock_nonanosleep
+};
+
 /**
  * mmtimer_init - device initialization routine
  *
@@ -206,6 +246,9 @@
 		return -1;
 	}

+	sgi_clock_period = sgi_clock.res = NSEC_PER_SEC / sn_rtc_cycles_per_second;
+	register_posix_clock(CLOCK_SGI_CYCLE, &sgi_clock);
+
 	printk(KERN_INFO "%s: v%s, %ld MHz\n", MMTIMER_DESC, MMTIMER_VERSION,
 	       sn_rtc_cycles_per_second/(unsigned long)1E6);


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Posix compliant cpu clocks V6 [1/3]: Generic Kernel patch
  2004-10-01 19:59                     ` Posix compliant cpu clocks V6 [1/3]: Generic Kernel patch Christoph Lameter
@ 2004-10-01 21:03                       ` Andrew Morton
  0 siblings, 0 replies; 57+ messages in thread
From: Andrew Morton @ 2004-10-01 21:03 UTC (permalink / raw)
  To: Christoph Lameter
  Cc: george, drepper, johnstul, Ulrich.Windl, jbarnes, linux-kernel,
	libc-alpha

Christoph Lameter <clameter@sgi.com> wrote:
>
> --- linux-2.6.9-rc3.orig/kernel/posix-timers.c	2004-09-29 20:04:47.000000000 -0700
> +++ linux-2.6.9-rc3/kernel/posix-timers.c	2004-10-01 12:48:55.000000000 -0700
> ...
> +int do_posix_clock_notimer_create(int which_clock,
> +		struct sigevent __user *time_event_spec,
> +		timer_t __user *created_timer_id);
> +int do_posix_clock_nonanosleep(int which_clock, int flags, struct timespec * t);

These guys are already declared in posix-timers.h.

I'll fix that up, queue the patch up.


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [RFC] Posix compliant behavior of CLOCK_PROCESS/THREAD_CPUTIME_ID
  2004-09-27 20:58           ` [RFC] Posix compliant behavior of CLOCK_PROCESS/THREAD_CPUTIME_ID Christoph Lameter
  2004-09-27 22:54             ` George Anzinger
  2004-09-28 19:18             ` Ulrich Drepper
@ 2004-10-01 21:57             ` Roland McGrath
  2004-10-01 23:30               ` Christoph Lameter
  2004-10-04 18:48               ` RFC: Posix compliant clock_getclockcpuid(pid) to access other processes clocks Christoph Lameter
  2 siblings, 2 replies; 57+ messages in thread
From: Roland McGrath @ 2004-10-01 21:57 UTC (permalink / raw)
  To: Christoph Lameter
  Cc: Ulrich Drepper, johnstul, Ulrich.Windl, george, linux-kernel, libc-alpha

Sorry I haven't replied sooner.  I don't think the facility offered by your
patch is enough by itself to be worth doing.  That information about a
process is already available to itself via getrusage/times, though those
don't offer a per-thread sample.  

I have been working on an alternate patch that implements more complete CPU
clock functionality.  This includes access to other threads' and process'
times, potentially finer-grained information (based on sched_clock), and
timers.  I will post this code when it's ready, hopefully soon.

As to supporting clock_settime, I think that is just plain not desireable.
I am not aware of any actual demand for it, and POSIX certainly does not
require that it be permitted.  It's certainly undesireable to let a process
reset its actual totals as reported by getrusage, process accounting, etc.;
I gather your later revisions have at least avoided that pitfall.  But I
don't really see the utility in letting applications use clock_settime on
their CPU clocks either.  They can just save the starting value at the time
they would use clock_settime to reset it to zero, and compute the delta later.



Thanks,
Roland

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: patches inline in mail
  2004-10-01 12:28                             ` Alan Cox
  2004-10-01 13:42                               ` Paul Fulghum
@ 2004-10-01 21:58                               ` George Anzinger
  2004-10-02 15:52                                 ` Olaf Dietsche
  1 sibling, 1 reply; 57+ messages in thread
From: George Anzinger @ 2004-10-01 21:58 UTC (permalink / raw)
  To: Alan Cox
  Cc: Andrew Morton, juhl-lkml, clameter, drepper, johnstul,
	Ulrich.Windl, jbarnes, Linux Kernel Mailing List, libc-alpha

Alan Cox wrote:
> On Gwe, 2004-10-01 at 06:29, Andrew Morton wrote:
> 
>>> Guild lines on how to insure this are welcome.
>>
>>Send angry email to everyone@mozilla.org.  AFAICT it's impossible with
>>recent mailnews.
> 
> 
> The mozilla behaviour is RFC compliant[1]. Use text/plain attachments
> and mark them "to view" and it should do happier things. (Except with
> Linus cos Mr Dinosaur[2] doesn't believe in MIME yet)

Just how does one "mark them "to view" "?

George
> 
> I've not been able to coax Evolution into not chewing on non attached
> text either (again RFC compliant but not useful). If anyone knows a
> magic incantation for it I'd love to know.
> 
> (and it might be a good addition to the lkml faq)
> 
> Alan
> [1] Yes the RFC is stupid but its the spec nowdays
> [2] Thankfully not purple and singing
> 
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 

-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [RFC] Posix compliant behavior of CLOCK_PROCESS/THREAD_CPUTIME_ID
  2004-10-01 21:57             ` [RFC] Posix compliant behavior of CLOCK_PROCESS/THREAD_CPUTIME_ID Roland McGrath
@ 2004-10-01 23:30               ` Christoph Lameter
  2004-10-04 18:48               ` RFC: Posix compliant clock_getclockcpuid(pid) to access other processes clocks Christoph Lameter
  1 sibling, 0 replies; 57+ messages in thread
From: Christoph Lameter @ 2004-10-01 23:30 UTC (permalink / raw)
  To: Roland McGrath
  Cc: Ulrich Drepper, johnstul, Ulrich.Windl, george, linux-kernel, libc-alpha

On Fri, 1 Oct 2004, Roland McGrath wrote:

> I have been working on an alternate patch that implements more complete CPU
> clock functionality.  This includes access to other threads' and process'
> times, potentially finer-grained information (based on sched_clock), and
> timers.  I will post this code when it's ready, hopefully soon.

Umm... How would you do that in a posix compliant way? This information is
already available via /proc


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Posix compliant cpu clocks V6 [2/3]: Glibc patch
  2004-10-01 20:01                     ` Posix compliant cpu clocks V6 [2/3]: Glibc patch Christoph Lameter
@ 2004-10-02  5:32                       ` Ulrich Drepper
  2004-10-04 15:04                         ` Christoph Lameter
                                           ` (2 more replies)
  0 siblings, 3 replies; 57+ messages in thread
From: Ulrich Drepper @ 2004-10-02  5:32 UTC (permalink / raw)
  To: Christoph Lameter
  Cc: George Anzinger, johnstul, Ulrich.Windl, jbarnes, akpm,
	linux-kernel, libc-alpha

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Christoph Lameter wrote:
> The following patch makes glibc not provide the above clocks and use the
> kernel clocks instead if either of the following condition is met:

Did you ever hear about a concept called binary compatiblity?  Don't
bother working on any glibc patch.

- --
➧ Ulrich Drepper ➧ Red Hat, Inc. ➧ 444 Castro St ➧ Mountain View, CA ❖
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)

iD8DBQFBXj1a2ijCOnn/RHQRAh31AJ9rZ5+i5x3LkTwEbeMj2DY/uBzPjwCfeAip
zTYpRJb0lfsR5POro22uViM=
=aUP/
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: patches inline in mail
  2004-10-02 15:52                                 ` Olaf Dietsche
@ 2004-10-02 15:20                                   ` Alan Cox
  2004-10-03 21:01                                     ` [OT] " Guennadi Liakhovetski
  2004-10-03 21:35                                     ` George Anzinger
  0 siblings, 2 replies; 57+ messages in thread
From: Alan Cox @ 2004-10-02 15:20 UTC (permalink / raw)
  To: Olaf Dietsche
  Cc: george, Andrew Morton, juhl-lkml, clameter, drepper, johnstul,
	Ulrich.Windl, jbarnes, Linux Kernel Mailing List, libc-alpha

On Sad, 2004-10-02 at 16:52, Olaf Dietsche wrote:
> I don't know how to do this with mozilla, but I suppose it's:
> "Content-Disposition: inline"
> 
> RFC 2183 <ftp://ftp.rfc-editor.org/in-notes/rfc2183.txt>

Yep - that worked 8)

Evolution has an option on attachments for this


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: patches inline in mail
  2004-10-01 21:58                               ` George Anzinger
@ 2004-10-02 15:52                                 ` Olaf Dietsche
  2004-10-02 15:20                                   ` Alan Cox
  0 siblings, 1 reply; 57+ messages in thread
From: Olaf Dietsche @ 2004-10-02 15:52 UTC (permalink / raw)
  To: george
  Cc: Alan Cox, Andrew Morton, juhl-lkml, clameter, drepper, johnstul,
	Ulrich.Windl, jbarnes, Linux Kernel Mailing List, libc-alpha

[-- Attachment #1: Type: text/plain, Size: 536 bytes --]

George Anzinger <george@mvista.com> writes:

> Alan Cox wrote:
>> The mozilla behaviour is RFC compliant[1]. Use text/plain attachments
>> and mark them "to view" and it should do happier things. (Except with
>> Linus cos Mr Dinosaur[2] doesn't believe in MIME yet)
>
> Just how does one "mark them "to view" "?

I don't know how to do this with mozilla, but I suppose it's:
"Content-Disposition: inline"

RFC 2183 <ftp://ftp.rfc-editor.org/in-notes/rfc2183.txt>

See:
2.1  The Inline Disposition Type
and
3.  Examples

Regards, Olaf.


[-- Attachment #2: Attachment test --]
[-- Type: text/plain, Size: 28 bytes --]

This is an attachment test.

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [OT] Re: patches inline in mail
  2004-10-02 15:20                                   ` Alan Cox
@ 2004-10-03 21:01                                     ` Guennadi Liakhovetski
  2004-10-03 23:18                                       ` Jesper Juhl
                                                         ` (2 more replies)
  2004-10-03 21:35                                     ` George Anzinger
  1 sibling, 3 replies; 57+ messages in thread
From: Guennadi Liakhovetski @ 2004-10-03 21:01 UTC (permalink / raw)
  To: Alan Cox
  Cc: Olaf Dietsche, george, Andrew Morton, juhl-lkml, clameter,
	drepper, johnstul, Ulrich.Windl, jbarnes,
	Linux Kernel Mailing List, libc-alpha

Hello

While we are at it, maybe someone could help me with my "antient" pine 
too. When sending patches inline (Ctrl-R) it looks fine up in the email, 
also when I am reading my own email as it came to the list, e.g.

@@ -8,9 +8,9 @@
  static void __inline__
  dc390_freetag (struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
  {
-	if (pSRB->TagNumber < 255) {

However, everybody (not pine-users) complains, that white spaces got 
corrupted. And if I export the email I see

@@ -8,9 +8,9 @@
   static void __inline__
   dc390_freetag (struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
   {
-	if (pSRB->TagNumber < 255) {

(notice the extra space). What is going on there and is there a solution 
(apart from switching to another mailing or sending as attachments)?

Thanks
Guennadi
---
Guennadi Liakhovetski


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: patches inline in mail
  2004-10-02 15:20                                   ` Alan Cox
  2004-10-03 21:01                                     ` [OT] " Guennadi Liakhovetski
@ 2004-10-03 21:35                                     ` George Anzinger
  2004-10-04  3:00                                       ` Jim Nelson
  1 sibling, 1 reply; 57+ messages in thread
From: George Anzinger @ 2004-10-03 21:35 UTC (permalink / raw)
  To: Alan Cox
  Cc: Olaf Dietsche, Andrew Morton, juhl-lkml, clameter, drepper,
	johnstul, Ulrich.Windl, jbarnes, Linux Kernel Mailing List,
	libc-alpha

Alan Cox wrote:
> On Sad, 2004-10-02 at 16:52, Olaf Dietsche wrote:
> 
>>I don't know how to do this with mozilla, but I suppose it's:
>>"Content-Disposition: inline"
>>
>>RFC 2183 <ftp://ftp.rfc-editor.org/in-notes/rfc2183.txt>
> 
> 
> Yep - that worked 8)
> 
> Evolution has an option on attachments for this

So where is the mozilla expert when he is needed??
>
-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Re: patches inline in mail
  2004-10-03 21:01                                     ` [OT] " Guennadi Liakhovetski
@ 2004-10-03 23:18                                       ` Jesper Juhl
  2004-10-04  6:20                                       ` Paul Jackson
  2004-10-04  7:26                                       ` Ulrich Windl
  2 siblings, 0 replies; 57+ messages in thread
From: Jesper Juhl @ 2004-10-03 23:18 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Alan Cox, Olaf Dietsche, george, Andrew Morton, clameter,
	drepper, johnstul, Ulrich.Windl, jbarnes,
	Linux Kernel Mailing List, libc-alpha

On Sun, 3 Oct 2004, Guennadi Liakhovetski wrote:

> Hello
> 
> While we are at it, maybe someone could help me with my "antient" pine too.
> When sending patches inline (Ctrl-R) it looks fine up in the email, also when
> I am reading my own email as it came to the list, e.g.
> 
[...]
> 
> (notice the extra space). What is going on there and is there a solution
> (apart from switching to another mailing or sending as attachments)?
> 

Recent Pine versions support a feature called flowed text that can 
whitespace damage your inline patches, you want to turn that off. Could 
probably also be some other setting that's causing it, but I haven't 
delved into it any deeper since my pine config seems to work well (at 
least I'm not getting any complains about damage when I use Ctrl+R to 
insert patches).
If you want it I can send you my .pinerc off-list, just ask for it in 
private email.

--
Jesper Juhl



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: patches inline in mail
  2004-10-03 21:35                                     ` George Anzinger
@ 2004-10-04  3:00                                       ` Jim Nelson
  0 siblings, 0 replies; 57+ messages in thread
From: Jim Nelson @ 2004-10-04  3:00 UTC (permalink / raw)
  To: Linux Kernel Mailing List

George Anzinger wrote:

> Alan Cox wrote:
>
>> On Sad, 2004-10-02 at 16:52, Olaf Dietsche wrote:
>>
>>> I don't know how to do this with mozilla, but I suppose it's:
>>> "Content-Disposition: inline"
>>>
>>> RFC 2183 <ftp://ftp.rfc-editor.org/in-notes/rfc2183.txt>
>>
>>
>>
>> Yep - that worked 8)
>>
>> Evolution has an option on attachments for this
>
>
> So where is the mozilla expert when he is needed??
>
>>

Dunno if you're being humorous or not, but here's how I did it.

In the menu bar, hit edit, preferences,(brings up a new window) mail and 
newsgroups, composition, and at the top of the screen is the "forwarding 
messages" option box - select inline.

At least that's how it works in 1.7 - haven't used the older variants in 
a while... :)


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Re: patches inline in mail
  2004-10-03 21:01                                     ` [OT] " Guennadi Liakhovetski
  2004-10-03 23:18                                       ` Jesper Juhl
@ 2004-10-04  6:20                                       ` Paul Jackson
  2004-10-04 19:11                                         ` Guennadi Liakhovetski
  2004-10-04  7:26                                       ` Ulrich Windl
  2 siblings, 1 reply; 57+ messages in thread
From: Paul Jackson @ 2004-10-04  6:20 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: alan, olaf+list.linux-kernel, george, akpm, juhl-lkml, clameter,
	drepper, johnstul, Ulrich.Windl, jbarnes, linux-kernel,
	libc-alpha, Simon.Derr

Guennadi wrote:
> However, everybody (not pine-users) complains, that white spaces got 
> corrupted. And if I export the email I see ...

I complained about the same extra space to a colleague of mine,
Simon Derr <Simon.Derr@bull.net>.

A day later, Simon wrote back to me:
> I think I found the culprit:
> pine 4.60 and later have a feature about 'flowed text' that has to be
> explicitely turned off and that messes with whitespaces.

And indeed, that fixed his patches, from my perspective.

-- 
                          I won't rest till it's the best ...
                          Programmer, Linux Scalability
                          Paul Jackson <pj@sgi.com> 1.650.933.1373

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Re: patches inline in mail
  2004-10-03 21:01                                     ` [OT] " Guennadi Liakhovetski
  2004-10-03 23:18                                       ` Jesper Juhl
  2004-10-04  6:20                                       ` Paul Jackson
@ 2004-10-04  7:26                                       ` Ulrich Windl
  2 siblings, 0 replies; 57+ messages in thread
From: Ulrich Windl @ 2004-10-04  7:26 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Olaf Dietsche, george, Andrew Morton, juhl-lkml, clameter,
	drepper, johnstul, Ulrich.Windl, jbarnes,
	Linux Kernel Mailing List, libc-alpha

Better show how the mail really looks like (source). The let's see whether it's a 
decoding or encoding error.

Ulrich

On 3 Oct 2004 at 23:01, Guennadi Liakhovetski wrote:

> Hello
> 
> While we are at it, maybe someone could help me with my "antient" pine 
> too. When sending patches inline (Ctrl-R) it looks fine up in the email, 
> also when I am reading my own email as it came to the list, e.g.
> 
> @@ -8,9 +8,9 @@
>   static void __inline__
>   dc390_freetag (struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
>   {
> -	if (pSRB->TagNumber < 255) {
> 
> However, everybody (not pine-users) complains, that white spaces got 
> corrupted. And if I export the email I see
> 
> @@ -8,9 +8,9 @@
>    static void __inline__
>    dc390_freetag (struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
>    {
> -	if (pSRB->TagNumber < 255) {
> 
> (notice the extra space). What is going on there and is there a solution 
> (apart from switching to another mailing or sending as attachments)?
> 
> Thanks
> Guennadi
> ---
> Guennadi Liakhovetski
> 



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Posix compliant cpu clocks V6 [2/3]: Glibc patch
  2004-10-02  5:32                       ` Ulrich Drepper
@ 2004-10-04 15:04                         ` Christoph Lameter
  2004-10-04 16:27                         ` Christoph Lameter
  2004-10-06 13:53                         ` Martijn Sipkema
  2 siblings, 0 replies; 57+ messages in thread
From: Christoph Lameter @ 2004-10-04 15:04 UTC (permalink / raw)
  To: Ulrich Drepper
  Cc: George Anzinger, johnstul, Ulrich.Windl, jbarnes, akpm,
	linux-kernel, libc-alpha

On Fri, 1 Oct 2004, Ulrich Drepper wrote:

> Christoph Lameter wrote:
> > The following patch makes glibc not provide the above clocks and use the
> > kernel clocks instead if either of the following condition is met:
>
> Did you ever hear about a concept called binary compatiblity?  Don't
> bother working on any glibc patch.

I wonder what this is about?


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Posix compliant cpu clocks V6 [2/3]: Glibc patch
  2004-10-02  5:32                       ` Ulrich Drepper
  2004-10-04 15:04                         ` Christoph Lameter
@ 2004-10-04 16:27                         ` Christoph Lameter
  2004-10-06 13:53                         ` Martijn Sipkema
  2 siblings, 0 replies; 57+ messages in thread
From: Christoph Lameter @ 2004-10-04 16:27 UTC (permalink / raw)
  To: Ulrich Drepper
  Cc: George Anzinger, johnstul, Ulrich.Windl, jbarnes, akpm,
	linux-kernel, libc-alpha

On Fri, 1 Oct 2004, Ulrich Drepper wrote:

> Did you ever hear about a concept called binary compatiblity?  Don't
> bother working on any glibc patch.

The patch provides complete backwards compatibility if _ASSUME_POSIX_TIMERS is not set.

If _ASSUME_POSIX_TIMERS is set then the patch assumes that this also
indicates that the cpu timers are available. Which would break binary
compatibility. Is that what you are referring to?

Also it seems the patch does not address clock_getcpuclockid() etc. I can
add that.

I had to take the material from sysdeps/unix/clock_* and put it into
sysdeps/unix/sysv/linux/clock_* because otherwise I would have broken all
the other users of sysdeps/unix/clock_*. I need the fallback to the
timer syscalls for clockids unknown to glibc that would have meant a
significant change to the code in sysdeps/unix/clock_*

I would be very grateful if you could indicate to me what fixes are
necessary to make the patch acceptable.

^ permalink raw reply	[flat|nested] 57+ messages in thread

* RFC: Posix compliant clock_getclockcpuid(pid) to access other processes clocks
  2004-10-01 21:57             ` [RFC] Posix compliant behavior of CLOCK_PROCESS/THREAD_CPUTIME_ID Roland McGrath
  2004-10-01 23:30               ` Christoph Lameter
@ 2004-10-04 18:48               ` Christoph Lameter
  1 sibling, 0 replies; 57+ messages in thread
From: Christoph Lameter @ 2004-10-04 18:48 UTC (permalink / raw)
  To: Roland McGrath
  Cc: Ulrich Drepper, johnstul, Ulrich.Windl, george, linux-kernel,
	libc-alpha, akpm, jbarnes

Here is a small idea for a kernel patch that implements access to other
process clocks via

clock_gettime(-PID,&timespec)

as Roland proposed and thus allows a full posix compliant implementation
of clock_getclockcpuid() in glibc.

clock_getclockcpuid(pid) would need to be changed to do

if (pid == 0)
	return CLOCK_PROCESS_CPUTIME_ID;
else
	return -1;

I may be able to finish this and send this to Andrew
by tomorrow.

Index: linus/kernel/posix-timers.c
===================================================================
--- linus.orig/kernel/posix-timers.c	2004-10-04 10:35:59.000000000 -0700
+++ linus/kernel/posix-timers.c	2004-10-04 11:38:06.000000000 -0700
@@ -1293,31 +1293,31 @@
  * associated with the clock.
  */

-unsigned long process_ticks(void) {
+unsigned long process_ticks(task_t *c) {
 	unsigned long ticks;
 	task_t *t;

 	/* The signal structure is shared between all threads */
-	ticks = current->signal->utime + current->signal->stime;
+	ticks = c->signal->utime + c->signal->stime;

 	/* Add up the cpu time for all the still running threads of this process */
-	t = current;
+	t = c;
 	do {
 		ticks += t->utime + t->stime;
 		t = next_thread(t);
-	} while (t != current);
+	} while (t != c);
 	return ticks;
 }

 int do_posix_clock_process_gettime(struct timespec *tp)
 {
-	jiffies_to_timespec(current->signal->process_clock_offset + process_ticks(), tp);
+	jiffies_to_timespec(current->signal->process_clock_offset + process_ticks(current), tp);
 	return 0;
 }

 int do_posix_clock_process_settime(struct timespec *tp)
 {
-	current->signal->process_clock_offset = timespec_to_jiffies(tp) - process_ticks();
+	current->signal->process_clock_offset = timespec_to_jiffies(tp) - process_ticks(current);
 	return 0;
 }

@@ -1326,11 +1326,15 @@
 {
 	struct timespec new_tp;

+	if (copy_from_user(&new_tp, tp, sizeof (*tp)))
+		return -EFAULT;
+	if (which_clock < 0) {
+		/* Setting of other processes clocks is not allowed */
+		return -EPERM;
+	}
 	if ((unsigned) which_clock >= MAX_CLOCKS ||
 					!posix_clocks[which_clock].res)
 		return -EINVAL;
-	if (copy_from_user(&new_tp, tp, sizeof (*tp)))
-		return -EFAULT;
 	if (posix_clocks[which_clock].clock_set)
 		return posix_clocks[which_clock].clock_set(&new_tp);

@@ -1343,6 +1347,15 @@
 	struct timespec rtn_tp;
 	int error = 0;

+	if (which_clock <  0) {
+		/* Obtain the clock from another process */
+		int pid = -which_clock;
+		task_t *c = find_task_by_pid(pid);
+
+		if (!c) return -EINVAL;
+	        jiffies_to_timespec(c->signal->process_clock_offset + process_ticks(c), tp);
+		return 0;
+	}
 	if ((unsigned) which_clock >= MAX_CLOCKS ||
 					!posix_clocks[which_clock].res)
 		return -EINVAL;
@@ -1361,6 +1374,10 @@
 {
 	struct timespec rtn_tp;

+	if (which_clock < 0) {
+		/* A process clock is desired. They all have the same resolution so... */
+		which_clock = CLOCK_PROCESS_CPUTIME_ID;
+	}
 	if ((unsigned) which_clock >= MAX_CLOCKS ||
 					!posix_clocks[which_clock].res)
 		return -EINVAL;

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [OT] Re: patches inline in mail
  2004-10-04  6:20                                       ` Paul Jackson
@ 2004-10-04 19:11                                         ` Guennadi Liakhovetski
  0 siblings, 0 replies; 57+ messages in thread
From: Guennadi Liakhovetski @ 2004-10-04 19:11 UTC (permalink / raw)
  To: Paul Jackson
  Cc: Guennadi Liakhovetski, alan, olaf+list.linux-kernel, george,
	akpm, juhl-lkml, clameter, drepper, johnstul, Ulrich.Windl,
	jbarnes, linux-kernel, libc-alpha, Simon.Derr

On Sun, 3 Oct 2004, Paul Jackson wrote:

> Guennadi wrote:
> > However, everybody (not pine-users) complains, that white spaces got 
> > corrupted. And if I export the email I see ...
> 
> I complained about the same extra space to a colleague of mine,
> Simon Derr <Simon.Derr@bull.net>.
> 
> A day later, Simon wrote back to me:
> > I think I found the culprit:
> > pine 4.60 and later have a feature about 'flowed text' that has to be
> > explicitely turned off and that messes with whitespaces.
> 
> And indeed, that fixed his patches, from my perspective.

Thanks to all, who replied. This:

--- .pinerc~	Sat Oct  2 22:59:50 2004
+++ .pinerc	Mon Oct  4 20:13:03 2004
@@ -82,6 +82,7 @@
 	signature-at-bottom,
 	no-pass-control-characters-as-is,
 	prefer-plain-text,
+	quell-flowed-text,
 	slash-collapses-entire-thread,
 	enable-bounce-cmd,
 	enable-msg-view-urls,

helped (I hope).

Thanks
Guennadi
---
Guennadi Liakhovetski


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Posix compliant cpu clocks V6 [2/3]: Glibc patch
  2004-10-02  5:32                       ` Ulrich Drepper
  2004-10-04 15:04                         ` Christoph Lameter
  2004-10-04 16:27                         ` Christoph Lameter
@ 2004-10-06 13:53                         ` Martijn Sipkema
  2 siblings, 0 replies; 57+ messages in thread
From: Martijn Sipkema @ 2004-10-06 13:53 UTC (permalink / raw)
  To: Ulrich Drepper, Christoph Lameter
  Cc: George Anzinger, johnstul, Ulrich.Windl, jbarnes, akpm,
	linux-kernel, libc-alpha

From: "Ulrich Drepper" <drepper@redhat.com>
> Christoph Lameter wrote:
>> The following patch makes glibc not provide the above clocks and use the
>> kernel clocks instead if either of the following condition is met:
>
> Did you ever hear about a concept called binary compatiblity?  Don't
> bother working on any glibc patch.

The functionality should arguably not have been added to glibc in the first
place since its implementation was incorrect.

--ms



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Posix compliant cpu clocks V7 [0/2]: Rationale and test program
       [not found]                   ` <B6E8046E1E28D34EB815A11AC8CA31290322B307@mtv-atc-605e--n.corp.sgi.com>
                                       ` (2 preceding siblings ...)
  2004-10-01 20:02                     ` Posix compliant cpu clocks V6 [3/3]: mmtimer provides CLOCK_SGI_CYCLE Christoph Lameter
@ 2004-10-07  4:56                     ` Christoph Lameter
  2004-10-12 20:19                       ` Periodic posix timer support broke between 2.6.9-rc1 and 2.6.9-rc1-bk17 Christoph Lameter
       [not found]                     ` <B6E8046E1E28D34EB815A11AC8CA31290322B331@mtv-atc-605e--n.corp.sgi.com>
  4 siblings, 1 reply; 57+ messages in thread
From: Christoph Lameter @ 2004-10-07  4:56 UTC (permalink / raw)
  To: George Anzinger
  Cc: Ulrich Drepper, johnstul, Ulrich.Windl, jbarnes, akpm,
	linux-kernel, libc-alpha, nickpiggin, roland

Posix compliant cpu clocks: V7 [0/3] Rationale and test program

Signed-off-by: Christoph Lameter <clameter@sgi.com>

Changes from V5:
 * add a simple means of accessing other processes cputimers.
 * Simplified glibc patch that makes glibc return errors when
   an applications accesses cputimers and is run with glibc under a kernel
   not providing cputimers. This may allow the detection of applications that
   need to be updated since they depend on the earlier non posix compliant
   version of glibc. Also should be more readable since the sections
   are no longer moved betweeen directory hierachies.
 * remove ability to set process and thread clocks.

POSIX clocks are to be implemented in the following way according
to V3 of the Single Unix Specification:

1. CLOCK_PROCESS_CPUTIME_ID

  Implementations shall also support the special clockid_t value
  CLOCK_PROCESS_CPUTIME_ID, which represents the CPU-time clock of the
  calling process when invoking one of the clock_*() or timer_*()
  functions. For these clock IDs, the values returned by clock_gettime() and
  specified by clock_settime() represent the amount of execution time of the
  process associated with the clock.

2. CLOCK_THREAD_CPUTIME_ID

  Implementations shall also support the special clockid_t value
  CLOCK_THREAD_CPUTIME_ID, which represents the CPU-time clock of the
  calling thread when invoking one of the clock_*() or timer_*()
  functions. For these clock IDs, the values returned by clock_gettime()
  and specified by clock_settime() shall represent the amount of
  execution time of the thread associated with the clock.

These times mentioned are CPU processing times and not the time that has
passed since the startup of a process. Glibc currently provides its own
implementation of these two clocks which is designed to return the time
that passed since the startup of a process or a thread.

Moreover Glibc's clocks are bound to CPU timers which is problematic when the
frequency of the clock changes or the process is moved to a different
processor whose cpu timer may not be fully synchronized to the cpu timer
of the current CPU. This patchset results in a both clocks working reliably.

The patch also implements the access to other the thread and process clocks
of linux processes by using negative clockid's:

1. For CLOCK_PROCESS_CPUTIME_ID: -pid
2. For CLOCK_THREAD_CPUTIME_ID: -(pid + PID_MAX_LIMIT)

This allows

clock_getcpuclockid(pid) to return -pid

and

pthread_getcpuiclock(pid) to return -(pid + PID_MAX_LIMIT)

to allow access to the corresponding clocks.

Todo:
- The timer API to generate events by a non tick based timer is not
  usable in its current state. The posix timer API seems to be only
  useful at this point to define clock_get/set. Need to revise this.
- Implement timed interrupts in mmtimer after API is revised.

The patchset consists of the following components:

[0/2] Contains an explanation as to why these patches are necessary
      as well as a test program and the output of a sample run.

[1/2] Linux Kernel Patch: Implements the two clocks and enhances some
      pieces of the posix-timers implementation in the kernel for these
      clocks and also makes it possible for device drivers to define
      additional clocks.

[2/2] Glibc patch: Use kernel clocks and also makes glibc able to use any
      posix clock provided by the kernel so that posix clocks by driver
      may be accessed. Break apps that use the old cputimer based
      CLOCK_*_CPUTIME_IDs on kernels that do not support CLOCK_*_CPUTIME_ID.

The mmtimer patch is unchanged from V6 and stays as is in 2.6.9-rc3-mm2.
But I expect to update the driver as soon as the interface to setup hardware
timer interrupts is usable.

Rolands patches:
----------------
This patch is not as comprehensive as Rolands but also not as invasive.
Roland's high resolution time through tsc is a hack but would significantly
improve the statistics we get for a process. However, we may get the same
result in a cleaner way after John Stultz and my plan for revising the
time subsystem is through. This would replace jiffies with nanoseconds
for time keeping throughout the kernel.

Nanosecond accuracy is already available through getnstimeofday() on some
platforms. Some of the functionality in Roland's patch may be implemented in a
TSC independent way using this function.

The use of negative pid values in certain numeric ranges for selecting the
type of clock is something that is also in a simplerr way present in
my patch. I do not like this and would rather see this incorporated in
glibc if the glibc people can come up with a sane implementation.

Single Thread Testing
  CLOCK_THREAD_CPUTIME_ID=          0.494140878 resolution= 0.000976563
 CLOCK_PROCESS_CPUTIME_ID=          0.494140878 resolution= 0.000976563
Multi Thread Testing
Starting Thread: 0 1 2 3 4 5 6 7 8 9
 Joining Thread: 0 1 2 3 4 5 6 7 8 9
0 Cycles=      0 Thread=  0.000000000ns Process=  0.495117441ns
1 Cycles=1000000 Thread=  0.140625072ns Process=  2.523438792ns
2 Cycles=2000000 Thread=  0.966797370ns Process=  8.512699671ns
3 Cycles=3000000 Thread=  0.806641038ns Process=  7.561527309ns
4 Cycles=4000000 Thread=  1.865235330ns Process= 12.891608163ns
5 Cycles=5000000 Thread=  1.604493009ns Process= 11.528326215ns
6 Cycles=6000000 Thread=  2.086915131ns Process= 13.500983475ns
7 Cycles=7000000 Thread=  2.245118337ns Process= 13.947272766ns
8 Cycles=8000000 Thread=  1.604493009ns Process= 12.252935961ns
9 Cycles=9000000 Thread=  2.160157356ns Process= 13.977546219ns

Clock status at the end of the timer tests:
          Gettimeofday() = 1097084999.489938000
           CLOCK_REALTIME= 1097084999.490116229 resolution= 0.000000040
          CLOCK_MONOTONIC=        177.071675109 resolution= 0.000000040
 CLOCK_PROCESS_CPUTIME_ID=         13.978522782 resolution= 0.000976563
  CLOCK_THREAD_CPUTIME_ID=          0.497070567 resolution= 0.000976563
          CLOCK_SGI_CYCLE=        229.967982280 resolution= 0.000000040
PROCESS clock of 1 (init)=          4.833986850 resolution= 0.000976563
 THREAD clock of 1 (init)=          0.009765630 resolution= 0.000976563



#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <asm/unistd.h>
#include <pthread.h>

#define clock_getres(x,y) syscall(__NR_clock_getres, x,y)
#define clock_gettime(x,y) syscall(__NR_clock_gettime, x, y)
#define clock_settime(x,y) syscall(__NR_clock_settime, x, y)

void pr(int clock,const char *n)
{
	struct timespec tv = {1,2};
	struct timespec res = {3,4};
	int rc;


	rc=clock_getres(clock,&res);
	if (rc) {
		printf("getres return code on %s=%d errno=%d\n",n,rc,errno);
	}
	rc=clock_gettime(clock,&tv);
	if (rc) {
		printf("gettime return code on %s=%d errno=%d\n",n,rc, errno);
	}
	else
	printf("%25s=% 11d.%09d resolution=% 2d.%09d\n",n,tv.tv_sec,tv.tv_nsec,res.tv_sec,res.tv_nsec);
}

int y;

void kx(long long x) {
	y=x;
};

struct timespec zero;

pthread_t thread[10];

struct tinfo {
	int i;
	struct timespec ttime,ptime;
} tinf[10];

void *thread_function(void *x) {
	struct tinfo *t=x;
	int i;

	for(i=1;i< t->i;i++) kx(1000000000000LL/i);
	clock_gettime(CLOCK_THREAD_CPUTIME_ID,&t->ttime);
	clock_gettime(CLOCK_PROCESS_CPUTIME_ID,&t->ptime);
}

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

	/* Waste some time */
	printf("Single Thread Testing\n");

	for(i=1;i<10000000;i++) kx(1000000000000LL/i);
	pr(CLOCK_THREAD_CPUTIME_ID,"CLOCK_THREAD_CPUTIME_ID");
	pr(CLOCK_PROCESS_CPUTIME_ID,"CLOCK_PROCESS_CPUTIME_ID");
	/* Waste some more time in threads */
	printf("Multi Thread Testing\nStarting Thread:");
	clock_settime(CLOCK_PROCESS_CPUTIME_ID,&zero);
	for(i=0;i<10;i++) {
		tinf[i].i=i*1000000;
		if (pthread_create(&thread[i], NULL, thread_function, tinf+i))
			perror("thread");
		else
			printf(" %d",i);
	}
	printf("\n Joining Thread:");
	for(i=0;i<10;i++) if (pthread_join( thread[i], NULL)) perror("join"); else printf(" %d",i);
	printf("\n");
	for(i=0;i<10;i++) {
		printf("%d Cycles=%7d Thread=% 3d.%09dns Process=% 3d.%09dns\n",i,tinf[i].i,tinf[i].ttime.tv_sec,tinf[i].ttime.tv_nsec,tinf[i].ptime.tv_sec,tinf[i].ptime.tv_nsec);
	}
	gettimeofday((struct timeval *)&tv);
	tv.tv_nsec = tv.tv_nsec*1000;
	printf("\nClock status at the end of the timer tests:\n");
	printf("          Gettimeofday() =% 11d.%09d\n",tv.tv_sec,tv.tv_nsec);
	pr(CLOCK_REALTIME,"CLOCK_REALTIME");
	pr(CLOCK_MONOTONIC,"CLOCK_MONOTONIC");
	pr(CLOCK_PROCESS_CPUTIME_ID,"CLOCK_PROCESS_CPUTIME_ID");
	pr(CLOCK_THREAD_CPUTIME_ID,"CLOCK_THREAD_CPUTIME_ID");
	pr(10,"CLOCK_SGI_CYCLE");
	pr(-1,"PROCESS clock of 1 (init)");
	pr(-1 - 4*1024*1024,"THREAD clock of 1 (init)");
	printf("\n");
}

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Posix compliant cpu clocks V7 [1/2]: Kernel Patch
       [not found]                     ` <B6E8046E1E28D34EB815A11AC8CA31290322B331@mtv-atc-605e--n.corp.sgi.com>
@ 2004-10-07  4:57                       ` Christoph Lameter
  2004-10-07  4:59                       ` Posix compliant cpu clocks V7 [2/2]: Glibc patch Christoph Lameter
  1 sibling, 0 replies; 57+ messages in thread
From: Christoph Lameter @ 2004-10-07  4:57 UTC (permalink / raw)
  To: George Anzinger
  Cc: Ulrich Drepper, johnstul, Ulrich.Windl, jbarnes, akpm,
	linux-kernel, libc-alpha, nickpiggin, roland

Index: linux-2.6.9-rc3/kernel/posix-timers.c
===================================================================
--- linux-2.6.9-rc3.orig/kernel/posix-timers.c	2004-09-29 20:04:47.000000000 -0700
+++ linux-2.6.9-rc3/kernel/posix-timers.c	2004-10-06 10:39:52.000000000 -0700
@@ -10,6 +10,10 @@
  * 2004-06-01  Fix CLOCK_REALTIME clock/timer TIMER_ABSTIME bug.
  *			     Copyright (C) 2004 Boris Hu
  *
+ * 2004-07-27 Provide POSIX compliant clocks
+ *		CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID.
+ *		by Christoph Lameter
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or (at
@@ -133,18 +137,10 @@
  *	    resolution.	 Here we define the standard CLOCK_REALTIME as a
  *	    1/HZ resolution clock.
  *
- * CPUTIME & THREAD_CPUTIME: We are not, at this time, definding these
- *	    two clocks (and the other process related clocks (Std
- *	    1003.1d-1999).  The way these should be supported, we think,
- *	    is to use large negative numbers for the two clocks that are
- *	    pinned to the executing process and to use -pid for clocks
- *	    pinned to particular pids.	Calls which supported these clock
- *	    ids would split early in the function.
- *
  * RESOLUTION: Clock resolution is used to round up timer and interval
  *	    times, NOT to report clock times, which are reported with as
  *	    much resolution as the system can muster.  In some cases this
- *	    resolution may depend on the underlaying clock hardware and
+ *	    resolution may depend on the underlying clock hardware and
  *	    may not be quantifiable until run time, and only then is the
  *	    necessary code is written.	The standard says we should say
  *	    something about this issue in the documentation...
@@ -162,7 +158,7 @@
  *
  *          At this time all functions EXCEPT clock_nanosleep can be
  *          redirected by the CLOCKS structure.  Clock_nanosleep is in
- *          there, but the code ignors it.
+ *          there, but the code ignores it.
  *
  * Permissions: It is assumed that the clock_settime() function defined
  *	    for each clock will take care of permission checks.	 Some
@@ -192,12 +188,13 @@
 #define p_timer_del(clock,a) \
 		if_clock_do((clock)->timer_del, do_timer_delete, (a))

-void register_posix_clock(int clock_id, struct k_clock *new_clock);
 static int do_posix_gettime(struct k_clock *clock, struct timespec *tp);
 static u64 do_posix_clock_monotonic_gettime_parts(
 	struct timespec *tp, struct timespec *mo);
 int do_posix_clock_monotonic_gettime(struct timespec *tp);
-int do_posix_clock_monotonic_settime(struct timespec *tp);
+static int do_posix_clock_monotonic_settime(struct timespec *tp);
+static int do_posix_clock_process_gettime(struct timespec *tp);
+static int do_posix_clock_thread_gettime(struct timespec *tp);
 static struct k_itimer *lock_timer(timer_t timer_id, unsigned long *flags);

 static inline void unlock_timer(struct k_itimer *timr, unsigned long flags)
@@ -216,7 +213,21 @@
 	struct k_clock clock_monotonic = {.res = CLOCK_REALTIME_RES,
 		.abs_struct = NULL,
 		.clock_get = do_posix_clock_monotonic_gettime,
-		.clock_set = do_posix_clock_monotonic_settime
+		.clock_set = do_posix_clock_nosettime
+	};
+	struct k_clock clock_thread = {.res = CLOCK_REALTIME_RES,
+		.abs_struct = NULL,
+		.clock_get = do_posix_clock_thread_gettime,
+		.clock_set = do_posix_clock_nosettime,
+		.timer_create = do_posix_clock_notimer_create,
+		.nsleep = do_posix_clock_nonanosleep
+	};
+	struct k_clock clock_process = {.res = CLOCK_REALTIME_RES,
+		.abs_struct = NULL,
+		.clock_get = do_posix_clock_process_gettime,
+		.clock_set = do_posix_clock_nosettime,
+		.timer_create = do_posix_clock_notimer_create,
+		.nsleep = do_posix_clock_nonanosleep
 	};

 #ifdef CONFIG_TIME_INTERPOLATION
@@ -226,6 +237,8 @@

 	register_posix_clock(CLOCK_REALTIME, &clock_realtime);
 	register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
+	register_posix_clock(CLOCK_PROCESS_CPUTIME_ID, &clock_process);
+	register_posix_clock(CLOCK_THREAD_CPUTIME_ID, &clock_thread);

 	posix_timers_cache = kmem_cache_create("posix_timers_cache",
 					sizeof (struct k_itimer), 0, 0, NULL, NULL);
@@ -577,6 +590,10 @@
 				!posix_clocks[which_clock].res)
 		return -EINVAL;

+	if (posix_clocks[which_clock].timer_create)
+		return posix_clocks[which_clock].timer_create(which_clock,
+				timer_event_spec, created_timer_id);
+
 	new_timer = alloc_posix_timer();
 	if (unlikely(!new_timer))
 		return -EAGAIN;
@@ -1222,16 +1239,87 @@
 	return 0;
 }

-int do_posix_clock_monotonic_settime(struct timespec *tp)
+int do_posix_clock_nosettime(struct timespec *tp)
 {
 	return -EINVAL;
 }

+int do_posix_clock_notimer_create(int which_clock,
+		struct sigevent __user *timer_event_spec,
+		timer_t __user *created_timer_id) {
+	return -EINVAL;
+}
+
+int do_posix_clock_nonanosleep(int which_lock, int flags,struct timespec * t) {
+/* Single Unix specficiation says to return ENOTSUP but we do not have that */
+	return -EINVAL;
+}
+
+static unsigned long process_ticks(task_t *p) {
+	unsigned long ticks;
+	task_t *t;
+
+	spin_lock(&p->sighand->siglock);
+	/* The signal structure is shared between all threads */
+	ticks = p->signal->utime + p->signal->stime;
+
+	/* Add up the cpu time for all the still running threads of this process */
+	t = p;
+	do {
+		ticks += t->utime + t->stime;
+		t = next_thread(t);
+	} while (t != p);
+
+	spin_unlock(&p->sighand->siglock);
+	return ticks;
+}
+
+static inline unsigned long thread_ticks(task_t *p) {
+	return p->utime + current->stime;
+}
+
+/*
+ * Single Unix Specification V3:
+ *
+ * Implementations shall also support the special clockid_t value
+ * CLOCK_THREAD_CPUTIME_ID, which represents the CPU-time clock of the calling
+ * thread when invoking one of the clock_*() or timer_*() functions. For these
+ * clock IDs, the values returned by clock_gettime() and specified by
+ * clock_settime() shall represent the amount of execution time of the thread
+ * associated with the clock.
+ */
+static int do_posix_clock_thread_gettime(struct timespec *tp)
+{
+	jiffies_to_timespec(thread_ticks(current), tp);
+	return 0;
+}
+
+/*
+ * Single Unix Specification V3:
+ *
+ * Implementations shall also support the special clockid_t value
+ * CLOCK_PROCESS_CPUTIME_ID, which represents the CPU-time clock of the
+ * calling process when invoking one of the clock_*() or timer_*() functions.
+ * For these clock IDs, the values returned by clock_gettime() and specified
+ * by clock_settime() represent the amount of execution time of the process
+ * associated with the clock.
+ */
+
+static int do_posix_clock_process_gettime(struct timespec *tp)
+{
+	jiffies_to_timespec(process_ticks(current), tp);
+	return 0;
+}
+
 asmlinkage long
 sys_clock_settime(clockid_t which_clock, const struct timespec __user *tp)
 {
 	struct timespec new_tp;

+	/* Cannot set process specific clocks */
+	if (which_clock<0)
+		return -EINVAL;
+
 	if ((unsigned) which_clock >= MAX_CLOCKS ||
 					!posix_clocks[which_clock].res)
 		return -EINVAL;
@@ -1249,6 +1337,29 @@
 	struct timespec rtn_tp;
 	int error = 0;

+	/* Process process specific clocks */
+	if (which_clock < 0) {
+		task_t *t;
+		int pid = -which_clock;
+
+		if (pid < PID_MAX_LIMIT) {
+			if (t = find_task_by_pid(pid)) {
+				jiffies_to_timespec(process_ticks(t), tp);
+				return 0;
+			}
+			return -EINVAL;
+		}
+		if (pid < 2*PID_MAX_LIMIT) {
+			if (t = find_task_by_pid(pid - PID_MAX_LIMIT)) {
+				jiffies_to_timespec(thread_ticks(t), tp);
+				return 0;
+			}
+			return -EINVAL;
+		}
+		/* More process specific clocks could follow here */
+		return -EINVAL;
+	}
+
 	if ((unsigned) which_clock >= MAX_CLOCKS ||
 					!posix_clocks[which_clock].res)
 		return -EINVAL;
@@ -1267,6 +1378,9 @@
 {
 	struct timespec rtn_tp;

+	/* All process clocks have the resolution of CLOCK_PROCESS_CPUTIME_ID */
+	if (which_clock < 0 ) which_clock = CLOCK_PROCESS_CPUTIME_ID;
+
 	if ((unsigned) which_clock >= MAX_CLOCKS ||
 					!posix_clocks[which_clock].res)
 		return -EINVAL;
@@ -1413,7 +1527,10 @@
 	if ((unsigned) t.tv_nsec >= NSEC_PER_SEC || t.tv_sec < 0)
 		return -EINVAL;

-	ret = do_clock_nanosleep(which_clock, flags, &t);
+	if (posix_clocks[which_clock].nsleep)
+		ret = posix_clocks[which_clock].nsleep(which_clock, flags, &t);
+	else
+		ret = do_clock_nanosleep(which_clock, flags, &t);
 	/*
 	 * Do this here as do_clock_nanosleep does not have the real address
 	 */
Index: linux-2.6.9-rc3/include/linux/posix-timers.h
===================================================================
--- linux-2.6.9-rc3.orig/include/linux/posix-timers.h	2004-09-29 20:04:46.000000000 -0700
+++ linux-2.6.9-rc3/include/linux/posix-timers.h	2004-10-06 10:33:52.000000000 -0700
@@ -13,9 +13,10 @@
 	struct k_clock_abs *abs_struct;
 	int (*clock_set) (struct timespec * tp);
 	int (*clock_get) (struct timespec * tp);
-	int (*nsleep) (int flags,
-		       struct timespec * new_setting,
-		       struct itimerspec * old_setting);
+	int (*timer_create) (int which_clock, struct sigevent __user *timer_event_spec,
+			timer_t __user * created_timer_id);
+	int (*nsleep) (int which_clock, int flags,
+		       struct timespec * t);
 	int (*timer_set) (struct k_itimer * timr, int flags,
 			  struct itimerspec * new_setting,
 			  struct itimerspec * old_setting);
@@ -23,6 +24,17 @@
 	void (*timer_get) (struct k_itimer * timr,
 			   struct itimerspec * cur_setting);
 };
+
+void register_posix_clock(int clock_id, struct k_clock *new_clock);
+
+/* Error handlers for timer_create, nanosleep and settime */
+int do_posix_clock_notimer_create(int which_clock,
+                struct sigevent __user *time_event_spec,
+                timer_t __user *created_timer_id);
+
+int do_posix_clock_nonanosleep(int which_clock, int flags, struct timespec * t);
+int do_posix_clock_nosettime(struct timespec *tp);
+
 struct now_struct {
 	unsigned long jiffies;
 };
@@ -42,3 +54,4 @@
               }								\
             }while (0)
 #endif
+
Index: linux-2.6.9-rc3/include/linux/time.h
===================================================================
--- linux-2.6.9-rc3.orig/include/linux/time.h	2004-09-29 20:05:18.000000000 -0700
+++ linux-2.6.9-rc3/include/linux/time.h	2004-10-06 10:33:52.000000000 -0700
@@ -413,7 +413,12 @@
 #define CLOCK_REALTIME_HR	 4
 #define CLOCK_MONOTONIC_HR	  5

-#define MAX_CLOCKS 6
+/*
+ * The IDs of various hardware clocks
+ */
+
+
+#define MAX_CLOCKS 16
 #define CLOCKS_MASK  (CLOCK_REALTIME | CLOCK_MONOTONIC | \
                      CLOCK_REALTIME_HR | CLOCK_MONOTONIC_HR)
 #define CLOCKS_MONO (CLOCK_MONOTONIC & CLOCK_MONOTONIC_HR)

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Posix compliant cpu clocks V7 [2/2]: Glibc patch
       [not found]                     ` <B6E8046E1E28D34EB815A11AC8CA31290322B331@mtv-atc-605e--n.corp.sgi.com>
  2004-10-07  4:57                       ` Posix compliant cpu clocks V7 [1/2]: Kernel Patch Christoph Lameter
@ 2004-10-07  4:59                       ` Christoph Lameter
  1 sibling, 0 replies; 57+ messages in thread
From: Christoph Lameter @ 2004-10-07  4:59 UTC (permalink / raw)
  To: George Anzinger
  Cc: Ulrich Drepper, johnstul, Ulrich.Windl, jbarnes, akpm,
	linux-kernel, libc-alpha, nickpiggin, roland

Posix compliant CLOCK_THREAD_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID

The following patch makes glibc not provide the above clocks. Glibc will
either return an error or use the kernel interface.
This also defines all the posix clock routines in such a way that these
function work as documented by posix. It allows the specification of pids
when invoking clock_getcpuclockid() and pthread_getcpuclockid to obtain
the process or task clock of any process in the system.

Patch is cleaned up so that is does not move sections of code around.

Signed-off-by: Christoph Lameter <clameter@sgi.com>

Index: libc/nptl/sysdeps/pthread/pthread_getcpuclockid.c
===================================================================
--- libc.orig/nptl/sysdeps/pthread/pthread_getcpuclockid.c	2003-06-24 16:53:20.000000000 -0700
+++ libc/nptl/sysdeps/pthread/pthread_getcpuclockid.c	2004-10-06 21:13:00.382271104 -0700
@@ -20,7 +20,7 @@
 #include <pthreadP.h>
 #include <sys/time.h>
 #include <tls.h>
-
+#include <linux/threads.h>

 int
 pthread_getcpuclockid (threadid, clockid)
@@ -35,19 +35,8 @@
     return ESRCH;

 #ifdef CLOCK_THREAD_CPUTIME_ID
-  /* We need to store the thread ID in the CLOCKID variable together
-     with a number identifying the clock.  We reserve the low 3 bits
-     for the clock ID and the rest for the thread ID.  This is
-     problematic if the thread ID is too large.  But 29 bits should be
-     fine.
-
-     If some day more clock IDs are needed the ID part can be
-     enlarged.  The IDs are entirely internal.  */
-  if (pd->tid >= 1 << (8 * sizeof (*clockid) - CLOCK_IDFIELD_SIZE))
-    return ERANGE;
-
   /* Store the number.  */
-  *clockid = CLOCK_THREAD_CPUTIME_ID | (pd->tid << CLOCK_IDFIELD_SIZE);
+  *clockid = - (pd->tid + PID_MAX_LIMIT);

   return 0;
 #else
Index: libc/sysdeps/unix/sysv/linux/clock_getres.c
===================================================================
--- libc.orig/sysdeps/unix/sysv/linux/clock_getres.c	2004-09-28 15:22:02.351950224 -0700
+++ libc/sysdeps/unix/sysv/linux/clock_getres.c	2004-10-06 21:19:57.842807456 -0700
@@ -20,24 +20,20 @@

 #include "kernel-features.h"

-
 #ifdef __ASSUME_POSIX_TIMERS
-/* This means the REALTIME and MONOTONIC clock are definitely
-   supported in the kernel.  */
-# define SYSDEP_GETRES \
-  case CLOCK_REALTIME:							      \
-  case CLOCK_MONOTONIC:							      \
-    retval = INLINE_SYSCALL (clock_getres, 2, clock_id, res);		      \
-    break
+/* we have to rely on the kernel */
+#define SYSDEP_DEFAULT_GETRES { \
+		INTERNAL_SYSCALL_DECL(err); \
+		retval = INTERNAL_SYSCALL(clock_getres, err, 2, clock_id, res); \
+	}
+
 #elif defined __NR_clock_getres
 /* Is the syscall known to exist?  */
 extern int __libc_missing_posix_timers attribute_hidden;

 /* The REALTIME and MONOTONIC clock might be available.  Try the
    syscall first.  */
-# define SYSDEP_GETRES \
-  case CLOCK_REALTIME:							      \
-  case CLOCK_MONOTONIC:							      \
+# define SYSDEP_DEFAULT_GETRES \
     {									      \
       int e = EINVAL;							      \
 									      \
@@ -65,7 +61,7 @@
       else								      \
 	__set_errno (e);						      \
     }									      \
-    break
+
 #endif

 #ifdef __NR_clock_getres
Index: libc/sysdeps/unix/clock_gettime.c
===================================================================
--- libc.orig/sysdeps/unix/clock_gettime.c	2004-09-28 15:22:02.192974392 -0700
+++ libc/sysdeps/unix/clock_gettime.c	2004-10-06 15:34:17.994743608 -0700
@@ -23,21 +23,6 @@
 #include <libc-internal.h>
 #include <ldsodefs.h>

-
-#if HP_TIMING_AVAIL
-/* Clock frequency of the processor.  We make it a 64-bit variable
-   because some jokers are already playing with processors with more
-   than 4GHz.  */
-static hp_timing_t freq;
-
-
-/* This function is defined in the thread library.  */
-extern int __pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq,
-				    struct timespec *tp)
-     __attribute__ ((__weak__));
-#endif
-
-
 /* Get current value of CLOCK and store it in TP.  */
 int
 clock_gettime (clockid_t clock_id, struct timespec *tp)
@@ -66,58 +51,14 @@
 #endif

     default:
-#if HP_TIMING_AVAIL
-      if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1))
-	  != CLOCK_THREAD_CPUTIME_ID)
-#endif
+#ifdef SYSDEP_DEFAULT_GETTIME
+      SYSDEP_DEFAULT_GETTIME;
+#else
 	{
 	  __set_errno (EINVAL);
 	  break;
 	}
-
-#if HP_TIMING_AVAIL
-      /* FALLTHROUGH.  */
-    case CLOCK_PROCESS_CPUTIME_ID:
-      {
-	hp_timing_t tsc;
-
-	if (__builtin_expect (freq == 0, 0))
-	  {
-	    /* This can only happen if we haven't initialized the `freq'
-	       variable yet.  Do this now. We don't have to protect this
-	       code against multiple execution since all of them should
-	       lead to the same result.  */
-	    freq = __get_clockfreq ();
-	    if (__builtin_expect (freq == 0, 0))
-	      /* Something went wrong.  */
-	      break;
-	  }
-
-	if (clock_id != CLOCK_PROCESS_CPUTIME_ID
-	    && __pthread_clock_gettime != NULL)
-	  {
-	    retval = __pthread_clock_gettime (clock_id, freq, tp);
-	    break;
-	  }
-
-	/* Get the current counter.  */
-	HP_TIMING_NOW (tsc);
-
-	/* Compute the offset since the start time of the process.  */
-	tsc -= GL(dl_cpuclock_offset);
-
-	/* Compute the seconds.  */
-	tp->tv_sec = tsc / freq;
-
-	/* And the nanoseconds.  This computation should be stable until
-	   we get machines with about 16GHz frequency.  */
-	tp->tv_nsec = ((tsc % freq) * UINT64_C (1000000000)) / freq;
-
-	retval = 0;
-      }
-    break;
 #endif
     }
-
   return retval;
 }
Index: libc/sysdeps/unix/sysv/linux/ia64/clock_getcpuclockid.c
===================================================================
--- libc.orig/sysdeps/unix/sysv/linux/ia64/clock_getcpuclockid.c	2004-09-28 15:22:02.595913136 -0700
+++ /dev/null1970-01-01 00:00:00.000000000 +0000
@@ -1,65 +0,0 @@
-/* Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#include <errno.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <fcntl.h>
-
-
-int
-clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
-{
-  /* We don't allow any process ID but our own.  */
-  if (pid != 0 && pid != getpid ())
-    return EPERM;
-
-  static int itc_usable;
-  int retval = ENOENT;
-
-  if (__builtin_expect (itc_usable == 0, 0))
-    {
-      int newval = 1;
-      int fd = open ("/proc/sal/itc_drift", O_RDONLY);
-      if (__builtin_expect (fd != -1, 1))
-	{
-	  char buf[16];
-	  /* We expect the file to contain a single digit followed by
-	     a newline.  If the format changes we better not rely on
-	     the file content.  */
-	  if (read (fd, buf, sizeof buf) != 2 || buf[0] != '0'
-	      || buf[1] != '\n')
-	    newval = -1;
-
-	  close (fd);
-	}
-
-      itc_usable = newval;
-    }
-
-  if (itc_usable > 0)
-    {
-      /* Store the number.  */
-      *clock_id = CLOCK_PROCESS_CPUTIME_ID;
-      retval = 0;
-    }
-
-  return retval;
-}
Index: libc/sysdeps/unix/sysv/linux/clock_settime.c
===================================================================
--- libc.orig/sysdeps/unix/sysv/linux/clock_settime.c	2004-10-01 10:27:15.007445832 -0700
+++ libc/sysdeps/unix/sysv/linux/clock_settime.c	2004-10-06 21:22:01.041078472 -0700
@@ -20,21 +20,18 @@

 #include "kernel-features.h"

-
 #ifdef __ASSUME_POSIX_TIMERS
-/* This means the REALTIME clock is definitely supported in the
-   kernel.  */
-# define SYSDEP_SETTIME \
-  case CLOCK_REALTIME:							      \
-    retval = INLINE_SYSCALL (clock_settime, 2, clock_id, tp);		      \
-    break
+#define SYSDEP_DEFAULT_SETTIME { \
+		INTERNAL_SYSCALL_DECL(err); \
+		retval = INTERNAL_SYSCALL(clock_settime, err, 2, clock_id, tp); \
+	}
+
 #elif defined __NR_clock_settime
 /* Is the syscall known to exist?  */
 extern int __libc_missing_posix_timers attribute_hidden;

 /* The REALTIME clock might be available.  Try the syscall first.  */
-# define SYSDEP_SETTIME \
-  case CLOCK_REALTIME:							      \
+# define SYSDEP_DEFAULT_SETTIME \
     {									      \
       int e = EINVAL;							      \
 									      \
@@ -64,8 +61,7 @@
 	  __set_errno (e);						      \
 	  retval = -1;							      \
 	}								      \
-    }									      \
-    break
+    }
 #endif

 #ifdef __NR_clock_settime
Index: libc/sysdeps/unix/sysv/linux/clock_getcpuclockid.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ libc/sysdeps/unix/sysv/linux/clock_getcpuclockid.c	2004-10-06 21:33:48.687499864 -0700
@@ -0,0 +1,44 @@
+
+/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <time.h>
+#include <unistd.h>
+
+int
+clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
+{
+  if (pid != 0 && pid != getpid ())
+#ifdef __ASSUME_POSIX_TIMERS
+	return -pid;
+#else
+/* We don't allow any process ID but our own.  */
+    return EPERM;
+#endif
+
+#ifdef CLOCK_PROCESS_CPUTIME_ID
+  /* Store the number.  */
+  *clock_id = CLOCK_PROCESS_CPUTIME_ID;
+
+  return 0;
+#else
+  /* We don't have a timer for that.  */
+  return ENOENT;
+#endif
+}
Index: libc/sysdeps/posix/clock_getres.c
===================================================================
--- libc.orig/sysdeps/posix/clock_getres.c	2004-09-28 15:22:02.032998712 -0700
+++ libc/sysdeps/posix/clock_getres.c	2004-10-06 14:48:30.854372424 -0700
@@ -23,13 +23,6 @@
 #include <sys/param.h>
 #include <libc-internal.h>

-
-#if HP_TIMING_AVAIL && !defined HANDLED_CPUTIME
-/* Clock frequency of the processor.  */
-static long int nsec;
-#endif
-
-
 /* Get resolution of clock.  */
 int
 clock_getres (clockid_t clock_id, struct timespec *res)
@@ -65,44 +58,15 @@
 #endif	/* handled REALTIME */

     default:
-#if HP_TIMING_AVAIL
-      if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1))
-	  != CLOCK_THREAD_CPUTIME_ID)
-#endif
-	{
+#ifdef SYSDEP_DEFAULT_GETRES
+      SYSDEP_DEFAULT_GETRES;
+#else
+      {
 	  __set_errno (EINVAL);
 	  break;
 	}
-
-#if HP_TIMING_AVAIL && !defined HANDLED_CPUTIME
-      /* FALLTHROUGH.  */
-    case CLOCK_PROCESS_CPUTIME_ID:
-      {
-	if (__builtin_expect (nsec == 0, 0))
-	  {
-	    hp_timing_t freq;
-
-	    /* This can only happen if we haven't initialized the `freq'
-	       variable yet.  Do this now. We don't have to protect this
-	       code against multiple execution since all of them should
-	       lead to the same result.  */
-	    freq = __get_clockfreq ();
-	    if (__builtin_expect (freq == 0, 0))
-	      /* Something went wrong.  */
-	      break;
-
-	    nsec = MAX (UINT64_C (1000000000) / freq, 1);
-	  }
-
-	/* File in the values.  The seconds are always zero (unless we
-	   have a 1Hz machine).  */
-	res->tv_sec = 0;
-	res->tv_nsec = nsec;
-
-	retval = 0;
-      }
-      break;
 #endif
+
     }

   return retval;
Index: libc/sysdeps/unix/clock_settime.c
===================================================================
--- libc.orig/sysdeps/unix/clock_settime.c	2004-10-01 10:26:04.247203024 -0700
+++ libc/sysdeps/unix/clock_settime.c	2004-10-06 15:56:49.504282928 -0700
@@ -22,20 +22,6 @@
 #include <libc-internal.h>
 #include <ldsodefs.h>

-
-#if HP_TIMING_AVAIL
-/* Clock frequency of the processor.  We make it a 64-bit variable
-   because some jokers are already playing with processors with more
-   than 4GHz.  */
-static hp_timing_t freq;
-
-
-/* This function is defined in the thread library.  */
-extern void __pthread_clock_settime (clockid_t clock_id, hp_timing_t offset)
-     __attribute__ ((__weak__));
-#endif
-
-
 /* Set CLOCK to value TP.  */
 int
 clock_settime (clockid_t clock_id, const struct timespec *tp)
@@ -70,56 +56,16 @@
 #endif

     default:
-#if HP_TIMING_AVAIL
-      if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1))
-	  != CLOCK_THREAD_CPUTIME_ID)
-#endif
+#ifdef SYSDEP_DEFAULT_SETTIME
+      SYSDEP_DEFAULT_SETTIME;
+#else
 	{
 	  __set_errno (EINVAL);
 	  retval = -1;
 	  break;
 	}

-#if HP_TIMING_AVAIL
-      /* FALLTHROUGH.  */
-    case CLOCK_PROCESS_CPUTIME_ID:
-      {
-	hp_timing_t tsc;
-	hp_timing_t usertime;
-
-	/* First thing is to get the current time.  */
-	HP_TIMING_NOW (tsc);
-
-	if (__builtin_expect (freq == 0, 0))
-	  {
-	    /* This can only happen if we haven't initialized the `freq'
-	       variable yet.  Do this now. We don't have to protect this
-	       code against multiple execution since all of them should
-	       lead to the same result.  */
-	    freq = __get_clockfreq ();
-	    if (__builtin_expect (freq == 0, 0))
-	      {
-		/* Something went wrong.  */
-		retval = -1;
-		break;
-	      }
-	  }
-
-	/* Convert the user-provided time into CPU ticks.  */
-	usertime = tp->tv_sec * freq + (tp->tv_nsec * freq) / 1000000000ull;
-
-	/* Determine the offset and use it as the new base value.  */
-	if (clock_id == CLOCK_PROCESS_CPUTIME_ID
-	    || __pthread_clock_settime == NULL)
-	  GL(dl_cpuclock_offset) = tsc - usertime;
-	else
-	  __pthread_clock_settime (clock_id, tsc - usertime);
-
-	retval = 0;
-      }
-      break;
 #endif
     }
-
   return retval;
 }
Index: libc/sysdeps/unix/sysv/linux/kernel-features.h
===================================================================
--- libc.orig/sysdeps/unix/sysv/linux/kernel-features.h	2004-09-23 16:40:16.491315016 -0700
+++ libc/sysdeps/unix/sysv/linux/kernel-features.h	2004-10-06 12:03:27.941843960 -0700
@@ -419,3 +419,11 @@
 #if __LINUX_KERNEL_VERSION >= 0x020609 && defined __alpha__
 #define __ASSUME_IEEE_RAISE_EXCEPTION	1
 #endif
+
+/* Starting with version 2.6.9, CLOCK_PROCESS/THREAD_CPUTIME_ID are supported
+ * with clock_gettime and also negative clockids to access other processes clocks
+ */
+
+#if __LINUX_KERNEL_VERSION >= 0x020609
+#define __ASSUME_POSIX_IMPROVED	1
+#endif
Index: libc/linuxthreads/sysdeps/pthread/getcpuclockid.c
===================================================================
--- libc.orig/linuxthreads/sysdeps/pthread/getcpuclockid.c	2004-07-12 09:16:56.800919000 -0700
+++ libc/linuxthreads/sysdeps/pthread/getcpuclockid.c	2004-10-06 12:40:44.548828016 -0700
@@ -21,25 +21,14 @@
 #include <sys/time.h>
 #include <time.h>
 #include <internals.h>
+#include <linux/threads.h>

 int
 pthread_getcpuclockid (pthread_t thread_id, clockid_t *clock_id)
 {
 #ifdef CLOCK_THREAD_CPUTIME_ID
-  /* We need to store the thread ID in the CLOCKID variable together
-     with a number identifying the clock.  We reserve the low 3 bits
-     for the clock ID and the rest for the thread ID.  This is
-     problematic if the thread ID is too large.  But 29 bits should be
-     fine.
-
-     If some day more clock IDs are needed the ID part can be
-     enlarged.  The IDs are entirely internal.  */
-  if (2 * PTHREAD_THREADS_MAX
-      >= 1 << (8 * sizeof (*clock_id) - CLOCK_IDFIELD_SIZE))
-    return ERANGE;
-
   /* Store the number.  */
-  *clock_id = CLOCK_THREAD_CPUTIME_ID | (thread_id << CLOCK_IDFIELD_SIZE);
+  *clock_id = - (thread_id + PID_MAX_LIMIT);

   return 0;
 #else
Index: libc/sysdeps/unix/sysv/linux/clock_gettime.c
===================================================================
--- libc.orig/sysdeps/unix/sysv/linux/clock_gettime.c	2004-09-28 15:22:02.359949008 -0700
+++ libc/sysdeps/unix/sysv/linux/clock_gettime.c	2004-10-06 21:21:03.551818168 -0700
@@ -20,24 +20,19 @@

 #include "kernel-features.h"

-
 #ifdef __ASSUME_POSIX_TIMERS
-/* This means the REALTIME and MONOTONIC clock are definitely
-   supported in the kernel.  */
-# define SYSDEP_GETTIME \
-  case CLOCK_REALTIME:							      \
-  case CLOCK_MONOTONIC:							      \
-    retval = INLINE_SYSCALL (clock_gettime, 2, clock_id, tp);		      \
-    break
+#define SYSDEP_DEFAULT_GETTIME { \
+		INTERNAL_SYSCALL_DECL(err); \
+		retval = INTERNAL_SYSCALL(clock_gettime, err, 2, clock_id, tp); \
+	}
+
 #elif defined __NR_clock_gettime
 /* Is the syscall known to exist?  */
 int __libc_missing_posix_timers attribute_hidden;

 /* The REALTIME and MONOTONIC clock might be available.  Try the
    syscall first.  */
-# define SYSDEP_GETTIME \
-  case CLOCK_REALTIME:							      \
-  case CLOCK_MONOTONIC:							      \
+# define SYSDEP_DEFAULT_GETTIME \
     {									      \
       int e = EINVAL;							      \
 									      \
@@ -64,8 +59,7 @@
 	HANDLE_REALTIME;						      \
       else								      \
 	__set_errno (e);						      \
-    }									      \
-    break
+    }
 #endif

 #ifdef __NR_clock_gettime
@@ -74,3 +68,4 @@
 #endif

 #include <sysdeps/unix/clock_gettime.c>
+

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Periodic posix timer support broke between 2.6.9-rc1 and 2.6.9-rc1-bk17
  2004-10-07  4:56                     ` Posix compliant cpu clocks V7 [0/2]: Rationale and test program Christoph Lameter
@ 2004-10-12 20:19                       ` Christoph Lameter
  2004-10-12 22:24                         ` George Anzinger
  2004-10-13 18:08                         ` Alexander Nyberg
  0 siblings, 2 replies; 57+ messages in thread
From: Christoph Lameter @ 2004-10-12 20:19 UTC (permalink / raw)
  To: George Anzinger; +Cc: johnstul, Ulrich.Windl, jbarnes, linux-kernel, roland

I ran some test programs and discovered that the periodic timer support
is broken. The timer is triggered once and then never again. Single shot
timers work fine. 2.6.9-rc1 is fine. The first kernel that I tested where
I noticed the breakage was 2.6.9-rc1-bk17. 2.6.9-rc2 and following all
cannot do periodic timer signals.

I looked through the changelog but I cannot see anything that would cause
the problem. Roland's patch surely could not have done this.

Will try to track this down further, time permitting...

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Periodic posix timer support broke between 2.6.9-rc1 and 2.6.9-rc1-bk17
  2004-10-12 20:19                       ` Periodic posix timer support broke between 2.6.9-rc1 and 2.6.9-rc1-bk17 Christoph Lameter
@ 2004-10-12 22:24                         ` George Anzinger
  2004-10-13 18:08                         ` Alexander Nyberg
  1 sibling, 0 replies; 57+ messages in thread
From: George Anzinger @ 2004-10-12 22:24 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: johnstul, Ulrich.Windl, jbarnes, linux-kernel, roland

Christoph Lameter wrote:
> I ran some test programs and discovered that the periodic timer support
> is broken. The timer is triggered once and then never again. Single shot
> timers work fine. 2.6.9-rc1 is fine. The first kernel that I tested where
> I noticed the breakage was 2.6.9-rc1-bk17. 2.6.9-rc2 and following all
> cannot do periodic timer signals.
> 
> I looked through the changelog but I cannot see anything that would cause
> the problem. Roland's patch surely could not have done this.
> 
> Will try to track this down further, time permitting...

The most likely thing would be failure to do the call back from the signal 
delivery code.
-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Periodic posix timer support broke between 2.6.9-rc1 and 2.6.9-rc1-bk17
  2004-10-12 20:19                       ` Periodic posix timer support broke between 2.6.9-rc1 and 2.6.9-rc1-bk17 Christoph Lameter
  2004-10-12 22:24                         ` George Anzinger
@ 2004-10-13 18:08                         ` Alexander Nyberg
  2004-10-13 18:11                           ` Christoph Lameter
  1 sibling, 1 reply; 57+ messages in thread
From: Alexander Nyberg @ 2004-10-13 18:08 UTC (permalink / raw)
  To: Christoph Lameter
  Cc: George Anzinger, johnstul, Ulrich.Windl, jbarnes, linux-kernel,
	roland, Ingo Molnar

> I ran some test programs and discovered that the periodic timer support
> is broken. The timer is triggered once and then never again. Single shot
> timers work fine. 2.6.9-rc1 is fine. The first kernel that I tested where
> I noticed the breakage was 2.6.9-rc1-bk17. 2.6.9-rc2 and following all
> cannot do periodic timer signals.
> 
> I looked through the changelog but I cannot see anything that would cause
> the problem. Roland's patch surely could not have done this.
> 
> Will try to track this down further, time permitting...

I took a bit of a look at this, and it looks like some things changed
with the introduction of the flexible mmap in 2.6.9-rc1-bk1.

If you run the program below it will work, doing as expected. Now
comment out the the line "memset(&sa, 0, sizeof(struct sigaction));"
and program won't run as expected.

Now do "echo -n 1 > /proc/sys/vm/legacy_va_layout" and run the same
program again (the one with memset commented out).

Turning on signal debugging tells us that with legacy_va_layout=0
"SIG deliver (a.out:415): sp=bffff6c0 pc=08048434 ra=00000000"
where ra is the 8-byte instruction that's supposed to get us back to
sys_sigreturn().

Me thinks someone somewhere is using some of the bits that we
"accidently" pass via sa.sa_flags by not setting it to 0, the regular
flags don't seem to show this behaviour, and I couldn't see any real
checking of the passed value of sa.sa_flags.

---------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/time.h>

void sighandler(int signal)
{
	printf("hihi\n");
}

int main()
{
	struct itimerval timeval;
	struct sigaction sa;
	
	memset(&timeval, 0, sizeof(struct timeval));
	memset(&sa, 0, sizeof(struct sigaction));
	
	sa.sa_handler = &sighandler;
	sigfillset(&sa.sa_mask);
	
	sigaction(SIGALRM, &sa, NULL);
	
	timeval.it_interval.tv_sec = 2;
	timeval.it_interval.tv_usec = 0;
	
	timeval.it_value.tv_sec = 2;
	timeval.it_value.tv_usec = 0;
	
	if (setitimer(ITIMER_REAL, &timeval, NULL))
		printf("Nooo!\n");

	for(;;)
		;

	return 0;
}


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: Periodic posix timer support broke between 2.6.9-rc1 and 2.6.9-rc1-bk17
  2004-10-13 18:08                         ` Alexander Nyberg
@ 2004-10-13 18:11                           ` Christoph Lameter
  0 siblings, 0 replies; 57+ messages in thread
From: Christoph Lameter @ 2004-10-13 18:11 UTC (permalink / raw)
  To: Alexander Nyberg
  Cc: George Anzinger, johnstul, Ulrich.Windl, jbarnes, linux-kernel,
	roland, Ingo Molnar

> Me thinks someone somewhere is using some of the bits that we
> "accidently" pass via sa.sa_flags by not setting it to 0, the regular
> flags don't seem to show this behaviour, and I couldn't see any real
> checking of the passed value of sa.sa_flags.

Nope. It was my screwed up setting of the resolution of CLOCK_REALTIME and
CLOCK_MONOTONIC. Fix was submitted to Linus and Andrew.


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Posix compliant process clock patch for the linux arch in glibc
  2004-09-28 19:18             ` Ulrich Drepper
  2004-09-28 19:25               ` Christoph Lameter
  2004-09-29  3:25               ` Posix compliant CLOCK_PROCESS/THREAD_CPUTIME_ID V4 Christoph Lameter
@ 2004-10-21 19:32               ` Christoph Lameter
  2 siblings, 0 replies; 57+ messages in thread
From: Christoph Lameter @ 2004-10-21 19:32 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: johnstul, Ulrich.Windl, george, linux-kernel, libc-alpha

Patches were recently accepted into Linus tree for 2.6.10 to implement
posix compliant process clocks. The current glibc code does not provide
access to process and thread clocks of other processes and contains an
implementation of CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID
that returns the time that the process/thread has been running instead of
the cputime spend on the process. This patch makes glibc to use the new
linux kernel abilities instead of improvising these clocks. In addition
clockids unknown to glibc are forwarded the kernel instead of glibc
returning an error immediately. This allow the use of new clocks provided
by the kernel such as CLOCK_SGI_CYCLE.

POSIX clocks are to be implemented in the following way according
to V3 of the Single Unix Specification:

1. CLOCK_PROCESS_CPUTIME_ID

  Implementations shall also support the special clockid_t value
  CLOCK_PROCESS_CPUTIME_ID, which represents the CPU-time clock of the
  calling process when invoking one of the clock_*() or timer_*()
  functions. For these clock IDs, the values returned by clock_gettime() and
  specified by clock_settime() represent the amount of execution time of the
  process associated with the clock.

2. CLOCK_THREAD_CPUTIME_ID

  Implementations shall also support the special clockid_t value
  CLOCK_THREAD_CPUTIME_ID, which represents the CPU-time clock of the
  calling thread when invoking one of the clock_*() or timer_*()
  functions. For these clock IDs, the values returned by clock_gettime()
  and specified by clock_settime() shall represent the amount of
  execution time of the thread associated with the clock.

These times mentioned are CPU processing times and not the time that has
passed since the startup of a process. Glibc currently provides its own
implementation of these two clocks which is designed to return the time
that passed since the startup of a process or a thread.

Moreover glibc's clocks are bound to CPU timers which is problematic when
the frequency of the clock changes or the process is moved to a different
processor whose cpu timer may not be fully synchronized to the cpu timer
of the current CPU. The use of th kernel posix timer function results in
both clocks always working reliably.

The patch also implements access to other the thread and process clocks
of linux processes by using negative clockid's:

1. For CLOCK_PROCESS_CPUTIME_ID: -pid
2. For CLOCK_THREAD_CPUTIME_ID: -(pid + PID_MAX_LIMIT)

This allows

clock_getcpuclockid(pid) to return -pid

and

pthread_getcpuiclock(pid) to return -(pid + PID_MAX_LIMIT)

to allow access to the corresponding clocks.

This patch will make attempts to use process clocks or CLOCK_PROCESS_CPUTIME_ID and
CLOCK_THREAD_CPUTIME_ID return error codes on kernels earlier than 2.6.10 because glibc
is current not able to provide these clocks in POSIX conformant way on its own.

Software written under Linux that assumes these clocks to return high precision light
weight real time values derived from a cpu timer (as in the current emulation by glibc)
will break!

Feedback would be appreciated especially since I am not a glibc expert.

Signed-off-by: Christoph Lameter <clameter@sgi.com>

Index: libc/nptl/sysdeps/pthread/pthread_getcpuclockid.c
===================================================================
--- libc.orig/nptl/sysdeps/pthread/pthread_getcpuclockid.c	2003-06-24 16:53:20.000000000 -0700
+++ libc/nptl/sysdeps/pthread/pthread_getcpuclockid.c	2004-10-21 11:05:11.295178056 -0700
@@ -20,7 +20,7 @@
 #include <pthreadP.h>
 #include <sys/time.h>
 #include <tls.h>
-
+#include <linux/threads.h>

 int
 pthread_getcpuclockid (threadid, clockid)
@@ -35,19 +35,8 @@
     return ESRCH;

 #ifdef CLOCK_THREAD_CPUTIME_ID
-  /* We need to store the thread ID in the CLOCKID variable together
-     with a number identifying the clock.  We reserve the low 3 bits
-     for the clock ID and the rest for the thread ID.  This is
-     problematic if the thread ID is too large.  But 29 bits should be
-     fine.
-
-     If some day more clock IDs are needed the ID part can be
-     enlarged.  The IDs are entirely internal.  */
-  if (pd->tid >= 1 << (8 * sizeof (*clockid) - CLOCK_IDFIELD_SIZE))
-    return ERANGE;
-
   /* Store the number.  */
-  *clockid = CLOCK_THREAD_CPUTIME_ID | (pd->tid << CLOCK_IDFIELD_SIZE);
+  *clockid = - (pd->tid + PID_MAX_LIMIT);

   return 0;
 #else
Index: libc/sysdeps/unix/sysv/linux/clock_getres.c
===================================================================
--- libc.orig/sysdeps/unix/sysv/linux/clock_getres.c	2004-09-28 15:22:02.351950224 -0700
+++ libc/sysdeps/unix/sysv/linux/clock_getres.c	2004-10-21 11:05:11.297177752 -0700
@@ -20,24 +20,17 @@

 #include "kernel-features.h"

-
 #ifdef __ASSUME_POSIX_TIMERS
-/* This means the REALTIME and MONOTONIC clock are definitely
-   supported in the kernel.  */
-# define SYSDEP_GETRES \
-  case CLOCK_REALTIME:							      \
-  case CLOCK_MONOTONIC:							      \
-    retval = INLINE_SYSCALL (clock_getres, 2, clock_id, res);		      \
-    break
+/* we have to rely on the kernel */
+#define SYSDEP_DEFAULT_GETRES retval = INLINE_SYSCALL(clock_getres, err, 2, clock_id, res)
+
 #elif defined __NR_clock_getres
 /* Is the syscall known to exist?  */
 extern int __libc_missing_posix_timers attribute_hidden;

 /* The REALTIME and MONOTONIC clock might be available.  Try the
    syscall first.  */
-# define SYSDEP_GETRES \
-  case CLOCK_REALTIME:							      \
-  case CLOCK_MONOTONIC:							      \
+# define SYSDEP_DEFAULT_GETRES \
     {									      \
       int e = EINVAL;							      \
 									      \
@@ -65,7 +58,7 @@
       else								      \
 	__set_errno (e);						      \
     }									      \
-    break
+
 #endif

 #ifdef __NR_clock_getres
Index: libc/sysdeps/unix/clock_gettime.c
===================================================================
--- libc.orig/sysdeps/unix/clock_gettime.c	2004-09-28 15:22:02.192974392 -0700
+++ libc/sysdeps/unix/clock_gettime.c	2004-10-21 11:05:11.300177296 -0700
@@ -23,21 +23,6 @@
 #include <libc-internal.h>
 #include <ldsodefs.h>

-
-#if HP_TIMING_AVAIL
-/* Clock frequency of the processor.  We make it a 64-bit variable
-   because some jokers are already playing with processors with more
-   than 4GHz.  */
-static hp_timing_t freq;
-
-
-/* This function is defined in the thread library.  */
-extern int __pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq,
-				    struct timespec *tp)
-     __attribute__ ((__weak__));
-#endif
-
-
 /* Get current value of CLOCK and store it in TP.  */
 int
 clock_gettime (clockid_t clock_id, struct timespec *tp)
@@ -66,58 +51,14 @@
 #endif

     default:
-#if HP_TIMING_AVAIL
-      if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1))
-	  != CLOCK_THREAD_CPUTIME_ID)
-#endif
+#ifdef SYSDEP_DEFAULT_GETTIME
+      SYSDEP_DEFAULT_GETTIME;
+#else
 	{
 	  __set_errno (EINVAL);
 	  break;
 	}
-
-#if HP_TIMING_AVAIL
-      /* FALLTHROUGH.  */
-    case CLOCK_PROCESS_CPUTIME_ID:
-      {
-	hp_timing_t tsc;
-
-	if (__builtin_expect (freq == 0, 0))
-	  {
-	    /* This can only happen if we haven't initialized the `freq'
-	       variable yet.  Do this now. We don't have to protect this
-	       code against multiple execution since all of them should
-	       lead to the same result.  */
-	    freq = __get_clockfreq ();
-	    if (__builtin_expect (freq == 0, 0))
-	      /* Something went wrong.  */
-	      break;
-	  }
-
-	if (clock_id != CLOCK_PROCESS_CPUTIME_ID
-	    && __pthread_clock_gettime != NULL)
-	  {
-	    retval = __pthread_clock_gettime (clock_id, freq, tp);
-	    break;
-	  }
-
-	/* Get the current counter.  */
-	HP_TIMING_NOW (tsc);
-
-	/* Compute the offset since the start time of the process.  */
-	tsc -= GL(dl_cpuclock_offset);
-
-	/* Compute the seconds.  */
-	tp->tv_sec = tsc / freq;
-
-	/* And the nanoseconds.  This computation should be stable until
-	   we get machines with about 16GHz frequency.  */
-	tp->tv_nsec = ((tsc % freq) * UINT64_C (1000000000)) / freq;
-
-	retval = 0;
-      }
-    break;
 #endif
     }
-
   return retval;
 }
Index: libc/sysdeps/unix/sysv/linux/ia64/clock_getcpuclockid.c
===================================================================
--- libc.orig/sysdeps/unix/sysv/linux/ia64/clock_getcpuclockid.c	2004-10-21 11:04:12.855062304 -0700
+++ /dev/null1970-01-01 00:00:00.000000000 +0000
@@ -1,47 +0,0 @@
-/* Copyright (C) 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#include <errno.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <fcntl.h>
-
-
-#include "has_cpuclock.c"
-
-
-int
-clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
-{
-  /* We don't allow any process ID but our own.  */
-  if (pid != 0 && pid != getpid ())
-    return EPERM;
-
-  int retval = ENOENT;
-
-  if (has_cpuclock () > 0)
-    {
-      /* Store the number.  */
-      *clock_id = CLOCK_PROCESS_CPUTIME_ID;
-      retval = 0;
-    }
-
-  return retval;
-}
Index: libc/sysdeps/unix/sysv/linux/clock_settime.c
===================================================================
--- libc.orig/sysdeps/unix/sysv/linux/clock_settime.c	2004-10-01 10:27:15.007445832 -0700
+++ libc/sysdeps/unix/sysv/linux/clock_settime.c	2004-10-21 11:05:11.326173344 -0700
@@ -20,21 +20,15 @@

 #include "kernel-features.h"

-
 #ifdef __ASSUME_POSIX_TIMERS
-/* This means the REALTIME clock is definitely supported in the
-   kernel.  */
-# define SYSDEP_SETTIME \
-  case CLOCK_REALTIME:							      \
-    retval = INLINE_SYSCALL (clock_settime, 2, clock_id, tp);		      \
-    break
+#define SYSDEP_DEFAULT_SETTIME retval = INLINE_SYSCALL(clock_settime, 2, clock_id, tp)
+
 #elif defined __NR_clock_settime
 /* Is the syscall known to exist?  */
 extern int __libc_missing_posix_timers attribute_hidden;

 /* The REALTIME clock might be available.  Try the syscall first.  */
-# define SYSDEP_SETTIME \
-  case CLOCK_REALTIME:							      \
+# define SYSDEP_DEFAULT_SETTIME \
     {									      \
       int e = EINVAL;							      \
 									      \
@@ -64,8 +58,7 @@
 	  __set_errno (e);						      \
 	  retval = -1;							      \
 	}								      \
-    }									      \
-    break
+    }
 #endif

 #ifdef __NR_clock_settime
Index: libc/sysdeps/unix/sysv/linux/clock_getcpuclockid.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ libc/sysdeps/unix/sysv/linux/clock_getcpuclockid.c	2004-10-21 11:05:11.327173192 -0700
@@ -0,0 +1,46 @@
+
+/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <time.h>
+#include <unistd.h>
+#include <kernel-features.h>
+
+int
+clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
+{
+  if (pid != 0 && pid != getpid ())
+#ifdef __ASSUME_POSIX_TIMERS
+	*clock_id = -pid;
+	return 0;
+#else
+/* We don't allow any process ID but our own.  */
+    return EPERM;
+#endif
+
+#ifdef CLOCK_PROCESS_CPUTIME_ID
+  /* Store the number.  */
+  *clock_id = CLOCK_PROCESS_CPUTIME_ID;
+
+  return 0;
+#else
+  /* We don't have a timer for that.  */
+  return ENOENT;
+#endif
+}
Index: libc/sysdeps/posix/clock_getres.c
===================================================================
--- libc.orig/sysdeps/posix/clock_getres.c	2004-09-28 15:22:02.032998712 -0700
+++ libc/sysdeps/posix/clock_getres.c	2004-10-21 11:05:11.329172888 -0700
@@ -23,13 +23,6 @@
 #include <sys/param.h>
 #include <libc-internal.h>

-
-#if HP_TIMING_AVAIL && !defined HANDLED_CPUTIME
-/* Clock frequency of the processor.  */
-static long int nsec;
-#endif
-
-
 /* Get resolution of clock.  */
 int
 clock_getres (clockid_t clock_id, struct timespec *res)
@@ -65,44 +58,15 @@
 #endif	/* handled REALTIME */

     default:
-#if HP_TIMING_AVAIL
-      if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1))
-	  != CLOCK_THREAD_CPUTIME_ID)
-#endif
-	{
+#ifdef SYSDEP_DEFAULT_GETRES
+      SYSDEP_DEFAULT_GETRES;
+#else
+      {
 	  __set_errno (EINVAL);
 	  break;
 	}
-
-#if HP_TIMING_AVAIL && !defined HANDLED_CPUTIME
-      /* FALLTHROUGH.  */
-    case CLOCK_PROCESS_CPUTIME_ID:
-      {
-	if (__builtin_expect (nsec == 0, 0))
-	  {
-	    hp_timing_t freq;
-
-	    /* This can only happen if we haven't initialized the `freq'
-	       variable yet.  Do this now. We don't have to protect this
-	       code against multiple execution since all of them should
-	       lead to the same result.  */
-	    freq = __get_clockfreq ();
-	    if (__builtin_expect (freq == 0, 0))
-	      /* Something went wrong.  */
-	      break;
-
-	    nsec = MAX (UINT64_C (1000000000) / freq, 1);
-	  }
-
-	/* File in the values.  The seconds are always zero (unless we
-	   have a 1Hz machine).  */
-	res->tv_sec = 0;
-	res->tv_nsec = nsec;
-
-	retval = 0;
-      }
-      break;
 #endif
+
     }

   return retval;
Index: libc/sysdeps/unix/clock_settime.c
===================================================================
--- libc.orig/sysdeps/unix/clock_settime.c	2004-10-01 10:26:04.247203024 -0700
+++ libc/sysdeps/unix/clock_settime.c	2004-10-21 11:05:11.331172584 -0700
@@ -22,20 +22,6 @@
 #include <libc-internal.h>
 #include <ldsodefs.h>

-
-#if HP_TIMING_AVAIL
-/* Clock frequency of the processor.  We make it a 64-bit variable
-   because some jokers are already playing with processors with more
-   than 4GHz.  */
-static hp_timing_t freq;
-
-
-/* This function is defined in the thread library.  */
-extern void __pthread_clock_settime (clockid_t clock_id, hp_timing_t offset)
-     __attribute__ ((__weak__));
-#endif
-
-
 /* Set CLOCK to value TP.  */
 int
 clock_settime (clockid_t clock_id, const struct timespec *tp)
@@ -70,56 +56,16 @@
 #endif

     default:
-#if HP_TIMING_AVAIL
-      if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1))
-	  != CLOCK_THREAD_CPUTIME_ID)
-#endif
+#ifdef SYSDEP_DEFAULT_SETTIME
+      SYSDEP_DEFAULT_SETTIME;
+#else
 	{
 	  __set_errno (EINVAL);
 	  retval = -1;
 	  break;
 	}

-#if HP_TIMING_AVAIL
-      /* FALLTHROUGH.  */
-    case CLOCK_PROCESS_CPUTIME_ID:
-      {
-	hp_timing_t tsc;
-	hp_timing_t usertime;
-
-	/* First thing is to get the current time.  */
-	HP_TIMING_NOW (tsc);
-
-	if (__builtin_expect (freq == 0, 0))
-	  {
-	    /* This can only happen if we haven't initialized the `freq'
-	       variable yet.  Do this now. We don't have to protect this
-	       code against multiple execution since all of them should
-	       lead to the same result.  */
-	    freq = __get_clockfreq ();
-	    if (__builtin_expect (freq == 0, 0))
-	      {
-		/* Something went wrong.  */
-		retval = -1;
-		break;
-	      }
-	  }
-
-	/* Convert the user-provided time into CPU ticks.  */
-	usertime = tp->tv_sec * freq + (tp->tv_nsec * freq) / 1000000000ull;
-
-	/* Determine the offset and use it as the new base value.  */
-	if (clock_id == CLOCK_PROCESS_CPUTIME_ID
-	    || __pthread_clock_settime == NULL)
-	  GL(dl_cpuclock_offset) = tsc - usertime;
-	else
-	  __pthread_clock_settime (clock_id, tsc - usertime);
-
-	retval = 0;
-      }
-      break;
 #endif
     }
-
   return retval;
 }
Index: libc/sysdeps/unix/sysv/linux/kernel-features.h
===================================================================
--- libc.orig/sysdeps/unix/sysv/linux/kernel-features.h	2004-09-23 16:40:16.491315016 -0700
+++ libc/sysdeps/unix/sysv/linux/kernel-features.h	2004-10-21 11:05:11.333172280 -0700
@@ -419,3 +419,11 @@
 #if __LINUX_KERNEL_VERSION >= 0x020609 && defined __alpha__
 #define __ASSUME_IEEE_RAISE_EXCEPTION	1
 #endif
+
+/* Starting with version 2.6.9, CLOCK_PROCESS/THREAD_CPUTIME_ID are supported
+ * with clock_gettime and also negative clockids to access other processes clocks
+ */
+
+#if __LINUX_KERNEL_VERSION >= 0x020609
+#define __ASSUME_POSIX_IMPROVED	1
+#endif
Index: libc/linuxthreads/sysdeps/pthread/getcpuclockid.c
===================================================================
--- libc.orig/linuxthreads/sysdeps/pthread/getcpuclockid.c	2004-07-12 09:16:56.800919000 -0700
+++ libc/linuxthreads/sysdeps/pthread/getcpuclockid.c	2004-10-21 11:05:11.334172128 -0700
@@ -21,25 +21,14 @@
 #include <sys/time.h>
 #include <time.h>
 #include <internals.h>
+#include <linux/threads.h>

 int
 pthread_getcpuclockid (pthread_t thread_id, clockid_t *clock_id)
 {
 #ifdef CLOCK_THREAD_CPUTIME_ID
-  /* We need to store the thread ID in the CLOCKID variable together
-     with a number identifying the clock.  We reserve the low 3 bits
-     for the clock ID and the rest for the thread ID.  This is
-     problematic if the thread ID is too large.  But 29 bits should be
-     fine.
-
-     If some day more clock IDs are needed the ID part can be
-     enlarged.  The IDs are entirely internal.  */
-  if (2 * PTHREAD_THREADS_MAX
-      >= 1 << (8 * sizeof (*clock_id) - CLOCK_IDFIELD_SIZE))
-    return ERANGE;
-
   /* Store the number.  */
-  *clock_id = CLOCK_THREAD_CPUTIME_ID | (thread_id << CLOCK_IDFIELD_SIZE);
+  *clock_id = - (thread_id + PID_MAX_LIMIT);

   return 0;
 #else
Index: libc/sysdeps/unix/sysv/linux/clock_gettime.c
===================================================================
--- libc.orig/sysdeps/unix/sysv/linux/clock_gettime.c	2004-09-28 15:22:02.359949008 -0700
+++ libc/sysdeps/unix/sysv/linux/clock_gettime.c	2004-10-21 11:05:11.336171824 -0700
@@ -20,24 +20,16 @@

 #include "kernel-features.h"

-
 #ifdef __ASSUME_POSIX_TIMERS
-/* This means the REALTIME and MONOTONIC clock are definitely
-   supported in the kernel.  */
-# define SYSDEP_GETTIME \
-  case CLOCK_REALTIME:							      \
-  case CLOCK_MONOTONIC:							      \
-    retval = INLINE_SYSCALL (clock_gettime, 2, clock_id, tp);		      \
-    break
+#define SYSDEP_DEFAULT_GETTIME retval = INLINE_SYSCALL(clock_gettime, 2, clock_id, tp)
+
 #elif defined __NR_clock_gettime
 /* Is the syscall known to exist?  */
 int __libc_missing_posix_timers attribute_hidden;

 /* The REALTIME and MONOTONIC clock might be available.  Try the
    syscall first.  */
-# define SYSDEP_GETTIME \
-  case CLOCK_REALTIME:							      \
-  case CLOCK_MONOTONIC:							      \
+# define SYSDEP_DEFAULT_GETTIME \
     {									      \
       int e = EINVAL;							      \
 									      \
@@ -64,8 +56,7 @@
 	HANDLE_REALTIME;						      \
       else								      \
 	__set_errno (e);						      \
-    }									      \
-    break
+    }
 #endif

 #ifdef __NR_clock_gettime
@@ -74,3 +65,4 @@
 #endif

 #include <sysdeps/unix/clock_gettime.c>
+


^ permalink raw reply	[flat|nested] 57+ messages in thread

end of thread, other threads:[~2004-10-22  4:43 UTC | newest]

Thread overview: 57+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <B6E8046E1E28D34EB815A11AC8CA312902CD3264@mtv-atc-605e--n.corp.sgi.com>
2004-09-24 12:16 ` [time] add support for CLOCK_THREAD_CPUTIME_ID and CLOCK_PROCESS_CPUTIME_ID Christoph Lameter
2004-09-25  4:25   ` Ulrich Drepper
2004-09-25  5:25     ` Christoph Lameter
2004-09-25  5:54     ` Christoph Lameter
2004-09-25  6:08       ` Ulrich Drepper
2004-09-25 14:51         ` Christoph Lameter
2004-09-25 15:19           ` Ulrich Drepper
2004-09-27 15:03             ` Christoph Lameter
2004-09-27 15:34         ` Christoph Lameter
     [not found]         ` <B6E8046E1E28D34EB815A11AC8CA312902CD327E@mtv-atc-605e--n.corp.sgi.com>
2004-09-27 20:58           ` [RFC] Posix compliant behavior of CLOCK_PROCESS/THREAD_CPUTIME_ID Christoph Lameter
2004-09-27 22:54             ` George Anzinger
2004-09-28 19:18             ` Ulrich Drepper
2004-09-28 19:25               ` Christoph Lameter
2004-09-29  3:25               ` Posix compliant CLOCK_PROCESS/THREAD_CPUTIME_ID V4 Christoph Lameter
2004-09-29 17:45                 ` George Anzinger
2004-09-29 18:14                   ` Christoph Lameter
2004-09-29 19:27                     ` George Anzinger
2004-09-29 19:34                       ` Christoph Lameter
2004-09-29 19:52                       ` Jesper Juhl
2004-09-30  0:14                         ` patches inline in mail George Anzinger
2004-09-30  3:24                           ` Paul Jackson
2004-10-01  5:29                           ` Andrew Morton
2004-10-01 12:28                             ` Alan Cox
2004-10-01 13:42                               ` Paul Fulghum
2004-10-01 19:53                                 ` Lee Revell
2004-10-01 21:58                               ` George Anzinger
2004-10-02 15:52                                 ` Olaf Dietsche
2004-10-02 15:20                                   ` Alan Cox
2004-10-03 21:01                                     ` [OT] " Guennadi Liakhovetski
2004-10-03 23:18                                       ` Jesper Juhl
2004-10-04  6:20                                       ` Paul Jackson
2004-10-04 19:11                                         ` Guennadi Liakhovetski
2004-10-04  7:26                                       ` Ulrich Windl
2004-10-03 21:35                                     ` George Anzinger
2004-10-04  3:00                                       ` Jim Nelson
2004-10-01  9:04                           ` Jesper Juhl
2004-09-29 19:32                   ` Posix compliant CLOCK_PROCESS/THREAD_CPUTIME_ID V5 Christoph Lameter
2004-10-01 19:57                   ` Posix compliant cpu clocks V6 [0/3]: Rationale and test program Christoph Lameter
     [not found]                   ` <B6E8046E1E28D34EB815A11AC8CA31290322B307@mtv-atc-605e--n.corp.sgi.com>
2004-10-01 19:59                     ` Posix compliant cpu clocks V6 [1/3]: Generic Kernel patch Christoph Lameter
2004-10-01 21:03                       ` Andrew Morton
2004-10-01 20:01                     ` Posix compliant cpu clocks V6 [2/3]: Glibc patch Christoph Lameter
2004-10-02  5:32                       ` Ulrich Drepper
2004-10-04 15:04                         ` Christoph Lameter
2004-10-04 16:27                         ` Christoph Lameter
2004-10-06 13:53                         ` Martijn Sipkema
2004-10-01 20:02                     ` Posix compliant cpu clocks V6 [3/3]: mmtimer provides CLOCK_SGI_CYCLE Christoph Lameter
2004-10-07  4:56                     ` Posix compliant cpu clocks V7 [0/2]: Rationale and test program Christoph Lameter
2004-10-12 20:19                       ` Periodic posix timer support broke between 2.6.9-rc1 and 2.6.9-rc1-bk17 Christoph Lameter
2004-10-12 22:24                         ` George Anzinger
2004-10-13 18:08                         ` Alexander Nyberg
2004-10-13 18:11                           ` Christoph Lameter
     [not found]                     ` <B6E8046E1E28D34EB815A11AC8CA31290322B331@mtv-atc-605e--n.corp.sgi.com>
2004-10-07  4:57                       ` Posix compliant cpu clocks V7 [1/2]: Kernel Patch Christoph Lameter
2004-10-07  4:59                       ` Posix compliant cpu clocks V7 [2/2]: Glibc patch Christoph Lameter
2004-10-21 19:32               ` Posix compliant process clock patch for the linux arch in glibc Christoph Lameter
2004-10-01 21:57             ` [RFC] Posix compliant behavior of CLOCK_PROCESS/THREAD_CPUTIME_ID Roland McGrath
2004-10-01 23:30               ` Christoph Lameter
2004-10-04 18:48               ` RFC: Posix compliant clock_getclockcpuid(pid) to access other processes clocks Christoph Lameter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.