2002-06-27 Jeff Johnston <jjohnstn@redhat.com>

* libc/sys/linux/Makefile.am: Add new clock routines.
        * libc/sys/linux/Makefile.in: Regenerated.
        * libc/sys/linux/clock_getres.c: New file.
        * libc/sys/linux/clock_gettime.c: Ditto.
        * libc/sys/linux/clock_settime.c: Ditto.
        * libc/sys/linux/hp-timing.h: Ditto.
        * libc/sys/linux/libc-internal.h: Ditto.
        * libc/sys/linux/sysconf.c: Fix typo.
        * libc/sys/linux/include/time.h: New file.
        * libc/sys/linux/machine/hp-timing.h: New file.
        * libc/sys/linux/machine/i386/Makefile.am: Add new files.
        * libc/sys/linux/machine/i386/Makefile.in: Regenerated.
        * libc/sys/linux/machine/i386/get_clockfreq.c: New file.
        * libc/sys/linux/machine/i386/hp-timing.c: Ditto.
        * libc/sys/linux/machine/i386/hp-timing.h: Ditto.
        * libc/sys/linux/sys/linux_time.h: Ditto.
        * libc/sys/linux/sys/time.h: Remove include of <linux/time.h> and
        replace with <sys/linux_time.h>.
This commit is contained in:
Jeff Johnston 2002-06-27 20:09:26 +00:00
parent d3c260c334
commit baf051ca35
18 changed files with 1111 additions and 22 deletions

View File

@ -1,3 +1,24 @@
2002-06-27 Jeff Johnston <jjohnstn@redhat.com>
* libc/sys/linux/Makefile.am: Add new clock routines.
* libc/sys/linux/Makefile.in: Regenerated.
* libc/sys/linux/clock_getres.c: New file.
* libc/sys/linux/clock_gettime.c: Ditto.
* libc/sys/linux/clock_settime.c: Ditto.
* libc/sys/linux/hp-timing.h: Ditto.
* libc/sys/linux/libc-internal.h: Ditto.
* libc/sys/linux/sysconf.c: Fix typo.
* libc/sys/linux/include/time.h: Add include of <sys/linux_time.h>.
* libc/sys/linux/machine/hp-timing.h: New file.
* libc/sys/linux/machine/i386/Makefile.am: Add new files.
* libc/sys/linux/machine/i386/Makefile.in: Regenerated.
* libc/sys/linux/machine/i386/get_clockfreq.c: New file.
* libc/sys/linux/machine/i386/hp-timing.c: Ditto.
* libc/sys/linux/machine/i386/hp-timing.h: Ditto.
* libc/sys/linux/sys/linux_time.h: New file.
* libc/sys/linux/sys/time.h: Remove include of <linux/time.h> and
replace with <sys/linux_time.h>.
Wed Jun 26 16:33:25 2002 J"orn Rennecke <joern.rennecke@superh.com>
* libc/sys/sh/crt0.S: Remove vestigial .section directive.

View File

@ -12,6 +12,9 @@ SUBLIBS = \
LIB_SOURCES = \
brk.c \
cfspeed.c \
clock_getres.c \
clock_gettime.c \
clock_settime.c \
flockfile.c \
ftok.c \
funlockfile.c \

View File

