This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
BZ#14317: Optimze __xpg_strerror_r
- From: Andreas Jaeger <aj at suse dot com>
- To: libc-alpha <libc-alpha at sourceware dot org>
- Date: Sat, 01 Dec 2012 18:03:55 +0100
- Subject: BZ#14317: Optimze __xpg_strerror_r
Going through the waiting bugs, I noticed this small patch.
Bruno comments:
> The implementation of __xpg_strerror_r spends time doing an strlen call,
> and then potentially returning before the value is actually used.
>
> This can be optimized.
And Carlos answered:
> Bruno,
>
> Fold the copyright years together e.g. 1991-2012.
>
> If you haven't posted this to libc-alpha, please do and I'll ack.
>
> This looks like a straight forward and useful optimization.
Unfortunately, this was never send to libc-alpha.
Ok to put it in now?
Andreas
2012-12-01 Bruno Haible <bruno@clisp.org>
[BZ #14317]
* string/xpg-strerror.c (__xpg_strerror_r): Optimize, call strlen
only if needed.
diff --git a/string/xpg-strerror.c b/string/xpg-strerror.c
index 7e46b33..73600fb 100644
--- a/string/xpg-strerror.c
+++ b/string/xpg-strerror.c
@@ -1,5 +1,4 @@
-/* Copyright (C) 1991, 1993, 1995-1998, 2000, 2002, 2004, 2010, 2011
- Free Software Foundation, Inc.
+/* Copyright (C) 1991-2012 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
@@ -28,20 +27,27 @@ int
__xpg_strerror_r (int errnum, char *buf, size_t buflen)
{
const char *estr = __strerror_r (errnum, buf, buflen);
- size_t estrlen = strlen (estr);
+ /* We know that __strerror_r returns buf (with a dynamically computed
+ string) if errnum is invalid, otherwise it returns a string whose
+ storage has indefinite extent. */
if (estr == buf)
{
assert (errnum < 0 || errnum >= _sys_nerr_internal
|| _sys_errlist_internal[errnum] == NULL);
return EINVAL;
}
- assert (errnum >= 0 && errnum < _sys_nerr_internal
- && _sys_errlist_internal[errnum] != NULL);
+ else
+ {
+ assert (errnum >= 0 && errnum < _sys_nerr_internal
+ && _sys_errlist_internal[errnum] != NULL);
+
+ size_t estrlen = strlen (estr);
- /* Terminate the string in any case. */
- if (buflen > 0)
- *((char *) __mempcpy (buf, estr, MIN (buflen - 1, estrlen))) = '\0';
+ /* Terminate the string in any case. */
+ if (buflen > 0)
+ *((char *) __mempcpy (buf, estr, MIN (buflen - 1, estrlen))) = '\0';
- return buflen <= estrlen ? ERANGE : 0;
+ return buflen <= estrlen ? ERANGE : 0;
+ }
}
--
Andreas Jaeger aj@{suse.com,opensuse.org} Twitter/Identica: jaegerandi
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn,Jennifer Guild,Felix Imendörffer,HRB16746 (AG Nürnberg)
GPG fingerprint = 93A3 365E CE47 B889 DF7F FED1 389A 563C C272 A126