On Wednesday 06 September 2006 23:15, Kevin Day wrote:
> I also discovered a possible problem with either my system or the
> uclibc on my system.
> The code example you gave above did not have a non-zero errno value
> returned (all returned a 0) with all of the following:
>
> (gcc-4.1.1)
> # gcc a.c -lm
> # gcc a.c -lm -fmath-errno
> # gcc a.c -ffast-math
> # gcc a.c -ffast-math -fmath-errno
cat >a.c <<EOF
/* In the previous letter I forgot stdio.h and gcc4 gave me a warning
about that. */
#include <stdio.h>
#include <math.h>
#include <errno.h>
int main ()
{
volatile double s = sqrt (-1);
printf ("%d\n", errno);
}
EOF
$ gcc4 -ffast-math a.c
$ ./a.out
0
$ gcc4 -ffast-math -fmath-errno a.c
$ ./a.out
0
$ gcc4 -lm a.c
$ ./a.out
33
$ gcc4 -lm -fmath-errno a.c
$ ./a.out
33
$ gcc4 -v
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: /home/pv/src/gcc-4.1.1/configure
--prefix=/home/pv/pkg/gcc/4.1.1 --disable-multilib --enable-shared
--enable-threads=posix --enable-version-specific-runtime-libs
--enable-languages=c --disable-checking --disable-nls
Thread model: posix
gcc version 4.1.1
Everything seems ok except -fmath-errno doesn't work as expected.
gcc-4.1.1 was built directly from gcc.gnu.org without any patches.
> uname -p returns: athlon-4
> ( Do you have a nice patch for uname that better handles the uname -p
> flags? I remember one of our patches already does that, but is not as
> "informative" as yours is)
I run the test from Gentoo machine. Gentoo patch makes uname just read
the processor name from /proc/cpuinfo so Gentoo version of uname depends
on /proc that's what I don't like.
It seems that the patch for this behavior is the attached one (extracted
from coreutils-5.94-patches-1.2.tar.bz2/patch/generic) though I'm not
sure (I haven't time to check this). You can also search for something
like coreutils-VERSION-patches... at
http://distfiles.gentoo.org/distfiles/.
> As a rather quick'n'dirty performance test, I tested the following:
> #include <math.h>
> #include <errno.h>
>
> int main ()
> {
> volatile double s = sqrt (-1);
> long i;
>
> for (i=0; i < 100000; i++){
> s = sqrt(-1);
> }
> }
>
> Against -lm, it took ~0.005s, whereas -ffast-math took ~0.001s.
In my turn, I have the following:
$ cat a.c
#include <math.h>
#include <stdio.h>
#include <errno.h>
int main ()
{
volatile double s = sqrt (-1);
long i;
for (i=0; i < 1000000; i++)
s = sqrt(-1);
printf ("%d\n", errno);
}
$ gcc4 a.c -lm
$ time ./a.out
33
real 0m0.056s
user 0m0.060s
sys 0m0.000s
$ gcc4 a.c -ffast-math
$ time ./a.out
0
real 0m0.005s
user 0m0.000s
sys 0m0.000s
$ gcc4 a.c -ffast-math -fmath-errno
$ time ./a.out
0
real 0m0.020s
user 0m0.020s
sys 0m0.000s
$ gcc3 a.c -ffast-math -fmath-errno
/tmp/ccOv3mc0.o: In function `main':
a.c:(.text+0x26): undefined reference to `sqrt'
a.c:(.text+0x47): undefined reference to `sqrt'
collect2: ld returned 1 exit status
$ gcc3 a.c -ffast-math -fmath-errno -lm
$ time ./a.out
33
real 0m0.057s
user 0m0.060s
sys 0m0.000s
$ gcc3 -v
Reading specs
from /home/pv/pkg/gcc/3.4.6/lib/gcc/i686-pc-linux-gnu/3.4.6/specs
Configured with: /home/pv/src/gcc-3.4.6/configure
--prefix=/home/pv/pkg/gcc/3.4.6 --disable-multilib --enable-shared
--enable-threads=posix --enable-version-specific-runtime-libs
--enable-languages=c --disable-checking --disable-nls
Thread model: posix
gcc version 3.4.6
Note that "gcc4 -ffast-math -fmath-errno" produces slower code than
"gcc4 -ffast-math" and faster one that "gcc4 -lm" though the executable
still doesn't print the correct errno value in the former case.
What's also interesting is that gcc3 and gcc4 handle -fmath-errno flag
in different ways. gcc4 just skips it while gcc3 uses a "usual"
function call instead of processor instruction when the flag is used.
It's this behavior that makes gcc3 giving the "undefined reference"
message and producing so slow code as without -ffast-math flag.
--
Nothing but perfection
pv
On linux platforms, grok /proc/cpuinfo for the CPU/vendor info.
Prob not suitable for upstream seeing as how it's 100% linux-specific
http://lists.gnu.org/archive/html/bug-coreutils/2005-09/msg00063.html
Patch originally by Carlos E. Gorges <[EMAIL PROTECTED]>, but
heavily reworked to suck less.
To add support for additional platforms, check out the show_cpuinfo()
func in the linux/arch/<ARCH>/ source tree of the kernel.
--- coreutils/src/uname.c
+++ coreutils/src/uname.c
@@ -51,6 +51,10 @@
# include <mach-o/arch.h>
#endif
+#if defined (__linux__)
+# define USE_PROCINFO
+#endif
+
#include "system.h"
#include "error.h"
#include "quote.h"
@@ -138,6 +143,95 @@ Print certain system information. With
exit (status);
}
+#if defined(USE_PROCINFO)
+
+# if defined(__s390__) || defined(__s390x__)
+# define CPUINFO_FILE "/proc/sysinfo"
+# define CPUINFO_FORMAT "%[^\t :]%*[ :]%[^\n]\n"
+# else
+# define CPUINFO_FILE "/proc/cpuinfo"
+# define CPUINFO_FORMAT "%[^\t:]\t:%[^\n]\n"
+# endif
+
+# define PROCINFO_ARCHITECTURE 0
+# define PROCINFO_HARDWARE_PLATFORM 1
+
+static void __eat_cpuinfo_space(char *buf)
+{
+ /* first eat trailing space */
+ char *tmp = buf + strlen(buf) - 1;
+ while (tmp > buf && isspace(*tmp))
+ *tmp-- = '\0';
+ /* then eat leading space */
+ tmp = buf;
+ while (*tmp && isspace(*tmp))
+ *tmp++;
+ if (tmp != buf)
+ memmove(buf, tmp, strlen(tmp)+1);
+}
+
+static int __linux_procinfo (int x, char *fstr, size_t s)
+{
+ FILE *fp;
+
+ char *procinfo_keys[] = {
+ #if defined(__i386__) || defined(__x86_64__)
+ "model name", "vendor_id"
+ #elif defined(__ia64__)
+ "family", "vendor"
+ #elif defined(__alpha__)
+ "cpu model", "system type"
+ #elif defined(sparc) || defined(__sparc__)
+ "type", "cpu"
+ #elif defined(__hppa__)
+ "cpu", "model"
+ #elif defined(__mips__)
+ "cpu model", "system type"
+ #elif defined(__powerpc__) || defined(__powerpc64__)
+ "cpu", "machine"
+ #elif defined(__arm__)
+ "Processor", "Hardware"
+ #elif defined(__s390__) || defined(__s390x__)
+ "Type", "Manufacturer"
+ #elif defined(__sh__)
+ "cpu family", "machine"
+ #elif defined(__m68k__)
+ "CPU", "MMU"
+ #elif defined(__cris__)
+ "cpu", "cpu model"
+ #elif defined(__frv__)
+ "CPU-Core", "System"
+ #elif defined(bfin)
+ "CPU", "BOARD Name"
+ #else
+ "unknown", "unknown"
+ #endif
+ };
+
+ if ((fp = fopen(CPUINFO_FILE, "r")) != NULL) {
+ char key[64], value[257], *ret = NULL;
+
+ while (fscanf(fp, CPUINFO_FORMAT, key, value) != EOF) {
+ __eat_cpuinfo_space(key);
+ if (!strcmp(key, procinfo_keys[x])) {
+ __eat_cpuinfo_space(value);
+ ret = value;
+ break;
+ }
+ }
+ fclose(fp);
+
+ if (ret) {
+ strncpy(fstr, ret, s);
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+#endif
+
/* Print ELEMENT, preceded by a space if something has already been
printed. */
@@ -250,10 +344,14 @@ main (int argc, char **argv)
if (toprint & PRINT_PROCESSOR)
{
char const *element = unknown;
-#if HAVE_SYSINFO && defined SI_ARCHITECTURE
+#if ( HAVE_SYSINFO && defined SI_ARCHITECTURE ) || defined(USE_PROCINFO)
{
static char processor[257];
+#if defined(USE_PROCINFO)
+ if (0 <= __linux_procinfo (PROCINFO_ARCHITECTURE, processor, sizeof processor))
+#else
if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor))
+#endif
element = processor;
}
#endif
@@ -306,9 +404,13 @@ main (int argc, char **argv)
if (element == unknown)
{
static char hardware_platform[257];
+#if defined(USE_PROCINFO)
+ if (0 <= __linux_procinfo (PROCINFO_HARDWARE_PLATFORM, hardware_platform, sizeof hardware_platform))
+#else
size_t s = sizeof hardware_platform;
static int mib[] = { CTL_HW, UNAME_HARDWARE_PLATFORM };
if (sysctl (mib, 2, hardware_platform, &s, 0, 0) >= 0)
+#endif
element = hardware_platform;
}
#endif
--
http://linuxfromscratch.org/mailman/listinfo/hlfs-dev
FAQ: http://www.linuxfromscratch.org/faq/
Unsubscribe: See the above information page