@ -109,6 +109,9 @@ SUBLIBS = \
LIB_SOURCES = \
brk.c \
cfspeed.c \
clock_getres.c \
clock_gettime.c \
clock_settime.c \
flockfile.c \
ftok.c \
funlockfile.c \
@ -206,13 +209,14 @@ DEFS = @DEFS@ -I. -I$(srcdir)
CPPFLAGS = @CPPFLAGS@
LIBS = @LIBS@
@USE_LIBTOOL_FALSE@lib_a_OBJECTS = brk.$(OBJEXT) cfspeed.$(OBJEXT) \
@USE_LIBTOOL_FALSE@flockfile.$(OBJEXT) ftok.$(OBJEXT) \
@USE_LIBTOOL_FALSE@funlockfile.$(OBJEXT) getdate.$(OBJEXT) \
@USE_LIBTOOL_FALSE@getdate_err.$(OBJEXT) gethostname.$(OBJEXT) \
@USE_LIBTOOL_FALSE@getoptlong.$(OBJEXT) getreent.$(OBJEXT) \
@USE_LIBTOOL_FALSE@ids.$(OBJEXT) inode.$(OBJEXT) io.$(OBJEXT) \
@USE_LIBTOOL_FALSE@io64.$(OBJEXT) ipc.$(OBJEXT) linux.$(OBJEXT) \
@USE_LIBTOOL_FALSE@mmap.$(OBJEXT) mq_close.$(OBJEXT) \
@USE_LIBTOOL_FALSE@clock_getres.$(OBJEXT) clock_gettime.$(OBJEXT) \
@USE_LIBTOOL_FALSE@clock_settime.$(OBJEXT) flockfile.$(OBJEXT) \
@USE_LIBTOOL_FALSE@ftok.$(OBJEXT) funlockfile.$(OBJEXT) \
@USE_LIBTOOL_FALSE@getdate.$(OBJEXT) getdate_err.$(OBJEXT) \
@USE_LIBTOOL_FALSE@gethostname.$(OBJEXT) getoptlong.$(OBJEXT) \
@USE_LIBTOOL_FALSE@getreent.$(OBJEXT) ids.$(OBJEXT) inode.$(OBJEXT) \
@USE_LIBTOOL_FALSE@io.$(OBJEXT) io64.$(OBJEXT) ipc.$(OBJEXT) \
@USE_LIBTOOL_FALSE@linux.$(OBJEXT) mmap.$(OBJEXT) mq_close.$(OBJEXT) \
@USE_LIBTOOL_FALSE@mq_getattr.$(OBJEXT) mq_notify.$(OBJEXT) \
@USE_LIBTOOL_FALSE@mq_open.$(OBJEXT) mq_receive.$(OBJEXT) \
@USE_LIBTOOL_FALSE@mq_send.$(OBJEXT) mq_setattr.$(OBJEXT) \
@ -234,15 +238,17 @@ LIBS = @LIBS@
@USE_LIBTOOL_FALSE@usleep.$(OBJEXT) wait.$(OBJEXT)
LTLIBRARIES = $(noinst_LTLIBRARIES)
@USE_LIBTOOL_TRUE@liblinux_la_OBJECTS = brk.lo cfspeed.lo flockfile.lo \
@USE_LIBTOOL_TRUE@ftok.lo funlockfile.lo getdate.lo getdate_err.lo \
@USE_LIBTOOL_TRUE@gethostname.lo getoptlong.lo getreent.lo ids.lo \
@USE_LIBTOOL_TRUE@inode.lo io.lo io64.lo ipc.lo linux.lo mmap.lo \
@USE_LIBTOOL_TRUE@mq_close.lo mq_getattr.lo mq_notify.lo mq_open.lo \
@USE_LIBTOOL_TRUE@mq_receive.lo mq_send.lo mq_setattr.lo mq_unlink.lo \
@USE_LIBTOOL_TRUE@ntp_gettime.lo pread.lo pread64.lo process.lo \
@USE_LIBTOOL_TRUE@psignal.lo pwrite.lo pwrite64.lo raise.lo realpath.lo \
@USE_LIBTOOL_TRUE@rename.lo resource.lo sched.lo select.lo seteuid.lo \
@USE_LIBTOOL_TRUE@liblinux_la_OBJECTS = brk.lo cfspeed.lo \
@USE_LIBTOOL_TRUE@clock_getres.lo clock_gettime.lo clock_settime.lo \
@USE_LIBTOOL_TRUE@flockfile.lo ftok.lo funlockfile.lo getdate.lo \
@USE_LIBTOOL_TRUE@getdate_err.lo gethostname.lo getoptlong.lo \
@USE_LIBTOOL_TRUE@getreent.lo ids.lo inode.lo io.lo io64.lo ipc.lo \
@USE_LIBTOOL_TRUE@linux.lo mmap.lo mq_close.lo mq_getattr.lo \
@USE_LIBTOOL_TRUE@mq_notify.lo mq_open.lo mq_receive.lo mq_send.lo \
@USE_LIBTOOL_TRUE@mq_setattr.lo mq_unlink.lo ntp_gettime.lo pread.lo \
@USE_LIBTOOL_TRUE@pread64.lo process.lo psignal.lo pwrite.lo \
@USE_LIBTOOL_TRUE@pwrite64.lo raise.lo realpath.lo rename.lo \
@USE_LIBTOOL_TRUE@resource.lo sched.lo select.lo seteuid.lo \
@USE_LIBTOOL_TRUE@sethostname.lo shm_open.lo shm_unlink.lo sig.lo \
@USE_LIBTOOL_TRUE@sigaction.lo sigqueue.lo signal.lo siglongjmp.lo \
@USE_LIBTOOL_TRUE@sigset.lo sigwait.lo socket.lo sleep.lo stack.lo \

