about summary refs log tree commit diff
path: root/wcsmbs/wcsnlen.c
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 /wcsmbs/wcsnlen.c
parent30a7e2081c690dbb22022e1a7d276341b7391434 (diff)
downloadglibc-457208b1e9498c1238b7af4387529388df0414c1.tar.gz
glibc-457208b1e9498c1238b7af4387529388df0414c1.tar.xz
glibc-457208b1e9498c1238b7af4387529388df0414c1.zip
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.
Diffstat (limited to 'wcsmbs/wcsnlen.c')
-rw-r--r--wcsmbs/wcsnlen.c22
1 files changed, 4 insertions, 18 deletions
diff --git a/wcsmbs/wcsnlen.c b/wcsmbs/wcsnlen.c
index f3d5fc1fba..d38c7e4953 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)