diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | libidn/iconvme.c | 18 | ||||
-rw-r--r-- | sysdeps/i386/i686/hp-timing.h | 24 | ||||
-rw-r--r-- | sysdeps/x86_64/hp-timing.h | 10 |
4 files changed, 42 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog index 18d5752d7a..f073d570c4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2005-03-15 Jakub Jelinek <jakub@redhat.com> + + [BZ #789] + * sysdeps/i386/i686/hp-timing.h (HP_TIMING_ACCUM): Fix asm constraints. + Remove memory clobber. + + * sysdeps/x86_64/hp-timing.h (HP_TIMING_ACCUM): Make the addition + thread-safe. Subtract GLRO(dl_hp_timing_overhead) from Diff. + 2005-03-14 Jakub Jelinek <jakub@redhat.com> * sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h: Don't include diff --git a/libidn/iconvme.c b/libidn/iconvme.c index daf0c8e349..cc4dd1daa5 100644 --- a/libidn/iconvme.c +++ b/libidn/iconvme.c @@ -41,10 +41,14 @@ #if HAVE_ICONV /* Get iconv etc. */ # include <iconv.h> -/* Get MB_LEN_MAX. */ +/* Get MB_LEN_MAX, CHAR_BIT. */ # include <limits.h> #endif +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t) -1) +#endif + /* Convert a zero-terminated string STR from the FROM_CODSET code set to the TO_CODESET code set. The returned string is allocated using malloc, and must be dellocated by the caller using free. On @@ -63,10 +67,18 @@ iconv_string (const char *str, const char *from_codeset, char *p = (char *) str; size_t inbytes_remaining = strlen (p); /* Guess the maximum length the output string can have. */ - size_t outbuf_size = (inbytes_remaining + 1) * MB_LEN_MAX; - size_t outbytes_remaining = outbuf_size - 1; /* -1 for NUL */ + size_t outbuf_size = inbytes_remaining + 1; + size_t outbytes_remaining; size_t err; int have_error = 0; + + /* Use a worst-case output size guess, so long as that wouldn't be + too large for comfort. It's OK if the guess is wrong so long as + it's nonzero. */ + size_t approx_sqrt_SIZE_MAX = SIZE_MAX >> (sizeof (size_t) * CHAR_BIT / 2); + if (outbuf_size <= approx_sqrt_SIZE_MAX / MB_LEN_MAX) + outbuf_size *= MB_LEN_MAX; + outbytes_remaining = outbuf_size - 1; #endif if (strcmp (to_codeset, from_codeset) == 0) diff --git a/sysdeps/i386/i686/hp-timing.h b/sysdeps/i386/i686/hp-timing.h index a5906835f7..b924869649 100644 --- a/sysdeps/i386/i686/hp-timing.h +++ b/sysdeps/i386/i686/hp-timing.h @@ -1,5 +1,5 @@ /* High precision, low overhead timing functions. i686 version. - Copyright (C) 1998, 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1998, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -119,26 +119,24 @@ typedef unsigned long long int hp_timing_t; /* We have to jump through hoops to get this correctly implemented. */ #define HP_TIMING_ACCUM(Sum, Diff) \ do { \ - char __not_done; \ + int __not_done; \ hp_timing_t __oldval = (Sum); \ hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead); \ do \ { \ hp_timing_t __newval = __oldval + __diff; \ int __temp0, __temp1; \ - __asm__ __volatile__ ("xchgl %4, %%ebx\n\t" \ + __asm__ __volatile__ ("xchgl %0, %%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"); \ + "sete %%bl\n\t" \ + "xchgl %0, %%ebx" \ + : "=SD" (__not_done), "=m" (Sum), \ + "=A" (__oldval), "=c" (__temp0) \ + : "m" (Sum), "2" (__oldval), \ + "3" ((unsigned int) (__newval >> 32)), \ + "0" ((unsigned int) __newval)); \ } \ - while (__not_done); \ + while ((unsigned char) __not_done); \ } while (0) /* No threads, no extra work. */ diff --git a/sysdeps/x86_64/hp-timing.h b/sysdeps/x86_64/hp-timing.h index e015ff79db..59a29abd45 100644 --- a/sysdeps/x86_64/hp-timing.h +++ b/sysdeps/x86_64/hp-timing.h @@ -1,5 +1,5 @@ /* High precision, low overhead timing functions. x86-64 version. - Copyright (C) 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005 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 @@ -31,7 +31,11 @@ /* The funny business for 32-bit mode is not required here. */ # undef HP_TIMING_ACCUM -# define HP_TIMING_ACCUM(Sum, Diff) ((Sum) += (Diff)) - +# define HP_TIMING_ACCUM(Sum, Diff) \ + do { \ + hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead); \ + __asm__ __volatile__ ("lock; addq %1, %0" \ + : "=m" (Sum) : "r" (__diff), "m" (Sum)); \ + } while (0) #endif /* hp-timing.h */ |