Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
* rt/tst-cpuclock1.c: New file.
	* rt/tst-cpuclock2.c: New file.
	* rt/tst-cputimer1.c: New file.
	* rt/tst-cputimer2.c: New file.
	* rt/tst-cputimer3.c: New file.
	* rt/Makefile (tests): Add them.

	* sysdeps/unix/sysv/linux/kernel-posix-cpu-timers.h: New file.
	* sysdeps/unix/sysv/linux/clock_getcpuclockid.c: New file.
	* sysdeps/unix/sysv/linux/ia64/clock_getcpuclockid.c
	(HAS_CPUCLOCK): New macro.
	(clock_getcpuclockid): Function removed.
	#include the new linux file to define it instead.
	* sysdeps/unix/clock_gettime.c [HP_TIMING_AVAIL] (hp_timing_gettime):
	New function, broken out of ...
	(clock_gettime) [HP_TIMING_AVAIL]: ... here.  Call it.
	(realtime_gettime): New function, broken out of ...
	(clock_gettime) [! HANDLED_REALTIME]: ... here.  Call it.
	(clock_gettime) [SYSDEP_GETTIME_CPU]: Use new macro in default case.
	* sysdeps/unix/sysv/linux/clock_gettime.c (SYSCALL_GETTIME): New macro.
	(SYSDEP_GETTIME_CPUTIME): New macro.
	(SYSDEP_GETTIME): Use both.
	[! __ASSUME_POSIX_TIMERS] (maybe_syscall_gettime): New function, broken
	out of ...
	(SYSDEP_GETTIME): ... here.  Use it.
	[__NR_clock_gettime] (HANDLED_CPUTIME): Define it.
	(SYSDEP_GETTIME_CPUTIME): New macro.  Handle CPU timers by trying
	kernel support and falling back to hp-timing code.
	* sysdeps/posix/clock_getres.c
	[HP_TIMING_AVAIL] (hp_timing_getres): New function, broken out of ...
	(clock_getres) [HP_TIMING_AVAIL]: ... here.  Call it.
	(realtime_getres): New function, broken out of ...
	(clock_getres) [! HANDLED_REALTIME]: ... here.  Call it.
	(clock_getres) [SYSDEP_GETRES_CPU]: Use new macro in default case.
	* sysdeps/unix/sysv/linux/clock_getres.c (SYSCALL_GETRES): New macro.
	(SYSDEP_GETRES_CPUTIME): New macro.
	(SYSDEP_GETRES): Use both.
	[! __ASSUME_POSIX_TIMERS] (maybe_syscall_getres): New function, broken
	out of ...
	(SYSDEP_GETRES): ... here.  Use it.
	[__NR_clock_getres] (HANDLED_CPUTIME): Define it.
	(SYSDEP_GETRES_CPUTIME): New macro.  Handle CPU timers by trying
	kernel support and falling back to hp-timing code.
	* sysdeps/unix/sysv/linux/clock_nanosleep.c: Handle
	CLOCK_PROCESS_CPUTIME_ID and CLOCK_PROCESS_THREAD_ID specially,
	translating to the kernel clockid_t for our own process/thread clock.
  • Loading branch information
Roland McGrath committed Apr 27, 2005
1 parent 2f4f3bd commit 84060ba
Show file tree
Hide file tree
Showing 12 changed files with 1,174 additions and 5 deletions.
49 changes: 49 additions & 0 deletions ChangeLog
@@ -1,3 +1,52 @@
2005-04-27 Roland McGrath <roland@redhat.com>

* rt/tst-cpuclock1.c: New file.
* rt/tst-cpuclock2.c: New file.
* rt/tst-cputimer1.c: New file.
* rt/tst-cputimer2.c: New file.
* rt/tst-cputimer3.c: New file.
* rt/Makefile (tests): Add them.

