1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-30 22:43:12 +03:00
2001-04-21  Ulrich Drepper  <drepper@redhat.com>

	* elf/dl-support.c: Include cpuclock-init.h.  Use CPUCLOCK_VARDEF and
	CPUCLOCK_INIT if defined.
	* sysdeps/generic/dl-sysdep.c: Likewise.
	* sysdeps/generic/cpuclock-init.h: New file.
	* sysdeps/unix/i386/i586/cpuclock-init.h: New file.
	* sysdeps/unix/i386/i586/Versions: New file.
	* sysdeps/unix/i386/i586/clock_settime.c: New file.
	* sysdeps/unix/i386/i586/clock_gettime.c: Handle thread CPU clock
	separately by calling __pthread_clock_gettime if this function is
	available.  Subtract offset from tsc value before computing time value.
This commit is contained in:
Ulrich Drepper
2001-04-21 07:55:01 +00:00
parent b17c0a8e31
commit 5fc48cd78f
18 changed files with 358 additions and 28 deletions

View File

@ -1,3 +1,21 @@
2001-04-21 Ulrich Drepper <drepper@redhat.com>
* internals.h: Include <cpuclock-init.h>.
(struct _pthread_descr_struct): Add p_cpuclock_offset field if
CPUCLOCK_VARDEF is defined.
* pthread.c (__pthread_initialize_minimal): Initialize
p_cpuclock_offset field for main thread if CPUCLOCK_INIT is defined.
* manager.c (pthread_start_thread): Set p_cpuclock_offset field
for new thread to current CPU clock value.
* sysdeps/i386/useldt.h: Extend all the macros to handle 8-byte values.
* sysdeps/i386/i586/Makefile: New file.
* sysdeps/i386/i586/Versions: New file.
* sysdeps/i386/i586/ptclock_gettime.c: New file.
* sysdeps/i386/i586/ptclock_settime.c: New file.
* sysdeps/i386/i686/Implies: New file.
2001-04-18 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/sysv/linux/sparc/sparc64/Makefile: Put specs into

View File

@ -33,6 +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>
#ifndef THREAD_GETMEM
# define THREAD_GETMEM(descr, member) descr->member
@ -179,6 +180,9 @@ 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. */
#endif
/* New elements must be added at the end. */
} __attribute__ ((aligned(32))); /* We need to align the structure so that
doubles are aligned properly. This is 8

View File

@ -225,9 +225,16 @@ static int pthread_start_thread(void *arg)
pthread_descr self = (pthread_descr) arg;
struct pthread_request request;
void * outcome;
#ifdef CPUCLOCK_VARDEF
CPUCLOCK_VARDEF (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);
THREAD_SETMEM (self, p_cpuclock_offset, tmpclock);
#endif
/* Make sure our pid field is initialized, just in case we get there
before our father has initialized it. */

View File

@ -225,6 +225,11 @@ static void pthread_handle_sigcancel(int sig);
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);
#endif
/* Signal numbers used for the communication.
In these variables we keep track of the used variables. If the
platform does not support any real-time signals we will define the
@ -390,6 +395,9 @@ __pthread_initialize_minimal(void)
#ifdef INIT_THREAD_SELF
INIT_THREAD_SELF(&__pthread_initial_thread, 0);
#endif
#ifdef CPUCLOCK_INIT
__pthread_initial_thread.p_cpuclock_offset = _dl_cpuclock_offset;
#endif
}

View File

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

View File

@ -0,0 +1,5 @@
libpthread {
GLIBC_2.2.3 {
__pthread_clock_gettime; __pthread_clock_settime;
}
}

View File

@ -0,0 +1,45 @@
/* 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 <libc-internal.h>
#include "../../../internals.h"
int
__pthread_clock_gettime (unsigned long long int freq, struct timespec *tp)
{
unsigned long long int tsc;
pthread_descr self = thread_self ();
/* Get the current counter. */
asm volatile ("rdtsc" : "=A" (tsc));
/* Compute the offset since the start time of the process. */
tsc -= THREAD_GETMEM (self, p_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;
return 0;
}

View File

@ -0,0 +1,32 @@
/* 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 <libc-internal.h>
#include "../../../internals.h"
void
__pthread_clock_settime (unsigned long long int offset)
{
pthread_descr self = thread_self ();
/* Compute the offset since the start time of the process. */
THREAD_SETMEM (self, p_cpuclock_offset, offset);
}

