* sysdeps/unix/i386/i586/clock_getres.c: Removed.
	* sysdeps/unix/i386/i586/clock_gettime.c: Removed.
	* sysdeps/unix/i386/i586/clock_nanosleep.c: Removed.
	* sysdeps/unix/i386/i586/clock_settime.c: Removed.
	* sysdeps/unix/i386/i586/cpuclock-init.h: Removed.
	* sysdeps/generic/cpuclock-init.h: Removed.
	* sysdeps/unix/i386/i686/Implies: Removed.
	* sysdeps/unix/i386/i686/tempname.c: Removed.
	* sysdeps/i386/i686/Versions: New file.
	* sysdeps/unix/i386/i586/Versions: Removed.

	* sysdeps/posix/clock_getres.c: If HP_TIMING_AVAIL is nonzero handle
	CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID.
	* sysdeps/unix/clock_gettime.c: Likewise.
	* sysdeps/unix/clock_nanosleep.c: Likewise.
	* sysdeps/unix/clock_settime.c: Likewise.
	* sysdeps/posix/tempname.c: Is HP_TIMING_AVAIL is nonzero define
	RANDOM_BITS use CPU clock.

	* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/bits/time.h: New file.
	* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9b/bits/time.h: New file.
	* sysdeps/unix/sysv/linux/sparc/sparc64/bits/time.h: New file.
	* sysdeps/sparc/Versions: New file.

	* elf/dl-support.c: Don't use cpuclock-init.h definitions, use
	hp-timing.h definitions.
	* sysdeps/generic/dl-sysdep.c: Likewise.

	* include/libc-internal.h: Include hp-timing.h.  Use hp_timing_t in
	__get_clockfreq prototype.

	* sysdeps/unix/sysv/linux/i386/get_clockfreq.c (__get_clockfreq):
	Use hp_timing_t type.

	* sysdeps/unix/sysv/linux/ia64/get_clockfreq.c: New file.
This commit is contained in:
Ulrich Drepper 2001-04-23 19:01:10 +00:00
parent bc183edc4e
commit 3b5c1b57d3
32 changed files with 578 additions and 398 deletions

View File

@ -1,5 +1,41 @@
2001-04-23 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/i386/i586/clock_getres.c: Removed.
* sysdeps/unix/i386/i586/clock_gettime.c: Removed.
* sysdeps/unix/i386/i586/clock_nanosleep.c: Removed.
* sysdeps/unix/i386/i586/clock_settime.c: Removed.
* sysdeps/unix/i386/i586/cpuclock-init.h: Removed.
* sysdeps/generic/cpuclock-init.h: Removed.
* sysdeps/unix/i386/i686/Implies: Removed.
* sysdeps/unix/i386/i686/tempname.c: Removed.
* sysdeps/i386/i686/Versions: New file.
* sysdeps/unix/i386/i586/Versions: Removed.
* sysdeps/posix/clock_getres.c: If HP_TIMING_AVAIL is nonzero handle
CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID.
* sysdeps/unix/clock_gettime.c: Likewise.
* sysdeps/unix/clock_nanosleep.c: Likewise.
* sysdeps/unix/clock_settime.c: Likewise.
* sysdeps/posix/tempname.c: Is HP_TIMING_AVAIL is nonzero define
RANDOM_BITS use CPU clock.
* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/bits/time.h: New file.
* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9b/bits/time.h: New file.
* sysdeps/unix/sysv/linux/sparc/sparc64/bits/time.h: New file.
* sysdeps/sparc/Versions: New file.
* elf/dl-support.c: Don't use cpuclock-init.h definitions, use
hp-timing.h definitions.
* sysdeps/generic/dl-sysdep.c: Likewise.
* include/libc-internal.h: Include hp-timing.h. Use hp_timing_t in
__get_clockfreq prototype.
* sysdeps/unix/sysv/linux/i386/get_clockfreq.c (__get_clockfreq):
Use hp_timing_t type.
* sysdeps/unix/sysv/linux/ia64/get_clockfreq.c: New file.
* sysdeps/posix/pathconf.c (__pathconf): For _PC_ASYNC_IO test
whether named file is a regular file or a block device.
* sysdeps/posix/fpathconf.c (__fpathconf): Likewise.

