RFC: Posix compliant clock_getclockcpuid(pid) to access otherprocesses clocks

From: Christoph Lameter
Date: Mon Oct 04 2004 - 13:53:21 EST


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;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/