* sysdeps/unix/sysv/linux/kernel-posix-cpu-timers.h: New file.
* sysdeps/unix/sysv/linux/clock_getcpuclockid.c: New file.
* sysdeps/unix/sysv/linux/ia64/clock_getcpuclockid.c
(HAS_CPUCLOCK): New macro.
(clock_getcpuclockid): Function removed.
#include the new linux file to define it instead.
* sysdeps/unix/clock_gettime.c [HP_TIMING_AVAIL] (hp_timing_gettime):
New function, broken out of ...
(clock_gettime) [HP_TIMING_AVAIL]: ... here. Call it.
(realtime_gettime): New function, broken out of ...
(clock_gettime) [! HANDLED_REALTIME]: ... here. Call it.
(clock_gettime) [SYSDEP_GETTIME_CPU]: Use new macro in default case.
* sysdeps/unix/sysv/linux/clock_gettime.c (SYSCALL_GETTIME): New macro.
(SYSDEP_GETTIME_CPUTIME): New macro.
(SYSDEP_GETTIME): Use both.
[! __ASSUME_POSIX_TIMERS] (maybe_syscall_gettime): New function, broken
out of ...
(SYSDEP_GETTIME): ... here. Use it.
[__NR_clock_gettime] (HANDLED_CPUTIME): Define it.
(SYSDEP_GETTIME_CPUTIME): New macro. Handle CPU timers by trying
kernel support and falling back to hp-timing code.
* sysdeps/posix/clock_getres.c
[HP_TIMING_AVAIL] (hp_timing_getres): New function, broken out of ...
(clock_getres) [HP_TIMING_AVAIL]: ... here. Call it.
(realtime_getres): New function, broken out of ...
(clock_getres) [! HANDLED_REALTIME]: ... here. Call it.
(clock_getres) [SYSDEP_GETRES_CPU]: Use new macro in default case.
* sysdeps/unix/sysv/linux/clock_getres.c (SYSCALL_GETRES): New macro.
(SYSDEP_GETRES_CPUTIME): New macro.
(SYSDEP_GETRES): Use both.
[! __ASSUME_POSIX_TIMERS] (maybe_syscall_getres): New function, broken
out of ...
(SYSDEP_GETRES): ... here. Use it.
[__NR_clock_getres] (HANDLED_CPUTIME): Define it.
(SYSDEP_GETRES_CPUTIME): New macro. Handle CPU timers by trying
kernel support and falling back to hp-timing code.
* sysdeps/unix/sysv/linux/clock_nanosleep.c: Handle
CLOCK_PROCESS_CPUTIME_ID and CLOCK_PROCESS_THREAD_ID specially,
translating to the kernel clockid_t for our own process/thread clock.

2005-04-27 Ulrich Drepper <drepper@redhat.com>

* stdlib/test-canon.c: Make doesExist a directory and add more tests
Expand Down
5 changes: 5 additions & 0 deletions linuxthreads/ChangeLog
@@ -1,3 +1,8 @@
2005-04-27 Roland McGrath <roland@redhat.com>

* sysdeps/pthread/getcpuclockid.c (pthread_getcpuclockid)
[__NR_clock_getres]: Use kernel-supplied CPU clocks if available.

2005-03-31 Jakub Jelinek <jakub@redhat.com>

* sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h: Use
Expand Down
69 changes: 68 additions & 1 deletion linuxthreads/sysdeps/pthread/getcpuclockid.c
@@ -1,4 +1,5 @@
/* Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
/* pthread_getcpuclockid -- Get POSIX clockid_t for a pthread_t. Linux version
Copyright (C) 2000, 2001, 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
Expand All @@ -21,10 +22,76 @@
#include <sys/time.h>
#include <time.h>
#include <internals.h>
#include "kernel-features.h"
#include "posix-cpu-timers.h"


#if !(__ASSUME_POSIX_CPU_TIMERS > 0)
int __libc_missing_posix_cpu_timers attribute_hidden;
#endif
#if !(__ASSUME_POSIX_TIMERS > 0)
int __libc_missing_posix_timers attribute_hidden;
#endif

int
pthread_getcpuclockid (pthread_t thread_id, clockid_t *clock_id)
{
#ifdef __NR_clock_getres
pthread_handle handle = thread_handle(thread_id);
int pid;

__pthread_lock (&handle->h_lock, NULL);
if (nonexisting_handle (handle, thread_id))
{
__pthread_unlock (&handle->h_lock);
return ESRCH;
}
pid = handle->h_descr->p_pid;
__pthread_unlock (&handle->h_lock);

/* The clockid_t value is a simple computation from the PID.
But we do a clock_getres call to validate it if we aren't
yet sure we have the kernel support. */

