This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: How are CPU-optimized libraries supposed to work?


On Fri, Oct 03, 2003 at 04:43:20PM -0700, Roland McGrath wrote:
> > Oh hm, I didn't realize that HP_TIMING_AVAIL was used for code in
> > addition to linker statistics etc.
> 
> It looks like it's only clock_gettime(CLOCK_*_CPUTIME_ID) that uses it.
> I've only glanced at the code and don't fully grok how it uses the value,
> but I do suspect that it matters that it get set early in startup.  But
> perhaps setting it in libc's initializer if ld.so failed to set it would be
> good enough.
> 
> The other approach is to make a i686-supporting i386-compatible ld.so by
> hacking it to detect the CPU flavor at runtime early on and do the
> initialization when possible.

It does matter that it get set early in startup.  It's used for a
quick, accurate wall time clock relative to process start time. 
However, all the spec has to say is:

Implementations shall also support the special clockid_t value
CLOCK_PROCESS_CPUTIME_ID, which represents the CPU-time clock of the
calling process when invoking one of the clock_*() or timer_*()
functions. For these clock IDs, the values returned by clock_gettime()
and specified by clock_settime() represent the amount of execution time
of the process associated with the clock.

I'm not quite sure that using rdtsc for this is kosher - it looks like
it's supposed to be a CPU-time clock, not a wall-time clock.  But in
any case, initializing it a little later doesn't seem like a big deal.
The difference is about a millisecond on my system.

With my previous patch:
Ret: 0 Time: 1116870 sec 181496067 nsec

With an i686 ld.so:
Ret: 0 Time: 0 sec 1388670 nsec

With this patch:
Ret: 0 Time: 0 sec 125189 nsec

How's this patch (besides ugly)?

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

2003-10-12  Daniel Jacobowitz  <drow@mvista.com>

	* sysdeps/generic/ldsodefs.h (struct rtld_global): Include timing
	members if HP_TIMING_PAD is defined.
	* sysdeps/i386/hp-timing.h: New file.
	* elf/Makefile: Add dl-altinit to routines, shared-only-routines.
	* elf/dl-altinit.c: New file.

--- glibc-2.3.2/sysdeps/generic/ldsodefs.h.orig	2003-10-03 11:47:45.000000000 -0400
+++ glibc-2.3.2/sysdeps/generic/ldsodefs.h	2003-10-03 11:48:10.000000000 -0400
@@ -292,7 +292,7 @@ struct rtld_global
   /* The object to be initialized first.  */
   EXTERN struct link_map *_dl_initfirst;
 
-#if HP_TIMING_AVAIL || HP_SMALL_TIMING_AVAIL
+#if HP_TIMING_AVAIL || HP_SMALL_TIMING_AVAIL || HP_TIMING_PAD
   /* Start time on CPU clock.  */
   EXTERN hp_timing_t _dl_cpuclock_offset;
 
--- /dev/null	1969-12-31 19:00:00.000000000 -0500
+++ glibc-2.3.2/sysdeps/i386/hp-timing.h	2003-10-03 11:50:30.000000000 -0400
@@ -0,0 +1,34 @@
+/* High precision, low overhead timing functions.  i386 version.
+   Copyright (C) 2003 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.  */
+
+#ifndef _i386_HP_TIMING_H
+#define _i386_HP_TIMING_H	1
+
+#define hp_timing_t hp_timing_t__
+#include <sysdeps/generic/hp-timing.h>
+#undef hp_timing_t
+
+/* We don't use high-precision timers, but we might load an i686 libpthread
+   which does.  */
+#define HP_TIMING_PAD 1
+
+/* i686 uses 64bit values for the times.  */
+typedef unsigned long long int hp_timing_t;
+
+#endif	/* hp-timing.h */
--- glibc-2.3.2/elf/Makefile.orig	2003-10-12 13:15:46.000000000 -0400
+++ glibc-2.3.2/elf/Makefile	2003-10-12 13:17:38.000000000 -0400
@@ -23,7 +23,7 @@ subdir		:= elf
 headers		= elf.h bits/elfclass.h link.h
 routines	= $(dl-routines) dl-open dl-close dl-support dl-iteratephdr \
 		  dl-iteratephdr-static dl-addr enbl-secure dl-profstub \
-		  dl-origin dl-libc dl-sym dl-tsd
+		  dl-origin dl-libc dl-sym dl-tsd dl-altinit
 
 # The core dynamic linking functions are in libc for the static and
 # profiled libraries.
@@ -40,6 +40,10 @@ elide-routines.os = $(all-dl-routines) d
 rtld-routines	:= rtld $(dl-routines) dl-sysdep dl-environ dl-minimal
 all-rtld-routines = $(rtld-routines) $(sysdep-rtld-routines)
 
+# We only need to re-run initializers if ld.so and libc.so might be built
+# for different machines, so only shared libraries need dl-altinit.
+shared-only-routines = dl-altinit
+
 distribute	:= rtld-Rules \
 		   $(rtld-routines:=.c) dynamic-link.h do-rel.h dl-machine.h \
 		   dl-cache.h dl-hash.h soinit.c sofini.c ldd.bash.in \
@@ -91,7 +95,7 @@ include ../Makeconfig
 
 ifeq ($(unwind-find-fde),yes)
 routines += unwind-dw2-fde-glibc
-shared-only-routines = unwind-dw2-fde-glibc
+shared-only-routines += unwind-dw2-fde-glibc
 endif
 
 before-compile  = $(objpfx)trusted-dirs.h
--- /dev/null	1969-12-31 19:00:00.000000000 -0500
+++ glibc-2.3.2/elf/dl-altinit.c	2003-10-12 13:23:15.000000000 -0400
@@ -0,0 +1,43 @@
+/* Extra initializers for shared libc.
+   Copyright (C) 2003 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 <ldsodefs.h>
+#include <hp-timing.h>
+
+/* This file is used from the shared libc, to initialize anything which
+   ld.so should have initialized but didn't - for instance, if ld.so
+   is built for a machine without HP_TIMING but libc.so is built for
+   a machine with HP_TIMING, clock_gettime will expect dl_cpuclock_offset
+   to be initialized.  */
+
+static void
+dlinit_hptiming (void)
+{
+#ifdef HP_TIMING_AVAIL
+  if (GL(dl_cpuclock_offset) == 0)
+    HP_TIMING_NOW (GL(dl_cpuclock_offset));
+#endif
+}
+
+static void dlinit_alt (void) __attribute__((constructor));
+static void
+dlinit_alt (void)
+{
+  dlinit_hptiming ();
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]