View File

@ -0,0 +1,94 @@
/* 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 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 <stdint.h>
#include <time.h>
#include <unistd.h>
#include <sys/param.h>
#include <libc-internal.h>
#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)
{
int retval = -1;
switch (clock_id)
{
case CLOCK_REALTIME:
{
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;
#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);
break;
}
return retval;
}

View File

@ -0,0 +1,109 @@
/* 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 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 <stdint.h>
#include <time.h>
#include <sys/time.h>
#include <libc-internal.h>
#include <hp-timing.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;
/* 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)
{
struct timeval tv;
int retval = -1;
switch (clock_id)
{
case CLOCK_REALTIME:
retval = gettimeofday (&tv, NULL);
if (retval == 0)
/* Convert into `timespec'. */
TIMEVAL_TO_TIMESPEC (&tv, tp);
break;
#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);
break;
}
return retval;
}

View File

@ -0,0 +1,111 @@
/* 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 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 <sys/time.h>
#include <libc-internal.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;
/* 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)
{
struct timeval tv;
int retval;
/* Make sure the time cvalue is OK. */
if (tp->tv_nsec < 0 || tp->tv_nsec >= 1000000000)
{
__set_errno (EINVAL);
return -1;
}
switch (clock_id)
{
case CLOCK_REALTIME:
TIMESPEC_TO_TIMEVAL (&tv, tp);
retval = settimeofday (&tv, NULL);
break;
#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);
retval = -1;
break;
}
return retval;
}

View File

@ -0,0 +1 @@
#include <machine/hp-timing.h>

View File