const clockid_t pidclock = MAKE_PROCESS_CPUCLOCK (pid, CPUCLOCK_SCHED);

# if !(__ASSUME_POSIX_CPU_TIMERS > 0)
# if !(__ASSUME_POSIX_TIMERS > 0)
if (__libc_missing_posix_timers && !__libc_missing_posix_cpu_timers)
__libc_missing_cpu_posix_timers = 1;
# endif
if (!__libc_missing_posix_cpu_timers)
{
INTERNAL_SYSCALL_DECL (err);
int r = INTERNAL_SYSCALL (clock_getres, err, 2, tidclock, NULL);
if (!INTERNAL_SYSCALL_ERROR_P (r, err))
# endif
{
*clock_id = pidclock;
return 0;
}

# if !(__ASSUME_POSIX_CPU_TIMERS > 0)
# if !(__ASSUME_POSIX_TIMERS > 0)
if (INTERNAL_SYSCALL_ERRNO (r, err) == ENOSYS)
{
/* The kernel doesn't support these calls at all. */
__libc_missing_posix_timers = 1;
__libc_missing_posix_cpu_timers = 1;
}
else
# endif
if (INTERNAL_SYSCALL_ERRNO (r, err) == EINVAL)
{
/* The kernel doesn't support these clocks at all. */
__libc_missing_posix_cpu_timers = 1;
}
else
return INTERNAL_SYSCALL_ERRNO (r, err);
}
# endif
#endif

#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
Expand Down
8 changes: 8 additions & 0 deletions nptl/ChangeLog
@@ -1,3 +1,11 @@
2005-04-27 Roland McGrath <roland@redhat.com>

* sysdeps/unix/sysv/linux/timer_create.c (timer_create): Handle
CLOCK_PROCESS_CPUTIME_ID and CLOCK_PROCESS_THREAD_ID specially,
translating to the kernel clockid_t for our own process/thread clock.

* sysdeps/unix/sysv/linux/pthread_getcpuclockid.c: New file.

2005-04-15 Jakub Jelinek <jakub@redhat.com>

* old_pthread_cond_init.c: Include <errno.h>.
Expand Down
111 changes: 111 additions & 0 deletions nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c
@@ -0,0 +1,111 @@
/* pthread_getcpuclockid -- Get POSIX clockid_t for a pthread_t. Linux version
Copyright (C) 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
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; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */

#include <errno.h>
#include <pthreadP.h>
#include <sys/time.h>
#include <tls.h>
#include "kernel-features.h"
#include "kernel-posix-cpu-timers.h"


#if !(__ASSUME_POSIX_CPU_TIMERS > 0)
int __libc_missing_posix_cpu_timers attribute_hidden;
#endif
#if !(__ASSUME_POSIX_TIMERS > 0)
int __libc_missing_posix_timers attribute_hidden;
#endif