View File

@ -29,7 +29,7 @@
#include <bits/libc-lock.h>
#include <dl-librecon.h>
#include <unsecvars.h>
#include <cpuclock-init.h>
#include <hp-timing.h>
extern char *__progname;
char **_dl_argv = &__progname; /* This is checked for some error messages. */
@ -94,8 +94,8 @@ struct r_scope_elem *_dl_main_searchlist = &_dl_initial_searchlist;
int _dl_starting_up = 1;
/* Initial value of the CPU clock. */
#ifdef CPUCLOCK_VARDEF
CPUCLOCK_VARDEF (_dl_cpuclock_offset);
#if HP_TIMING_AVAIL
hp_timing_t _dl_cpuclock_offset;
#endif
/* During the program run we must not modify the global data of
@ -133,8 +133,8 @@ static void non_dynamic_init (void) __attribute__ ((unused));
static void
non_dynamic_init (void)
{
#ifdef CPUCLOCK_INIT
CPUCLOCK_INIT (_dl_cpuclock_offset);
#if HP_TIMING_AVAIL
HP_TIMING_NOW (_dl_cpuclock_offset);
#endif
if (!_dl_pagesize)

View File

@ -4,6 +4,8 @@
#ifndef _LIBC_INTERNAL
# define _LIBC_INTERNAL 1
#include <hp-timing.h>
/* Initialize the `__libc_enable_secure' flag. */
extern void __libc_init_secure (void);
@ -19,7 +21,7 @@ extern void __cyg_profile_func_enter (void *this_fn, void *call_site);
extern void __cyg_profile_func_exit (void *this_fn, void *call_site);
/* Get frequency of the system processor. */
extern unsigned long long int __get_clockfreq (void);
extern hp_timing_t __get_clockfreq (void);
/* Free all allocated resources. */
extern void __libc_freeres (void);

View File

@ -1,3 +1,18 @@
2001-04-23 Ulrich Drepper <drepper@redhat.com>
* Makefile (libpthread-routines): Add ptclock_gettime and
ptclock_settime.
* internals.h: Don't use cpuclock-init.h definitions, use
hp-timing.h definitions.
* pthread.c: Likewise.
* manager.c: Likewise.
* ptclock_gettime.c: New file.
* ptclock_settime.c: New file.
* sysdeps/i386/i586/ptclock_gettime.c: Removed.
* sysdeps/i386/i586/ptclock_settime.c: Removed.
* sysdeps/i386/i586/Makefile: Removed.
2001-04-22 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/bits/posix_opt.h: Define _POSIX_ASYNCH_IO.

View File

@ -35,7 +35,8 @@ extra-libs-others := $(extra-libs)
libpthread-routines := attr cancel condvar join manager mutex ptfork \
ptlongjmp pthread signals specific errno lockfile \
semaphore spinlock wrapsyscall rwlock pt-machine \
oldsemaphore events getcpuclockid pspinlock barrier
oldsemaphore events getcpuclockid pspinlock barrier \
ptclock_gettime ptclock_settime
nodelete-yes = -Wl,--enable-new-dtags,-z,nodelete
initfirst-yes = -Wl,--enable-new-dtags,-z,initfirst

View File