@ -0,0 +1,225 @@
/*
* time.h
*
* Struct and function declarations for dealing with time.
*/
#ifndef _TIME_H_
#define _TIME_H_
#include "_ansi.h"
#include <sys/reent.h>
#include <sys/linux_time.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef NULL
#define NULL 0
#endif
/* Get _CLOCKS_PER_SEC_ */
#include <machine/time.h>
#ifndef _CLOCKS_PER_SEC_
#define _CLOCKS_PER_SEC_ 1000
#endif
#define CLOCKS_PER_SEC _CLOCKS_PER_SEC_
#define CLK_TCK CLOCKS_PER_SEC
#define __need_size_t
#include <stddef.h>
#include <sys/types.h>
struct tm
{
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
#ifndef __timer_t_defined
# define __timer_t_defined 1
typedef __timer_t timer_t;
#endif
clock_t _EXFUN(clock, (void));
double _EXFUN(difftime, (time_t _time2, time_t _time1));
time_t _EXFUN(mktime, (struct tm *_timeptr));
time_t _EXFUN(time, (time_t *_timer));
#ifndef _REENT_ONLY
char *_EXFUN(asctime, (const struct tm *_tblock));
char *_EXFUN(ctime, (const time_t *_time));
struct tm *_EXFUN(gmtime, (const time_t *_timer));
struct tm *_EXFUN(localtime,(const time_t *_timer));
#endif
size_t _EXFUN(strftime, (char *_s, size_t _maxsize, const char *_fmt, const struct tm *_t));
char *_EXFUN(asctime_r, (const struct tm *, char *));
char *_EXFUN(ctime_r, (const time_t *, char *));
struct tm *_EXFUN(gmtime_r, (const time_t *, struct tm *));
struct tm *_EXFUN(localtime_r, (const time_t *, struct tm *));
#ifndef __STRICT_ANSI__
char *_EXFUN(strptime, (const char *, const char *, struct tm *));
_VOID _EXFUN(tzset, (_VOID));
_VOID _EXFUN(_tzset_r, (struct _reent *));
/* getdate functions */
#ifndef _REENT_ONLY
#define getdate_err (*__getdate_err())
int *_EXFUN(__getdate_err,(_VOID));
struct tm * _EXFUN(getdate, (const char *));
/* getdate_err is set to one of the following values to indicate the error.
1 the DATEMSK environment variable is null or undefined,
2 the template file cannot be opened for reading,
3 failed to get file status information,
4 the template file is not a regular file,
5 an error is encountered while reading the template file,
6 memory allication failed (not enough memory available),
7 there is no line in the template that matches the input,
8 invalid input specification */
#endif /* !_REENT_ONLY */
/* getdate_r returns the error code as above */
int _EXFUN(getdate_r, (const char *, struct tm *));
/* defines for the opengroup specifications Derived from Issue 1 of the SVID. */
extern __IMPORT time_t _timezone;
extern __IMPORT int _daylight;
extern __IMPORT char *_tzname[2];
/* POSIX defines the external tzname being defined in time.h */
#ifndef tzname
#define tzname _tzname
#endif
/* CYGWIN also exposes daylight and timezone in the name space */
#ifdef __CYGWIN__
#ifndef daylight
#define daylight _daylight
#endif
#if timezonevar
#ifndef timezone
#define timezone ((long int) _timezone)
#endif
#else
char *_EXFUN(timezone, (void));
#endif
#endif /* __CYGWIN__ */
#endif /* !__STRICT_ANSI__ */
#include <bits/posix_opt.h>
#if defined(_POSIX_TIMERS)
#include <signal.h>
/* Clocks, P1003.1b-1993, p. 263 */
int _EXFUN(clock_settime, (clockid_t clock_id, const struct timespec *tp));
int _EXFUN(clock_gettime, (clockid_t clock_id, struct timespec *tp));
int _EXFUN(clock_getres, (clockid_t clock_id, struct timespec *res));
/* Create a Per-Process Timer, P1003.1b-1993, p. 264 */
int _EXFUN(timer_create,
(clockid_t clock_id, struct sigevent *evp, timer_t *timerid));
/* Delete a Per_process Timer, P1003.1b-1993, p. 266 */
int _EXFUN(timer_delete, (timer_t timerid));
/* Per-Process Timers, P1003.1b-1993, p. 267 */
int _EXFUN(timer_settime,
(timer_t timerid, int flags, const struct itimerspec *value,
struct itimerspec *ovalue));
int _EXFUN(timer_gettime, (timer_t timerid, struct itimerspec *value));
int _EXFUN(timer_getoverrun, (timer_t timerid));
/* High Resolution Sleep, P1003.1b-1993, p. 269 */
int _EXFUN(nanosleep, (const struct timespec *rqtp, struct timespec *rmtp));
#endif /* _POSIX_TIMERS */
/* CPU-time Clock Attributes, P1003.4b/D8, p. 54 */
/* values for the clock enable attribute */
#define CLOCK_ENABLED 1 /* clock is enabled, i.e. counting execution time */
#define CLOCK_DISABLED 0 /* clock is disabled */
/* values for the pthread cputime_clock_allowed attribute */
#define CLOCK_ALLOWED 1 /* If a thread is created with this value a */
/* CPU-time clock attached to that thread */
/* shall be accessible. */
#define CLOCK_DISALLOWED 0 /* If a thread is created with this value, the */
/* thread shall not have a CPU-time clock */
/* accessible. */
/* Manifest Constants, P1003.1b-1993, p. 262 */
#define CLOCK_REALTIME (clockid_t)1
/* Flag indicating time is "absolute" with respect to the clock
associated with a time. */
#define TIMER_ABSTIME 4
/* Manifest Constants, P1003.4b/D8, p. 55 */
#if defined(_POSIX_CPUTIME)
/* When used in a clock or timer function call, this is interpreted as
the identifier of the CPU_time clock associated with the PROCESS
making the function call. */
#define CLOCK_PROCESS_CPUTIME (clockid_t)2
#endif
#if defined(_POSIX_THREAD_CPUTIME)
/* When used in a clock or timer function call, this is interpreted as
the identifier of the CPU_time clock associated with the THREAD
making the function call. */
#define CLOCK_THREAD_CPUTIME (clockid_t)3
#endif
#if defined(_POSIX_CPUTIME)
/* Accessing a Process CPU-time CLock, P1003.4b/D8, p. 55 */
int _EXFUN(clock_getcpuclockid, (pid_t pid, clockid_t *clock_id));
#endif /* _POSIX_CPUTIME */
#if defined(_POSIX_CPUTIME) || defined(_POSIX_THREAD_CPUTIME)
/* CPU-time Clock Attribute Access, P1003.4b/D8, p. 56 */
int _EXFUN(clock_setenable_attr, (clockid_t clock_id, int attr));
int _EXFUN(clock_getenable_attr, (clockid_t clock_id, int *attr));
#endif /* _POSIX_CPUTIME or _POSIX_THREAD_CPUTIME */
#ifdef __cplusplus
}
#endif
#endif /* _TIME_H_ */

