aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1998-11-13 13:21:56 +0000
committerUlrich Drepper <drepper@redhat.com>1998-11-13 13:21:56 +0000
commit7f2a1e3cf8077faa2c5de78f081890302a4c8362 (patch)
treefe02a7b2be425a9609d7bc3ffddc72b5efd54f1b /libio/bits/stdio.h
parent* sysdeps/unix/sysv/linux/m68k/sysdep.h (INLINE_SYSCALL): Remove (diff)
downloadglibc-7f2a1e3cf8077faa2c5de78f081890302a4c8362.tar.gz
glibc-7f2a1e3cf8077faa2c5de78f081890302a4c8362.tar.bz2
glibc-7f2a1e3cf8077faa2c5de78f081890302a4c8362.zip
Correct and improve fread_unlocked and fwrite_unlocked optimizations.
Diffstat (limited to 'libio/bits/stdio.h')
-rw-r--r--libio/bits/stdio.h39
1 files changed, 27 insertions, 12 deletions
diff --git a/libio/bits/stdio.h b/libio/bits/stdio.h
index f47749e1d6..a3e3d6fc8d 100644
--- a/libio/bits/stdio.h
+++ b/libio/bits/stdio.h
@@ -127,32 +127,47 @@ ferror_unlocked (FILE *__stream) __THROW
#if defined __USE_MISC && defined __GNUC__ && defined __OPTIMIZE__
/* Perform some simple optimizations. */
# define fread_unlocked(ptr, size, n, stream) \
- (__extension__ ((__builtin_constant_p (size) && __builtin_constant_p (n) \
+ (__extension__ ((((__builtin_constant_p (size) \
+ && ((size) == 0 || __builtin_constant_p (n))) \
+ || (__builtin_constant_p (n) && (n) == 0)) \
&& (size_t) ((size) * (n)) <= 8) \
? ({ char *__ptr = (char *) (ptr); \
FILE *__stream = (stream); \
- int __c; \
- size_t __cnt = (size) * (n); \
- while (__cnt-- > 0) \
+ size_t __size = (size); \
+ size_t __n = (n); \
+ size_t __readres = __n; \
+ size_t __cnt = __size * __n + 1; \
+ while (--__cnt > 0) \
{ \
- __c = _IO_getc_unlocked (__stream); \
+ int __c = _IO_getc_unlocked (__stream); \
if (__c == EOF) \
- break; \
+ { \
+ __readres = (__size * __n - __cnt) / __size; \
+ break; \
+ } \
*__ptr++ = __c; \
} \
- ((size_t) ((size) * (n)) - __cnt) / (size); }) \
+ __readres; }) \
: fread_unlocked (ptr, size, n, stream)))
# define fwrite_unlocked(ptr, size, n, stream) \
- (__extension__ ((__builtin_constant_p (size) && __builtin_constant_p (n) \
+ (__extension__ ((((__builtin_constant_p (size) \
+ && ((size) == 0 || __builtin_constant_p (n))) \
+ || (__builtin_constant_p (n) && (n) == 0)) \
&& (size_t) ((size) * (n)) <= 8) \
? ({ const char *__ptr = (const char *) (ptr); \
FILE *__stream = (stream); \
- size_t __cnt = (size) * (n); \
- while (__cnt-- > 0) \
+ size_t __size = (size); \
+ size_t __n = (n); \
+ size_t __writeres = __n; \
+ size_t __cnt = __size * __n + 1; \
+ while (--__cnt > 0) \
if (_IO_putc_unlocked (*__ptr++, __stream) == EOF) \
- break; \
- ((size_t) ((size) * (n)) - __cnt) / (size); }) \
+ { \
+ __writeres = (__size * __n - __cnt) / __size; \
+ break; \
+ } \
+ __writeres; }) \
: fwrite_unlocked (ptr, size, n, stream)))
#endif