@ -33,7 +33,7 @@ extern int __compare_and_swap (long int *p, long int oldval, long int newval);
#include "pt-machine.h"
#include "semaphore.h"
#include "../linuxthreads_db/thread_dbP.h"
#include <cpuclock-init.h>
#include <hp-timing.h>
#ifndef THREAD_GETMEM
# define THREAD_GETMEM(descr, member) descr->member
@ -180,8 +180,8 @@ struct _pthread_descr_struct {
struct __res_state *p_resp; /* Pointer to resolver state */
struct __res_state p_res; /* per-thread resolver state */
int p_inheritsched; /* copied from the thread attribute */
#ifdef CPUCLOCK_VARDEF
CPUCLOCK_VARDEF (p_cpuclock_offset); /* Initial CPU clock for thread. */
#if HP_TIMING_AVAIL
hp_timing_t p_cpuclock_offset; /* Initial CPU clock for thread. */
#endif
/* New elements must be added at the end. */
} __attribute__ ((aligned(32))); /* We need to align the structure so that

View File

@ -230,15 +230,15 @@ pthread_start_thread(void *arg)
pthread_descr self = (pthread_descr) arg;
struct pthread_request request;
void * outcome;
#ifdef CPUCLOCK_VARDEF
CPUCLOCK_VARDEF (tmpclock);
#if HP_TIMING_AVAIL
hp_timing_t tmpclock;
#endif
/* Initialize special thread_self processing, if any. */
#ifdef INIT_THREAD_SELF
INIT_THREAD_SELF(self, self->p_nr);
#endif
#ifdef CPUCLOCK_INIT
CPUCLOCK_INIT (tmpclock);
#if HP_TIMING_AVAIL
HP_TIMING_NOW (tmpclock);
THREAD_SETMEM (self, p_cpuclock_offset, tmpclock);
#endif
/* Make sure our pid field is initialized, just in case we get there

View File

@ -18,18 +18,18 @@
#include <time.h>
#include <libc-internal.h>
#include "../../../internals.h"
#include "internals.h"
#if HP_TIMING_AVAIL
int
__pthread_clock_gettime (unsigned long long int freq, struct timespec *tp)
__pthread_clock_gettime (hp_timing_t freq, struct timespec *tp)
{
unsigned long long int tsc;
hp_timing_t tsc;
pthread_descr self = thread_self ();
/* Get the current counter. */
asm volatile ("rdtsc" : "=A" (tsc));
HP_TIMING_NOW (tsc);
/* Compute the offset since the start time of the process. */
tsc -= THREAD_GETMEM (self, p_cpuclock_offset);
@ -43,3 +43,4 @@ __pthread_clock_gettime (unsigned long long int freq, struct timespec *tp)
return 0;
}
#endif

View File

@ -18,15 +18,16 @@
#include <time.h>
#include <libc-internal.h>
#include "../../../internals.h"
#include "internals.h"
#if HP_TIMING_AVAIL
void
__pthread_clock_settime (unsigned long long int offset)
__pthread_clock_settime (hp_timing_t offset)
{
pthread_descr self = thread_self ();
/* Compute the offset since the start time of the process. */
THREAD_SETMEM (self, p_cpuclock_offset, offset);
}
#endif

View File

@ -226,8 +226,8 @@ static void pthread_handle_sigrestart(int sig);
static void pthread_handle_sigdebug(int sig);
/* CPU clock handling. */
#ifdef CPUCLOCK_VARDECL
CPUCLOCK_VARDECL (_dl_cpuclock_offset);
#if HP_TIMING_AVAIL
extern hp_timing_t _dl_cpuclock_offset;
#endif
/* Signal numbers used for the communication.
@ -395,7 +395,7 @@ __pthread_initialize_minimal(void)
#ifdef INIT_THREAD_SELF
INIT_THREAD_SELF(&__pthread_initial_thread, 0);
#endif
#ifdef CPUCLOCK_INIT
#if HP_TIMING_AVAIL
__pthread_initial_thread.p_cpuclock_offset = _dl_cpuclock_offset;
#endif
}

View File

@ -1,3 +0,0 @@
ifeq ($(subdir),linuxthreads)
libpthread-sysdep_routines += ptclock_gettime ptclock_settime
endif

View File

@ -1 +0,0 @@
/* In general there is no CPU clock. */

View File