int
pthread_getcpuclockid (threadid, clockid)
pthread_t threadid;
clockid_t *clockid;
{
struct pthread *pd = (struct pthread *) threadid;

/* Make sure the descriptor is valid. */
if (INVALID_TD_P (pd))
/* Not a valid thread handle. */
return ESRCH;

#ifdef __NR_clock_getres
/* The clockid_t value is a simple computation from the TID.
But we do a clock_getres call to validate it if we aren't
yet sure we have the kernel support. */

const clockid_t tidclock = MAKE_THREAD_CPUCLOCK (pd->tid, CPUCLOCK_SCHED);

# if !(__ASSUME_POSIX_CPU_TIMERS > 0)
# if !(__ASSUME_POSIX_TIMERS > 0)
if (__libc_missing_posix_timers && !__libc_missing_posix_cpu_timers)
__libc_missing_posix_cpu_timers = 1;
# endif
if (!__libc_missing_posix_cpu_timers)
{
INTERNAL_SYSCALL_DECL (err);
int r = INTERNAL_SYSCALL (clock_getres, err, 2, tidclock, NULL);
if (!INTERNAL_SYSCALL_ERROR_P (r, err))
# endif
{
*clockid = tidclock;
return 0;
}

# if !(__ASSUME_POSIX_CPU_TIMERS > 0)
# if !(__ASSUME_POSIX_TIMERS > 0)
if (INTERNAL_SYSCALL_ERRNO (r, err) == ENOSYS)
{
/* The kernel doesn't support these calls at all. */
__libc_missing_posix_timers = 1;
__libc_missing_posix_cpu_timers = 1;
}
else
# endif
if (INTERNAL_SYSCALL_ERRNO (r, err) == EINVAL)
{
/* The kernel doesn't support these clocks at all. */
__libc_missing_posix_cpu_timers = 1;
}
else
return INTERNAL_SYSCALL_ERRNO (r, err);
}
# endif
#endif

#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);

return 0;
#else
/* We don't have a timer for that. */
return ENOENT;
#endif
}
13 changes: 10 additions & 3 deletions nptl/sysdeps/unix/sysv/linux/timer_create.c
Expand Up @@ -28,6 +28,7 @@
#include <internaltypes.h>
#include <nptl/pthreadP.h>
#include "kernel-posix-timers.h"
#include "kernel-posix-cpu-timers.h"


#ifdef __NR_timer_create
Expand Down Expand Up @@ -58,6 +59,12 @@ timer_create (clock_id, evp, timerid)
if (__no_posix_timers >= 0)
# endif
{
clockid_t syscall_clockid = (clock_id == CLOCK_PROCESS_CPUTIME_ID
? MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED)
: clock_id == CLOCK_THREAD_CPUTIME_ID
? MAKE_THREAD_CPUCLOCK (0, CPUCLOCK_SCHED)
: clock_id);

/* If the user wants notification via a thread we need to handle
this special. */
if (evp == NULL
Expand Down Expand Up @@ -88,7 +95,7 @@ timer_create (clock_id, evp, timerid)
}

kernel_timer_t ktimerid;
int retval = INLINE_SYSCALL (timer_create, 3, clock_id, evp,
int retval = INLINE_SYSCALL (timer_create, 3, syscall_clockid, evp,
&ktimerid);

# ifndef __ASSUME_POSIX_TIMERS
Expand Down Expand Up @@ -196,8 +203,8 @@ timer_create (clock_id, evp, timerid)
/* Create the timer. */
INTERNAL_SYSCALL_DECL (err);
int res;
res = INTERNAL_SYSCALL (timer_create, err, 3, clock_id, &sev,
&newp->ktimerid);
res = INTERNAL_SYSCALL (timer_create, err, 3,
syscall_clockid, &sev, &newp->ktimerid);
if (! INTERNAL_SYSCALL_ERROR_P (res, err))
{
*timerid = (timer_t) newp;
Expand Down
4 changes: 3 additions & 1 deletion rt/Makefile
Expand Up @@ -45,7 +45,9 @@ tests := tst-shm tst-clock tst-clock_nanosleep tst-timer tst-timer2 \
tst-aio tst-aio64 tst-aio2 tst-aio3 tst-aio4 tst-aio5 tst-aio6 \
tst-aio7 tst-mqueue1 tst-mqueue2 tst-mqueue3 tst-mqueue4 \
tst-mqueue5 tst-mqueue6 tst-mqueue7 tst-mqueue8 tst-mqueue9 \
tst-timer3 tst-timer4 tst-timer5
tst-timer3 tst-timer4 tst-timer5 \
tst-cpuclock1 tst-cpuclock2 \
tst-cputimer1 tst-cputimer2 tst-cputimer3

extra-libs := librt
extra-libs-others := $(extra-libs)
Expand Down

0 comments on commit 84060ba

Please sign in to comment.