From 5fc48cd78f0c50e889d1c1f3b8f812058db71ecd Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sat, 21 Apr 2001 07:55:01 +0000 Subject: Update. 2001-04-21 Ulrich Drepper * 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. --- linuxthreads/sysdeps/i386/i586/Makefile | 3 ++ linuxthreads/sysdeps/i386/i586/Versions | 5 ++ linuxthreads/sysdeps/i386/i586/ptclock_gettime.c | 45 ++++++++++++++++ linuxthreads/sysdeps/i386/i586/ptclock_settime.c | 32 ++++++++++++ linuxthreads/sysdeps/i386/i686/Implies | 1 + linuxthreads/sysdeps/i386/useldt.h | 66 +++++++++++++++++------- 6 files changed, 133 insertions(+), 19 deletions(-) create mode 100644 linuxthreads/sysdeps/i386/i586/Makefile create mode 100644 linuxthreads/sysdeps/i386/i586/Versions create mode 100644 linuxthreads/sysdeps/i386/i586/ptclock_gettime.c create mode 100644 linuxthreads/sysdeps/i386/i586/ptclock_settime.c create mode 100644 linuxthreads/sysdeps/i386/i686/Implies (limited to 'linuxthreads/sysdeps/i386') diff --git a/linuxthreads/sysdeps/i386/i586/Makefile b/linuxthreads/sysdeps/i386/i586/Makefile new file mode 100644 index 0000000000..96c195f6e5 --- /dev/null +++ b/linuxthreads/sysdeps/i386/i586/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),linuxthreads) +libpthread-sysdep_routines += ptclock_gettime ptclock_settime +endif diff --git a/linuxthreads/sysdeps/i386/i586/Versions b/linuxthreads/sysdeps/i386/i586/Versions new file mode 100644 index 0000000000..f9921aff55 --- /dev/null +++ b/linuxthreads/sysdeps/i386/i586/Versions @@ -0,0 +1,5 @@ +libpthread { + GLIBC_2.2.3 { + __pthread_clock_gettime; __pthread_clock_settime; + } +} diff --git a/linuxthreads/sysdeps/i386/i586/ptclock_gettime.c b/linuxthreads/sysdeps/i386/i586/ptclock_gettime.c new file mode 100644 index 0000000000..818251074e --- /dev/null +++ b/linuxthreads/sysdeps/i386/i586/ptclock_gettime.c @@ -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 +#include + +#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; +} diff --git a/linuxthreads/sysdeps/i386/i586/ptclock_settime.c b/linuxthreads/sysdeps/i386/i586/ptclock_settime.c new file mode 100644 index 0000000000..3026528cc2 --- /dev/null +++ b/linuxthreads/sysdeps/i386/i586/ptclock_settime.c @@ -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 +#include + +#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); +} diff --git a/linuxthreads/sysdeps/i386/i686/Implies b/linuxthreads/sysdeps/i386/i686/Implies new file mode 100644 index 0000000000..0df509e35f --- /dev/null +++ b/linuxthreads/sysdeps/i386/i686/Implies @@ -0,0 +1 @@ +i386/i586 diff --git a/linuxthreads/sysdeps/i386/useldt.h b/linuxthreads/sysdeps/i386/useldt.h index ebf520cc39..b9566ace1f 100644 --- a/linuxthreads/sysdeps/i386/useldt.h +++ b/linuxthreads/sysdeps/i386/useldt.h @@ -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 . @@ -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))); \ } \ -- cgit 1.4.1