@ -35,7 +35,7 @@
#include <dl-machine.h>
#include <dl-procinfo.h>
#include <dl-osinfo.h>
#include <cpuclock-init.h>
#include <hp-timing.h>
extern int _dl_argc;
extern char **_dl_argv;
@ -61,8 +61,8 @@ int __libc_multiple_libcs = 0; /* Defining this here avoids the inclusion
void *__libc_stack_end;
static ElfW(auxv_t) *_dl_auxv;
unsigned long int _dl_hwcap_mask = HWCAP_IMPORTANT;
#ifdef CPUCLOCK_VARDEF
CPUCLOCK_VARDEF (_dl_cpuclock_offset);
#if HP_TIMING_AVAIL
hp_timing_t _dl_cpuclock_offset;
#endif
#ifndef DL_FIND_ARG_COMPONENTS
@ -100,8 +100,8 @@ _dl_sysdep_start (void **start_argptr,
# define set_seen(tag) seen |= M ((tag)->a_type)
#endif
#ifdef CPUCLOCK_INIT
CPUCLOCK_INIT (_dl_cpuclock_offset);
#if HP_TIMING_AVAIL
HP_TIMING_NOW (_dl_cpuclock_offset);
#endif
DL_FIND_ARG_COMPONENTS (start_argptr, _dl_argc, _dl_argv, _environ,

View File

@ -17,14 +17,19 @@
Boston, MA 02111-1307, USA. */
#include <errno.h>
#include <stdint.h>
#include <time.h>
#include <unistd.h>
#include <sys/param.h>
#include <libc-internal.h>
#ifndef EXTRA_CLOCK_CASES
# define EXTRA_CLOCK_CASES
#if HP_TIMING_AVAIL
/* Clock frequency of the processor. */
static long int nsec;
#endif
/* Get resolution of clock. */
int
clock_getres (clockid_t clock_id, struct timespec *res)
@ -50,7 +55,35 @@ clock_getres (clockid_t clock_id, struct timespec *res)
}
break;
EXTRA_CLOCK_CASES
#if HP_TIMING_AVAIL
case CLOCK_PROCESS_CPUTIME_ID:
case CLOCK_THREAD_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
default:
__set_errno (EINVAL);

View File

@ -107,6 +107,25 @@
# define __secure_getenv getenv
#endif
#ifdef _LIBC
# include <hp-timing.h>
# if HP_TIMING_AVAIL
# define RANDOM_BITS(Var) \
if (__builtin_expect (value == UINT64_C (0), 0)) \
{ \
/* If this is the first time this function is used initialize \
the variable we accumulate the value in to some somewhat \
random value. If we'd not do this programs at startup time \
might have a reduced set of possible names, at least on slow \
machines. */ \
struct timeval tv; \
__gettimeofday (&tv, NULL); \
value = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; \
} \
HP_TIMING_NOW (Var)
# endif
#endif
/* Use the widest available unsigned type if uint64_t is not
available. The algorithm below extracts a number less than 62**6
(approximately 2**35.725) from uint64_t, so ancient hosts where

6
sysdeps/sparc/Versions Normal file
View File

@ -0,0 +1,6 @@
ld {
GLIBC_2.2.3 {
# If this symbol is ever available on SPARC it was introduced in 2.2.3.
_dl_cpuclock_offset;
}
}

View File

@ -17,14 +17,30 @@
Boston, MA 02111-1307, USA. */
#include <errno.h>
#include <stdint.h>
#include <time.h>
#include <sys/time.h>
#include <libc-internal.h>
#include <hp-timing.h>
#ifndef EXTRA_CLOCK_CASES
# define EXTRA_CLOCK_CASES
#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;
/* We need the starting time for the process. */
extern hp_timing_t _dl_cpuclock_offset;
/* This function is defined in the thread library. */
extern int __pthread_clock_gettime (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)
@ -41,7 +57,48 @@ clock_gettime (clockid_t clock_id, struct timespec *tp)
TIMEVAL_TO_TIMESPEC (&tv, tp);
break;
EXTRA_CLOCK_CASES
#if HP_TIMING_AVAIL
case CLOCK_PROCESS_CPUTIME_ID:
case CLOCK_THREAD_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_THREAD_CPUTIME_ID
&& __pthread_clock_gettime != NULL)
{
retval = __pthread_clock_gettime (freq, tp);
break;
}
/* Get the current counter. */
HP_TIMING_NOW (tsc);
/* Compute the offset since the start time of the process. */
tsc -= _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
default:
__set_errno (EINVAL);

View File

