aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2019-02-05 18:55:59 -0200
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2019-02-27 10:00:37 -0300
commit457208b1e9498c1238b7af4387529388df0414c1 (patch)
treed7310c4d50b115ceef62d4c7a1de7fff9b2657e9
parent30a7e2081c690dbb22022e1a7d276341b7391434 (diff)
downloadglibc-457208b1e9498c1238b7af4387529388df0414c1.zip
glibc-457208b1e9498c1238b7af4387529388df0414c1.tar.gz
glibc-457208b1e9498c1238b7af4387529388df0414c1.tar.bz2
wcsmbs: optimize wcsnlen
This patch rewrites wcsnlen using wmemchr. The generic wmemchr already uses the strategy (loop unrolling and tail handling) and by using it it allows architectures that have optimized wmemchr (s390 and x86_64) to optimize wcsnlen as well. Checked on x86_64-linux-gnu. * wcsmbs/wcsnlen.c (__wcsnlen): Rewrite using wmemchr.
-rw-r--r--ChangeLog2
-rw-r--r--wcsmbs/wcsnlen.c22
2 files changed, 6 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index 97e70aa..9ab66cf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
2019-02-27 Adhemerval Zanella <adhemerval.zanella@linaro.org>
+ * wcsmbs/wcsnlen.c (__wcsnlen): Rewrite using wmemchr.
+
* wcsmbs/wcsncpy.c (__wcsncpy): Rewrite using wcsnlen, wmemset, and
wmemcpy.
diff --git a/wcsmbs/wcsnlen.c b/wcsmbs/wcsnlen.c
index f3d5fc1..d38c7e4 100644
--- a/wcsmbs/wcsnlen.c
+++ b/wcsmbs/wcsnlen.c
@@ -26,24 +26,10 @@
size_t
__wcsnlen (const wchar_t *s, size_t maxlen)
{
- size_t len = 0;
-
- while (maxlen > 0 && s[len] != L'\0')
- {
- ++len;
- if (--maxlen == 0 || s[len] == L'\0')
- return len;
- ++len;
- if (--maxlen == 0 || s[len] == L'\0')
- return len;
- ++len;
- if (--maxlen == 0 || s[len] == L'\0')
- return len;
- ++len;
- --maxlen;
- }
-
- return len;
+ const wchar_t *ret = __wmemchr (s, L'\0', maxlen);
+ if (ret)
+ maxlen = ret - s;
+ return maxlen;
}
#ifndef WCSNLEN
weak_alias (__wcsnlen, wcsnlen)