View File

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

View File

@ -1,6 +1,6 @@
/* Special definitions for ix86 machine using segment register based
thread descriptor.
Copyright (C) 1998, 2000 Free Software Foundation, Inc.
Copyright (C) 1998, 2000, 2001 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>.
@ -88,16 +88,24 @@ extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t);
: "0" (0), \
"i" (offsetof (struct _pthread_descr_struct, \
member))); \
else if (sizeof (__value) == 4) \
__asm__ __volatile__ ("movl %%gs:%P1,%0" \
: "=r" (__value) \
: "i" (offsetof (struct _pthread_descr_struct, \
member))); \
else \
{ \
if (sizeof (__value) != 4) \
/* There should not be any value with a size other than 1 or 4. */ \
if (sizeof (__value) != 8) \
/* There should not be any value with a size other than 1, 4 or 8. */\
abort (); \
\
__asm__ __volatile__ ("movl %%gs:%P1,%0" \
: "=r" (__value) \
__asm__ __volatile__ ("movl %%gs:%P1,%%eax\n\t" \
"movl %%gs:%P2,%%edx" \
: "=A" (__value) \
: "i" (offsetof (struct _pthread_descr_struct, \
member))); \
member)), \
"i" (offsetof (struct _pthread_descr_struct, \
member) + 4)); \
} \
__value; \
})
@ -112,14 +120,20 @@ extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t);
: "0" (0), \
"r" (offsetof (struct _pthread_descr_struct, \
member))); \
else if (sizeof (__value) == 4) \
__asm__ __volatile__ ("movl %%gs:(%1),%0" \
: "=r" (__value) \
: "r" (offsetof (struct _pthread_descr_struct, \
member))); \
else \
{ \
if (sizeof (__value) != 4) \
/* There should not be any value with a size other than 1 or 4. */ \
if (sizeof (__value) != 8) \
/* There should not be any value with a size other than 1, 4 or 8. */\
abort (); \
\
__asm__ __volatile__ ("movl %%gs:(%1),%0" \
: "=r" (__value) \
__asm__ __volatile__ ("movl %%gs:(%1),%%eax\n\t" \
"movl %%gs:4(%1),%%edx" \
: "=&A" (__value) \
: "r" (offsetof (struct _pthread_descr_struct, \
member))); \
} \
@ -135,16 +149,24 @@ extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t);
: "q" (__value), \
"i" (offsetof (struct _pthread_descr_struct, \
member))); \
else if (sizeof (__value) == 4) \
__asm__ __volatile__ ("movl %0,%%gs:%P1" : \
: "r" (__value), \
"i" (offsetof (struct _pthread_descr_struct, \
member))); \
else \
{ \
if (sizeof (__value) != 4) \
/* There should not be any value with a size other than 1 or 4. */ \
if (sizeof (__value) != 8) \
/* There should not be any value with a size other than 1, 4 or 8. */\
abort (); \
\
__asm__ __volatile__ ("movl %0,%%gs:%P1" : \
: "r" (__value), \
__asm__ __volatile__ ("movl %%eax,%%gs:%P1\n\n" \
"movl %%edx,%%gs:%P2" : \
: "A" (__value), \
"i" (offsetof (struct _pthread_descr_struct, \
member))); \
member)), \
"i" (offsetof (struct _pthread_descr_struct, \
member) + 4)); \
} \
})
@ -157,14 +179,20 @@ extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t);
: "q" (__value), \
"r" (offsetof (struct _pthread_descr_struct, \
member))); \
else if (sizeof (__value) == 4) \
__asm__ __volatile__ ("movl %0,%%gs:(%1)" : \
: "r" (__value), \
"r" (offsetof (struct _pthread_descr_struct, \
member))); \
else \
{ \
if (sizeof (__value) != 4) \
/* There should not be any value with a size other than 1 or 4. */ \
if (sizeof (__value) != 8) \
/* There should not be any value with a size other than 1, 4 or 8. */\
abort (); \
\
__asm__ __volatile__ ("movl %0,%%gs:(%1)" : \
: "r" (__value), \
__asm__ __volatile__ ("movl %%eax,%%gs:(%1)\n\t" \
"movl %%edx,%%gs:4(%1)" : \
: "A" (__value), \
"r" (offsetof (struct _pthread_descr_struct, \
member))); \
} \