@ -20,9 +20,14 @@
#include <assert.h>
#include <errno.h>
#include <time.h>
#include <hp-timing.h>
#ifndef CLOCK_P
#if HP_TIMING_AVAIL
# define CLOCK_P(clock) \
(clock) != CLOCK_PROCESS_CPUTIME_ID \
&& (clock) != CLOCK_THREAD_CPUTIME_ID
#else
# define CLOCK_P(clock) 0
#endif

View File

@ -19,12 +19,26 @@
#include <errno.h>
#include <time.h>
#include <sys/time.h>
#include <libc-internal.h>
#ifndef EXTRA_CLOCK_CASES
# define EXTRA_CLOCK_CASES
#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;
/* We need the starting time for the process. */
extern hp_timing_t _dl_cpuclock_offset;
/* This function is defined in the thread library. */
extern void __pthread_clock_settime (hp_timing_t offset)
__attribute__ ((__weak__));
#endif
/* Set CLOCK to value TP. */
int
clock_settime (clockid_t clock_id, const struct timespec *tp)
@ -47,7 +61,45 @@ clock_settime (clockid_t clock_id, const struct timespec *tp)
retval = settimeofday (&tv, NULL);
break;
EXTRA_CLOCK_CASES
#if HP_TIMING_AVAIL
case CLOCK_PROCESS_CPUTIME_ID:
case CLOCK_THREAD_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_THREAD_CPUTIME_ID
|| __pthread_clock_settime == NULL)
_dl_cpuclock_offset = tsc - usertime;
else
__pthread_clock_settime (tsc - usertime);
retval = 0;
}
break;
#endif
default:
__set_errno (EINVAL);

View File

@ -1,72 +0,0 @@
/* Copyright (C) 1999, 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 Library General Public License as
published by the Free Software Foundation; either version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library 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 <time.h>
#include <sys/param.h>
#include <libc-internal.h>
/* This implementation uses the TSC register in modern (i586 and up) IA-32
processors (most modern clones also provide it). Since we need the
resolution of the clock and since determining this is not cheap, we
cache the value. But this means that systems with processors running
at different speeds or process migration to machines with slower or
faster processors will not work without changes. */
/* Clock frequency of the processor. */
static long int nsec;
/* We add an limitation here: we assume that the machine is not up as
long as it takes to wrap-around the 64-bit timestamp counter. On a
4GHz machine it would take 136 years of uptime to wrap around so
this "limitation" is not severe.
We use this clock also as the monotonic clock since we don't allow
setting the CPU-time clock. If this should ever change we will have
to separate the two. */
#define EXTRA_CLOCK_CASES \
case CLOCK_PROCESS_CPUTIME_ID: \
case CLOCK_THREAD_CPUTIME_ID: \
{ \
if (__builtin_expect (nsec == 0, 0)) \
{ \
unsigned long long int 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 (1000000000ULL / 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;
#include <sysdeps/posix/clock_getres.c>

View File

@ -1,107 +0,0 @@
/* Copyright (C) 1999, 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 Library General Public License as
published by the Free Software Foundation; either version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library 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 <time.h>
#include <libc-internal.h>
#include "cpuclock-init.h"
/* This implementation uses the TSC register in modern (i586 and up) IA-32
processors (most modern clones also provide it). Since we need the
resolution of the clock and since determining this is not cheap, we
cache the value. But this means that systems with processors running
at different speeds or process migration to machines with slower or
faster processors will not work without changes. */
/* 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 unsigned long long int freq;
/* We need the starting time for the process. */
CPUCLOCK_VARDECL (_dl_cpuclock_offset);
/* This function is defined in the thread library. */
extern int __pthread_clock_gettime (unsigned long long int freq,
struct timespec *tp)
__attribute__ ((__weak__));
/* We add an limitation here: we assume that the process is not
running as long as it takes to wrap-around the 64-bit timestamp
counter. On a 4GHz machine it would take 136 years of uptime to
wrap around so this "limitation" is not severe. */
#define EXTRA_CLOCK_CASES \
case CLOCK_THREAD_CPUTIME_ID: \
if (__pthread_clock_gettime != NULL) \
{ \
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; \
} \
\
retval = __pthread_clock_gettime (freq, tp); \
break; \
} \
/* FALLTHROUGH */ \
\
case CLOCK_PROCESS_CPUTIME_ID: \
{ \
unsigned long long int 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; \
} \
\
/* Get the current counter. */ \
asm volatile ("rdtsc" : "=A" (tsc)); \
\
/* Compute the offset since the start time of the process. */ \
tsc -= _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) * 1000000000ull) / freq; \
\
retval = 0; \
} \
break;
#include <sysdeps/unix/clock_gettime.c>