View File

@ -0,0 +1,32 @@
/* This file contains a number of internal prototype declarations that
don't fit anywhere else. */
#ifndef _LIBC_INTERNAL
# define _LIBC_INTERNAL 1
#include <hp-timing.h>
/* macro to set errno */
#define __set_errno(x) (errno = (x))
/* Initialize the `__libc_enable_secure' flag. */
extern void __libc_init_secure (void);
/* This function will be called from _init in init-first.c. */
extern void __libc_global_ctors (void);
/* Discover the tick frequency of the machine if something goes wrong,
we return 0, an impossible hertz. */
extern int __profile_frequency (void);
/* Hooks for the instrumenting functions. */
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 hp_timing_t __get_clockfreq (void);
/* Free all allocated resources. */
extern void __libc_freeres (void);
#endif /* _LIBC_INTERNAL */

View File

@ -0,0 +1,83 @@
/* High precision, low overhead timing functions. Generic version.
Copyright (C) 1998, 2000 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
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. */
#ifndef _HP_TIMING_H
#define _HP_TIMING_H 1
/* There are no generic definitions for the times. We could write something
using the `gettimeofday' system call where available but the overhead of
the system call might be too high.
In case a platform supports timers in the hardware the following macros
and types must be defined:
- HP_TIMING_AVAIL: test for availability.
- HP_TIMING_INLINE: this macro is non-zero if the functionality is not
implemented using function calls but instead uses some inlined code
which might simply consist of a few assembler instructions. We have to
know this since we might want to use the macros here in places where we
cannot make function calls.
- hp_timing_t: This is the type for variables used to store the time
values.
- HP_TIMING_ZERO: clear `hp_timing_t' object.
- HP_TIMING_NOW: place timestamp for current time in variable given as
parameter.
- HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the
HP_TIMING_DIFF macro.
- HP_TIMING_DIFF: compute difference between two times and store it
in a third. Source and destination might overlap.
- HP_TIMING_ACCUM: add time difference to another variable. This might
be a bit more complicated to implement for some platforms as the
operation should be thread-safe and 64bit arithmetic on 32bit platforms
is not.
- HP_TIMING_ACCUM_NT: this is the variant for situations where we know
there are no threads involved.
- HP_TIMING_PRINT: write decimal representation of the timing value into
the given string. This operation need not be inline even though
HP_TIMING_INLINE is specified.
*/
/* Provide dummy definitions. */
#define HP_TIMING_AVAIL (0)
#define HP_TIMING_INLINE (0)
typedef int hp_timing_t;
#define HP_TIMING_ZERO(Var)
#define HP_TIMING_NOW(var)
#define HP_TIMING_DIFF_INIT()
#define HP_TIMING_DIFF(Diff, Start, End)
#define HP_TIMING_ACCUM(Sum, Diff)
#define HP_TIMING_ACCUM_NT(Sum, Diff)
#define HP_TIMING_PRINT(Buf, Len, Val)
/* Since this implementation is not available we tell the user about it. */
#define HP_TIMING_NONAVAIL 1
#endif /* hp-timing.h */

