aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog19
-rw-r--r--benchtests/bench-strsep.c79
-rw-r--r--string/bits/string2.h90
-rw-r--r--string/string-inlines.c64
-rw-r--r--string/strsep.c26
-rw-r--r--sysdeps/unix/sysv/linux/internal_statvfs.c2
6 files changed, 145 insertions, 135 deletions
diff --git a/ChangeLog b/ChangeLog
index b8436d3..8e8c0a3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2015-12-21 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * benchtests/bench-strsep.c (oldstrsep): Add old implementation.
+ (do_one_test) Restore original string so iteration works.
+ * string/string-inlines.c (do_test): Create better input strings.
+ (test_main) Reduce number of testruns.
+ * string/string-inlines.c (__old_strsep_1c): New function.
+ (__old_strsep_2c): Likewise.
+ (__old_strsep_3c): Likewise.
+ * string/strsep.c (__strsep): Remove case of small delim string.
+ Call strcspn directly rather than strpbrk.
+ * string/bits/string2.h (__strsep): Remove define.
+ (__strsep_1c): Remove.
+ (__strsep_2c): Remove.
+ (__strsep_3c): Remove.
+ (strsep): Remove.
+ * sysdeps/unix/sysv/linux/internal_statvfs.c
+ (__statvfs_getflags): Rename to __strsep.
+
2016-12-21 Florian Weimer <fweimer@redhat.com>
* csu/libc-tls.c (_dl_tls_setup): Remove.
diff --git a/benchtests/bench-strsep.c b/benchtests/bench-strsep.c
index 774a093..4a53b4f 100644
--- a/benchtests/bench-strsep.c
+++ b/benchtests/bench-strsep.c
@@ -49,10 +49,56 @@ simple_strsep (char **s1, char *s2)
return begin;
}
+char *
+oldstrsep (char **stringp, const char *delim)
+{
+ char *begin, *end;
+
+ begin = *stringp;
+ if (begin == NULL)
+ return NULL;
+
+ /* A frequent case is when the delimiter string contains only one
+ character. Here we don't need to call the expensive `strpbrk'
+ function and instead work using `strchr'. */
+ if (delim[0] == '\0' || delim[1] == '\0')
+ {
+ char ch = delim[0];
+
+ if (ch == '\0')
+ end = NULL;
+ else
+ {
+ if (*begin == ch)
+ end = begin;
+ else if (*begin == '\0')
+ end = NULL;
+ else
+ end = strchr (begin + 1, ch);
+ }
+ }
+ else
+ /* Find the end of the token. */
+ end = strpbrk (begin, delim);
+
+ if (end)
+ {
+ /* Terminate the token and set *STRINGP past NUL character. */
+ *end++ = '\0';
+ *stringp = end;
+ }
+ else
+ /* No more delimiters; this is the last token. */
+ *stringp = NULL;
+
+ return begin;
+}
+
typedef char *(*proto_t) (const char **, const char *);
IMPL (simple_strsep, 0)
IMPL (strsep, 1)
+IMPL (oldstrsep, 2)
static void
do_one_test (impl_t * impl, const char *s1, const char *s2)
@@ -63,7 +109,10 @@ do_one_test (impl_t * impl, const char *s1, const char *s2)
TIMING_NOW (start);
for (i = 0; i < iters; ++i)
{
- CALL (impl, &s1, s2);
+ const char *s1a = s1;
+ CALL (impl, &s1a, s2);
+ if (s1a != NULL)
+ ((char*)s1a)[-1] = '1';
}
TIMING_NOW (stop);
@@ -76,7 +125,10 @@ static void
do_test (size_t align1, size_t align2, size_t len1, size_t len2, int fail)
{
char *s2 = (char *) (buf2 + align2);
- static const char d[] = "1234567890abcdef";
+
+ /* Search for a delimiter in a string containing mostly '0', so don't
+ use '0' as a delimiter. */
+ static const char d[] = "123456789abcdefg";
#define dl (sizeof (d) - 1)
char *ss2 = s2;
for (size_t l = len2; l > 0; l = l > dl ? l - dl : 0)
@@ -92,24 +144,9 @@ do_test (size_t align1, size_t align2, size_t len1, size_t len2, int fail)
FOR_EACH_IMPL (impl, 0)
{
char *s1 = (char *) (buf1 + align1);
- if (fail)
- {
- char *ss1 = s1;
- for (size_t l = len1; l > 0; l = l > dl ? l - dl : 0)
- {
- size_t t = l > dl ? dl : l;
- memcpy (ss1, d, t);
- ++ss1[len2 > 7 ? 7 : len2 - 1];
- ss1 += t;
- }
- }
- else
- {
- memset (s1, '0', len1);
- memcpy (s1 + (len1 - len2) - 2, s2, len2);
- if ((len1 / len2) > 4)
- memcpy (s1 + (len1 - len2) - (3 * len2), s2, len2);
- }
+ memset (s1, '0', len1);
+ if (!fail)
+ s1[len1 / 2] = '1';
s1[len1] = '\0';
do_one_test (impl, s1, s2);
}
@@ -127,7 +164,7 @@ test_main (void)
putchar ('\n');
for (size_t klen = 2; klen < 32; ++klen)
- for (size_t hlen = 2 * klen; hlen < 16 * klen; hlen += klen)
+ for (size_t hlen = 4 * klen; hlen < 8 * klen; hlen += klen)
{
do_test (0, 0, hlen, klen, 0);
do_test (0, 0, hlen, klen, 1);
diff --git a/string/bits/string2.h b/string/bits/string2.h
index e39d4f1..c136617 100644
--- a/string/bits/string2.h
+++ b/string/bits/string2.h
@@ -180,96 +180,6 @@ extern void *__rawmemchr (const void *__s, int __c);
#endif
-#if !defined _HAVE_STRING_ARCH_strsep || defined _FORCE_INLINES
-# ifndef _HAVE_STRING_ARCH_strsep
-
-extern char *__strsep_g (char **__stringp, const char *__delim);
-# define __strsep(s, reject) \
- __extension__ \
- ({ char __r0, __r1, __r2; \
- (__builtin_constant_p (reject) && __string2_1bptr_p (reject) \
- && (__r0 = ((const char *) (reject))[0], \
- ((const char *) (reject))[0] != '\0') \
- ? ((__r1 = ((const char *) (reject))[1], \
- ((const char *) (reject))[1] == '\0') \
- ? __strsep_1c (s, __r0) \
- : ((__r2 = ((const char *) (reject))[2], __r2 == '\0') \
- ? __strsep_2c (s, __r0, __r1) \
- : (((const char *) (reject))[3] == '\0' \
- ? __strsep_3c (s, __r0, __r1, __r2) \
- : __strsep_g (s, reject)))) \
- : __strsep_g (s, reject)); })
-# endif
-
-__STRING_INLINE char *__strsep_1c (char **__s, char __reject);
-__STRING_INLINE char *
-__strsep_1c (char **__s, char __reject)
-{
- char *__retval = *__s;
- if (__retval != NULL && (*__s = strchr (__retval, __reject)) != NULL)
- *(*__s)++ = '\0';
- return __retval;
-}
-
-__STRING_INLINE char *__strsep_2c (char **__s, char __reject1, char __reject2);
-__STRING_INLINE char *
-__strsep_2c (char **__s, char __reject1, char __reject2)
-{
- char *__retval = *__s;
- if (__retval != NULL)
- {
- char *__cp = __retval;
- while (1)
- {
- if (*__cp == '\0')
- {
- __cp = NULL;
- break;
- }
- if (*__cp == __reject1 || *__cp == __reject2)
- {
- *__cp++ = '\0';
- break;
- }
- ++__cp;
- }
- *__s = __cp;
- }
- return __retval;
-}
-
-__STRING_INLINE char *__strsep_3c (char **__s, char __reject1, char __reject2,
- char __reject3);
-__STRING_INLINE char *
-__strsep_3c (char **__s, char __reject1, char __reject2, char __reject3)
-{
- char *__retval = *__s;
- if (__retval != NULL)
- {
- char *__cp = __retval;
- while (1)
- {
- if (*__cp == '\0')
- {
- __cp = NULL;
- break;
- }
- if (*__cp == __reject1 || *__cp == __reject2 || *__cp == __reject3)
- {
- *__cp++ = '\0';
- break;
- }
- ++__cp;
- }
- *__s = __cp;
- }
- return __retval;
-}
-# ifdef __USE_MISC
-# define strsep(s, reject) __strsep (s, reject)
-# endif
-#endif
-
/* We need the memory allocation functions for inline strdup().
Referring to stdlib.h (even minimally) is not allowed
in any of the tight standards compliant modes. */
diff --git a/string/string-inlines.c b/string/string-inlines.c
index d43e589..7b1de71 100644
--- a/string/string-inlines.c
+++ b/string/string-inlines.c
@@ -63,6 +63,70 @@ __old_strtok_r_1c (char *__s, char __sep, char **__nextp)
return __result;
}
compat_symbol (libc, __old_strtok_r_1c, __strtok_r_1c, GLIBC_2_1_1);
+
+char *
+__old_strsep_1c (char **__s, char __reject)
+{
+ char *__retval = *__s;
+ if (__retval != NULL && (*__s = strchr (__retval, __reject)) != NULL)
+ *(*__s)++ = '\0';
+ return __retval;
+}
+compat_symbol (libc, __old_strsep_1c, __strsep_1c, GLIBC_2_1_1);
+
+char *
+__old_strsep_2c (char **__s, char __reject1, char __reject2)
+{
+ char *__retval = *__s;
+ if (__retval != NULL)
+ {
+ char *__cp = __retval;
+ while (1)
+ {
+ if (*__cp == '\0')
+ {
+ __cp = NULL;
+ break;
+ }
+ if (*__cp == __reject1 || *__cp == __reject2)
+ {
+ *__cp++ = '\0';
+ break;
+ }
+ ++__cp;
+ }
+ *__s = __cp;
+ }
+ return __retval;
+}
+compat_symbol (libc, __old_strsep_2c, __strsep_2c, GLIBC_2_1_1);
+
+char *
+__old_strsep_3c (char **__s, char __reject1, char __reject2, char __reject3)
+{
+ char *__retval = *__s;
+ if (__retval != NULL)
+ {
+ char *__cp = __retval;
+ while (1)
+ {
+ if (*__cp == '\0')
+ {
+ __cp = NULL;
+ break;
+ }
+ if (*__cp == __reject1 || *__cp == __reject2 || *__cp == __reject3)
+ {
+ *__cp++ = '\0';
+ break;
+ }
+ ++__cp;
+ }
+ *__s = __cp;
+ }
+ return __retval;
+}
+compat_symbol (libc, __old_strsep_3c, __strsep_3c, GLIBC_2_1_1);
#endif
#if SHLIB_COMPAT (libc, GLIBC_2_1_1, GLIBC_2_24)
diff --git a/string/strsep.c b/string/strsep.c
index 1054774..68581c8 100644
--- a/string/strsep.c
+++ b/string/strsep.c
@@ -29,30 +29,10 @@ __strsep (char **stringp, const char *delim)
if (begin == NULL)
return NULL;
- /* A frequent case is when the delimiter string contains only one
- character. Here we don't need to call the expensive `strpbrk'
- function and instead work using `strchr'. */
- if (delim[0] == '\0' || delim[1] == '\0')
- {
- char ch = delim[0];
-
- if (ch == '\0')
- end = NULL;
- else
- {
- if (*begin == ch)
- end = begin;
- else if (*begin == '\0')
- end = NULL;
- else
- end = strchr (begin + 1, ch);
- }
- }
- else
- /* Find the end of the token. */
- end = strpbrk (begin, delim);
+ /* Find the end of the token. */
+ end = begin + strcspn (begin, delim);
- if (end)
+ if (*end)
{
/* Terminate the token and set *STRINGP past NUL character. */
*end++ = '\0';
diff --git a/sysdeps/unix/sysv/linux/internal_statvfs.c b/sysdeps/unix/sysv/linux/internal_statvfs.c
index 012f93f..ce649cd 100644
--- a/sysdeps/unix/sysv/linux/internal_statvfs.c
+++ b/sysdeps/unix/sysv/linux/internal_statvfs.c
@@ -168,7 +168,7 @@ __statvfs_getflags (const char *name, int fstype, int fd)
char *cp = mntbuf.mnt_opts;
char *opt;
- while ((opt = strsep (&cp, ",")) != NULL)
+ while ((opt = __strsep (&cp, ",")) != NULL)
if (strcmp (opt, "ro") == 0)
result |= ST_RDONLY;
else if (strcmp (opt, "nosuid") == 0)