View File

@ -1,25 +0,0 @@
/* High-resolution sleep with the specified clock.
Copyright (C) 2000 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 Library General Public License as
published by the Free Software Foundation; either version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library 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. */
/* Additional definitions for the x86 version. */
#define CLOCK_P(clock) \
(clock) != CLOCK_PROCESS_CPUTIME_ID \
&& (clock) != CLOCK_THREAD_CPUTIME_ID
#include <sysdeps/unix/clock_nanosleep.c>

View File

@ -1,85 +0,0 @@
/* Copyright (C) 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 Library General Public License as
published by the Free Software Foundation; either version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library 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 <time.h>
#include "cpuclock-init.h"
#include "libc-internal.h"
/* This implementation uses the TSC register in modern (i586 and up) IA-32
processors (most modern clones also provide it). Since we need the
resolution of the clock and since determining this is not cheap, we
cache the value. But this means that systems with processors running
at different speeds or process migration to machines with slower or
faster processors will not work without changes. */
/* 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 unsigned long long int freq;
/* We need the starting time for the process. */
CPUCLOCK_VARDECL (_dl_cpuclock_offset);
/* This function is defined in the thread library. */
extern void __pthread_clock_settime (unsigned long long int offset)
__attribute__ ((__weak__));
/* We add an limitation here: we assume that the process is not
running as long as it takes to wrap-around the 64-bit timestamp
counter. On a 4GHz machine it would take 136 years of uptime to
wrap around so this "limitation" is not severe. */
#define EXTRA_CLOCK_CASES \
case CLOCK_PROCESS_CPUTIME_ID: \
case CLOCK_THREAD_CPUTIME_ID: \
{ \
unsigned long long int tsc; \
unsigned long long int usertime; \
\
/* First thing is to get the current time. */ \
asm volatile ("rdtsc" : "=A" (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; \
} \
\
/* 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_THREAD_CPUTIME_ID \
|| __pthread_clock_settime == NULL) \
_dl_cpuclock_offset = tsc - usertime; \
else \
__pthread_clock_settime (tsc - usertime); \
} \
break;
#include <sysdeps/unix/clock_settime.c>

View File

@ -1,27 +0,0 @@
/* x86 TSC based CPU clock initialization code.
Copyright (C) 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 Library General Public License as
published by the Free Software Foundation; either version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library 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. */
/* The TSC value has 64 bits. */
#define CPUCLOCK_VARDEF(name) unsigned long long int name
/* A declaration. */
#define CPUCLOCK_VARDECL(name) extern unsigned long long int name
/* Reading the TSC value is a simple instruction. */
#define CPUCLOCK_INIT(name) asm volatile ("rdtsc" : "=A" (name))

View File

@ -1 +0,0 @@
unix/i386/i586

View File

@ -1,35 +0,0 @@
/* Copyright (C) 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 Library General Public License as
published by the Free Software Foundation; either version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library 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. */
/* For i686 and up we have a better and faster source of random bits in the
form of the time stamp counter. */
#define RANDOM_BITS(Var) \
if (__builtin_expect (value == UINT64_C (0), 0)) \
{ \
/* If this is the first time this function is used initialize \
the variable we accumulate the value in to some somewhat \
random value. If we'd not do this programs at startup time \
might have a reduced set of possible names, at least on slow \
machines. */ \
struct timeval tv; \
__gettimeofday (&tv, NULL); \
value = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; \
} \
__asm__ __volatile__ ("rdtsc" : "=A" (Var))
#include_next <tempname.c>

View File

@ -24,7 +24,7 @@
#include <libc-internal.h>
unsigned long long int
hp_timing_t
__get_clockfreq (void)
{
/* We read the information from the /proc filesystem. It contains at
@ -33,7 +33,7 @@ __get_clockfreq (void)
or also
cpu MHz : 497.841
We search for this line and convert the number in an integer. */
static unsigned long long int result;
static hp_timing_t result;
int fd;
/* If this function was called before, we know the result. */

View File

@ -0,0 +1,89 @@
/* Get frequency of the system processor. IA-64/Linux version.
Copyright (C) 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 Library General Public License as
published by the Free Software Foundation; either version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library 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 <ctype.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <libc-internal.h>
hp_timing_t
__get_clockfreq (void)
{
/* We read the information from the /proc filesystem. It contains at
least one line like
itc MHz : 733.390988
We search for this line and convert the number in an integer. */
static hp_timing_t result;
int fd;
/* If this function was called before, we know the result. */
if (result != 0)
return result;
fd = open ("/proc/cpuinfo", O_RDONLY);
if (__builtin_expect (fd != -1, 1))
{
/* XXX AFAIK the /proc filesystem can generate "files" only up
to a size of 4096 bytes. */
char buf[4096];
ssize_t n;
n = read (fd, buf, sizeof buf);
if (__builtin_expect (n, 1) > 0)
{
char *mhz = memmem (buf, n, "itc MHz", 7);
if (__builtin_expect (mhz != NULL, 1))
{
char *endp = buf + n;
int seen_decpoint = 0;
int ndigits = 0;
/* Search for the beginning of the string. */
while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n')
++mhz;
while (mhz < endp && *mhz != '\n')
{
if (*mhz >= '0' && *mhz <= '9')
{
result *= 10;
result += *mhz - '0';
if (seen_decpoint)
++ndigits;
}
else if (*mhz == '.')
seen_decpoint = 1;
++mhz;
}
/* Compensate for missing digits at the end. */
while (ndigits++ < 6)
result *= 10;
}
}
close (fd);
}
return result;
}

View File

@ -0,0 +1,73 @@
/* System-dependent timing definitions. Linux/SPARCv9 version.
Copyright (C) 1996, 1997, 1999, 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 Library General Public License as
published by the Free Software Foundation; either version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library 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. */
/*
* Never include this file directly; use <time.h> instead.
*/
#ifndef __need_timeval
# ifndef _BITS_TIME_H
# define _BITS_TIME_H 1
/* ISO/IEC 9899:1990 7.12.1: <time.h>
The macro `CLOCKS_PER_SEC' is the number per second of the value
returned by the `clock' function. */
/* CAE XSH, Issue 4, Version 2: <time.h>
The value of CLOCKS_PER_SEC is required to be 1 million on all
XSI-conformant systems. */
# define CLOCKS_PER_SEC 1000000l
# if !defined __STRICT_ANSI__ && !defined __USE_XOPEN2K
/* Even though CLOCKS_PER_SEC has such a strange value CLK_TCK
presents the real value for clock ticks per second for the system. */
# include <bits/types.h>
extern long int __sysconf (int);
# define CLK_TCK ((__clock_t) __sysconf (2)) /* 2 is _SC_CLK_TCK */
# endif
# ifdef __USE_POSIX199309
/* Identifier for system-wide realtime clock. */
# define CLOCK_REALTIME 0
/* High-resolution timer from the CPU. */
# define CLOCK_PROCESS_CPUTIME_ID 2
/* Thread-specific CPU-time clock. */
# define CLOCK_THREAD_CPUTIME_ID 3
/* Flag to indicate time is absolute. */
# define TIMER_ABSTIME 1
# endif
# endif /* bits/time.h */
#endif
#ifdef __need_timeval
# undef __need_timeval
# ifndef _STRUCT_TIMEVAL
# define _STRUCT_TIMEVAL 1
# include <bits/types.h>
/* A time value that is accurate to the nearest
microsecond but also has a range of years. */
struct timeval
{
__time_t tv_sec; /* Seconds. */
__suseconds_t tv_usec; /* Microseconds. */
};
# endif /* struct timeval */
#endif /* need timeval */

View File

@ -0,0 +1,73 @@
/* System-dependent timing definitions. Linux/SPARCv9b version.
Copyright (C) 1996, 1997, 1999, 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 Library General Public License as
published by the Free Software Foundation; either version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library 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. */
/*
* Never include this file directly; use <time.h> instead.
*/
#ifndef __need_timeval
# ifndef _BITS_TIME_H
# define _BITS_TIME_H 1
/* ISO/IEC 9899:1990 7.12.1: <time.h>
The macro `CLOCKS_PER_SEC' is the number per second of the value
returned by the `clock' function. */
/* CAE XSH, Issue 4, Version 2: <time.h>
The value of CLOCKS_PER_SEC is required to be 1 million on all
XSI-conformant systems. */
# define CLOCKS_PER_SEC 1000000l
# if !defined __STRICT_ANSI__ && !defined __USE_XOPEN2K
/* Even though CLOCKS_PER_SEC has such a strange value CLK_TCK
presents the real value for clock ticks per second for the system. */
# include <bits/types.h>
extern long int __sysconf (int);
# define CLK_TCK ((__clock_t) __sysconf (2)) /* 2 is _SC_CLK_TCK */
# endif
# ifdef __USE_POSIX199309
/* Identifier for system-wide realtime clock. */
# define CLOCK_REALTIME 0
/* High-resolution timer from the CPU. */
# define CLOCK_PROCESS_CPUTIME_ID 2
/* Thread-specific CPU-time clock. */
# define CLOCK_THREAD_CPUTIME_ID 3
/* Flag to indicate time is absolute. */
# define TIMER_ABSTIME 1
# endif
# endif /* bits/time.h */
#endif
#ifdef __need_timeval
# undef __need_timeval
# ifndef _STRUCT_TIMEVAL
# define _STRUCT_TIMEVAL 1
# include <bits/types.h>
/* A time value that is accurate to the nearest
microsecond but also has a range of years. */
struct timeval
{
__time_t tv_sec; /* Seconds. */
__suseconds_t tv_usec; /* Microseconds. */
};
# endif /* struct timeval */
#endif /* need timeval */

View File

@ -0,0 +1,73 @@
/* System-dependent timing definitions. Linux/SPARC64 version.
Copyright (C) 1996, 1997, 1999, 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 Library General Public License as
published by the Free Software Foundation; either version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library 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. */
/*
* Never include this file directly; use <time.h> instead.
*/
#ifndef __need_timeval
# ifndef _BITS_TIME_H
# define _BITS_TIME_H 1
/* ISO/IEC 9899:1990 7.12.1: <time.h>
The macro `CLOCKS_PER_SEC' is the number per second of the value
returned by the `clock' function. */
/* CAE XSH, Issue 4, Version 2: <time.h>
The value of CLOCKS_PER_SEC is required to be 1 million on all
XSI-conformant systems. */
# define CLOCKS_PER_SEC 1000000l
# if !defined __STRICT_ANSI__ && !defined __USE_XOPEN2K
/* Even though CLOCKS_PER_SEC has such a strange value CLK_TCK
presents the real value for clock ticks per second for the system. */
# include <bits/types.h>
extern long int __sysconf (int);
# define CLK_TCK ((__clock_t) __sysconf (2)) /* 2 is _SC_CLK_TCK */
# endif
# ifdef __USE_POSIX199309
/* Identifier for system-wide realtime clock. */
# define CLOCK_REALTIME 0
/* High-resolution timer from the CPU. */
# define CLOCK_PROCESS_CPUTIME_ID 2
/* Thread-specific CPU-time clock. */
# define CLOCK_THREAD_CPUTIME_ID 3
/* Flag to indicate time is absolute. */
# define TIMER_ABSTIME 1
# endif
# endif /* bits/time.h */
#endif
#ifdef __need_timeval
# undef __need_timeval
# ifndef _STRUCT_TIMEVAL
# define _STRUCT_TIMEVAL 1
# include <bits/types.h>
/* A time value that is accurate to the nearest
microsecond but also has a range of years. */
struct timeval
{
__time_t tv_sec; /* Seconds. */
__suseconds_t tv_usec; /* Microseconds. */
};
# endif /* struct timeval */
#endif /* need timeval */