View File

@ -4,7 +4,7 @@ AUTOMAKE_OPTIONS = cygnus
INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
LIB_SOURCES = setjmp.S sigaction.c
LIB_SOURCES = get_clockfreq.c hp-timing.c setjmp.S sigaction.c
liblinuxi386_la_LDFLAGS = -Xcompiler -nostdlib

View File

@ -98,7 +98,7 @@ AUTOMAKE_OPTIONS = cygnus
INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
LIB_SOURCES = setjmp.S sigaction.c
LIB_SOURCES = get_clockfreq.c hp-timing.c setjmp.S sigaction.c
liblinuxi386_la_LDFLAGS = -Xcompiler -nostdlib
@ -122,11 +122,14 @@ DEFS = @DEFS@ -I. -I$(srcdir)
CPPFLAGS = @CPPFLAGS@
LIBS = @LIBS@
lib_a_LIBADD =
@USE_LIBTOOL_FALSE@lib_a_OBJECTS = setjmp.$(OBJEXT) sigaction.$(OBJEXT)
@USE_LIBTOOL_FALSE@lib_a_OBJECTS = get_clockfreq.$(OBJEXT) \
@USE_LIBTOOL_FALSE@hp-timing.$(OBJEXT) setjmp.$(OBJEXT) \
@USE_LIBTOOL_FALSE@sigaction.$(OBJEXT)
LTLIBRARIES = $(noinst_LTLIBRARIES)
liblinuxi386_la_LIBADD =
@USE_LIBTOOL_TRUE@liblinuxi386_la_OBJECTS = setjmp.lo sigaction.lo
@USE_LIBTOOL_TRUE@liblinuxi386_la_OBJECTS = get_clockfreq.lo \
@USE_LIBTOOL_TRUE@hp-timing.lo setjmp.lo sigaction.lo
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)

View File

@ -0,0 +1,117 @@
/* Get frequency of the system processor. i386/Linux version.
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 <ctype.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <libc-internal.h>
static
void *memmem (const void *a, size_t len1, const void *b, size_t len2)
{
char *end, *start;
char *ptr1, *ptr2;
if (len2 > len1)
return NULL;
start = (char *)a;
end = start + len1;
while (start < end)
{
size_t len = len2;
ptr1 = start;
ptr2 = (char *)b;
while (len > 0 && *ptr1++ == *ptr2++)
--len;
if (len == 0)
return start;
++start;
}
return NULL;
}
hp_timing_t
__get_clockfreq (void)
{
/* We read the information from the /proc filesystem. It contains at
least one line like
cpu MHz : 497.840237
or also
cpu MHz : 497.841
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, "cpu 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,24 @@
/* Support for high precision, low overhead timing functions. i686 version.
Copyright (C) 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
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 <hp-timing.h>
/* We have to define the variable for the overhead. */
hp_timing_t __libc_hp_timing_overhead;

View File

@ -0,0 +1,187 @@
/* High precision, low overhead timing functions. i686 version.
Copyright (C) 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
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. */
/* Modified for newlib by Jeff Johnston - June 27, 2002 */
#ifndef _HP_TIMING_H
#define _HP_TIMING_H 1
#include <string.h>
#include <stdio.h>
#include <sys/param.h>
#ifdef __i686__
/* The macros defined here use the timestamp counter in i586 and up versions
of the x86 processors. They provide a very accurate way to measure the
time with very little overhead. The time values themself have no real
meaning, only differences are interesting.
This version is for the i686 processors. The difference to the i586
version is that the timerstamp register is unconditionally used. This is
not the case for the i586 version where we have to perform runtime test
whether the processor really has this capability. We have to make this
distinction since the sysdeps/i386/i586 code is supposed to work on all
platforms while the i686 already contains i686-specific code.
The list of macros we need includes the following:
- HP_TIMING_AVAIL: test for availability.
- HP_TIMING_INLINE: this macro is non-zero if the functionality is not
implemented using function calls but instead uses some inlined code
which might simply consist of a few assembler instructions. We have to
know this since we might want to use the macros here in places where we
cannot make function calls.
- hp_timing_t: This is the type for variables used to store the time
values.
- HP_TIMING_ZERO: clear `hp_timing_t' object.
- HP_TIMING_NOW: place timestamp for current time in variable given as
parameter.
- HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the
HP_TIMING_DIFF macro.
- HP_TIMING_DIFF: compute difference between two times and store it
in a third. Source and destination might overlap.
- HP_TIMING_ACCUM: add time difference to another variable. This might
be a bit more complicated to implement for some platforms as the
operation should be thread-safe and 64bit arithmetic on 32bit platforms
is not.
- HP_TIMING_ACCUM_NT: this is the variant for situations where we know
there are no threads involved.
- HP_TIMING_PRINT: write decimal representation of the timing value into
the given string. This operation need not be inline even though
HP_TIMING_INLINE is specified.
*/
/* We always assume having the timestamp register. */
#define HP_TIMING_AVAIL (1)
/* We indeed have inlined functions. */
#define HP_TIMING_INLINE (1)
/* We use 64bit values for the times. */
typedef unsigned long long int hp_timing_t;
/* Internal variable used to store the overhead of the measurement
opcodes. */
extern hp_timing_t __libc_hp_timing_overhead;
/* Set timestamp value to zero. */
#define HP_TIMING_ZERO(Var) (Var) = (0)
/* That's quite simple. Use the `rdtsc' instruction. Note that the value
might not be 100% accurate since there might be some more instructions
running in this moment. This could be changed by using a barrier like
'cpuid' right before the `rdtsc' instruciton. But we are not interested
in accurate clock cycles here so we don't do this. */
#define HP_TIMING_NOW(Var) __asm__ __volatile__ ("rdtsc" : "=A" (Var))
/* Use two 'rdtsc' instructions in a row to find out how long it takes. */
#define HP_TIMING_DIFF_INIT() \
do { \
int __cnt = 5; \
__libc_hp_timing_overhead = ~0ull; \
do \
{ \
hp_timing_t __t1, __t2; \
HP_TIMING_NOW (__t1); \
HP_TIMING_NOW (__t2); \
if (__t2 - __t1 < __libc_hp_timing_overhead) \
__libc_hp_timing_overhead = __t2 - __t1; \
} \
while (--__cnt > 0); \
} while (0)
/* It's simple arithmetic for us. */
#define HP_TIMING_DIFF(Diff, Start, End) (Diff) = ((End) - (Start))
/* We have to jump through hoops to get this correctly implemented. */
#define HP_TIMING_ACCUM(Sum, Diff) \
do { \
char __not_done; \
hp_timing_t __oldval = (Sum); \
hp_timing_t __diff = (Diff) - __libc_hp_timing_overhead; \
do \
{ \
hp_timing_t __newval = __oldval + __diff; \
int __temp0, __temp1; \
__asm__ __volatile__ ("xchgl %4, %%ebx\n\t" \
"lock; cmpxchg8b %1\n\t" \
"sete %0\n\t" \
"movl %4, %%ebx" \
: "=q" (__not_done), "=m" (Sum), \
"=A" (__oldval), "=c" (__temp0), \
"=SD" (__temp1) \
: "1" (Sum), "2" (__oldval), \
"3" (__newval >> 32), \
"4" (__newval & 0xffffffff) \
: "memory"); \
} \
while (__not_done); \
} while (0)
/* No threads, no extra work. */
#define HP_TIMING_ACCUM_NT(Sum, Diff) (Sum) += (Diff)
/* Print the time value. */
#define HP_TIMING_PRINT(Buf, Len, Val) \
do { \
char __buf[20]; \
char *__cp = __buf + sizeof (__buf); \
int __len = (Len); \
char *__dest = (Buf); \
do { \
*--__cp = Val % 10; \
Val /= 10; \
} while (Val > 0); \
while (__len-- > 0 && __cp < __buf + sizeof (__buf)) \
*__dest++ = *__cp++; \
memcpy (__dest, " clock cycles", MIN (__len, sizeof (" clock cycles"))); \
} while (0)
#else /* !__i686__ */
/* Provide dummy definitions. */
#define HP_TIMING_AVAIL (0)
#define HP_TIMING_INLINE (0)
typedef int hp_timing_t;
#define HP_TIMING_ZERO(Var)
#define HP_TIMING_NOW(var)
#define HP_TIMING_DIFF_INIT()
#define HP_TIMING_DIFF(Diff, Start, End)
#define HP_TIMING_ACCUM(Sum, Diff)
#define HP_TIMING_ACCUM_NT(Sum, Diff)
#define HP_TIMING_PRINT(Buf, Len, Val)
/* Since this implementation is not available we tell the user about it. */
#define HP_TIMING_NONAVAIL 1
#endif
#endif /* hp-timing.h */

View File

@ -0,0 +1,73 @@
#ifndef _LINUX_TIME_H
#define _LINUX_TIME_H
#include <asm/param.h>
#include <sys/types.h>
#ifndef _STRUCT_TIMESPEC
#define _STRUCT_TIMESPEC
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
#endif /* _STRUCT_TIMESPEC */
/*
* Change timeval to jiffies, trying to avoid the
* most obvious overflows..
*
* And some not so obvious.
*
* Note that we don't want to return MAX_LONG, because
* for various timeout reasons we often end up having
* to wait "jiffies+1" in order to guarantee that we wait
* at _least_ "jiffies" - so "jiffies+1" had better still
* be positive.
*/
#define MAX_JIFFY_OFFSET ((~0UL >> 1)-1)
static __inline__ unsigned long
timespec_to_jiffies(struct timespec *value)
{
unsigned long sec = value->tv_sec;
long nsec = value->tv_nsec;
if (sec >= (MAX_JIFFY_OFFSET / HZ))
return MAX_JIFFY_OFFSET;
nsec += 1000000000L / HZ - 1;
nsec /= 1000000000L / HZ;
return HZ * sec + nsec;
}
static __inline__ void
jiffies_to_timespec(unsigned long jiffies, struct timespec *value)
{
value->tv_nsec = (jiffies % HZ) * (1000000000L / HZ);
value->tv_sec = jiffies / HZ;
}
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
struct timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of dst correction */
};
#define ITIMER_REAL 0
#define ITIMER_VIRTUAL 1
#define ITIMER_PROF 2
struct itimerspec {
struct timespec it_interval; /* timer period */
struct timespec it_value; /* timer expiration */
};
struct itimerval {
struct timeval it_interval; /* timer interval */
struct timeval it_value; /* current value */
};
#endif

View File

@ -42,7 +42,7 @@
#define _SYS_TIME_H
#include <sys/types.h>
#include <linux/time.h>
#include <sys/linux_time.h>
/* Macros for converting between `struct timeval' and `struct timespec'. */
# define TIMEVAL_TO_TIMESPEC(tv, ts) { \

View File

@ -201,7 +201,7 @@ sysconf (int name)
case _SC_ASYNCHRONOUS_IO:
#ifdef _POSIX_ASYNCHRONOUS_IO
return 1;TZNAME_MAX;
return 1;
#else
return -1;
#endif