This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Improve str(n)cat_chk performance.


Here we sync implementation with strcat/strncat generic one. That makes
performance comparable with strcat instead of slow byte-by-byte loop.

Ok to commit this?


	* debug/strcat_chk.c (__strcat_chk): Sync with generic implementation.
	* debug/strncat_chk.c (__strncat_chk): Likewise.

diff --git a/debug/strcat_chk.c b/debug/strcat_chk.c
index 8d7359f..8f26012 100644
--- a/debug/strcat_chk.c
+++ b/debug/strcat_chk.c
@@ -16,8 +16,6 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <string.h>
-#include <memcopy.h>
-
 
 /* Append SRC on the end of DEST.  */
 char *
@@ -26,32 +24,12 @@ __strcat_chk (dest, src, destlen)
      const char *src;
      size_t destlen;
 {
-  char *s1 = dest;
-  const char *s2 = src;
-  char c;
-
-  /* Find the end of the string.  */
-  do
-    {
-      if (__glibc_unlikely (destlen-- == 0))
-	__chk_fail ();
-      c = *s1++;
-    }
-  while (c != '\0');
-
-  /* Make S1 point before the next character, so we can increment
-     it while memory is read (wins on pipelined cpus).  */
-  ++destlen;
-  s1 -= 2;
-
-  do
-    {
-      if (__glibc_unlikely (destlen-- == 0))
-	__chk_fail ();
-      c = *s2++;
-      *++s1 = c;
-    }
-  while (c != '\0');
+  size_t len = strlen (dest);
+  size_t srclen = strlen (src);
 
+  if (__glibc_unlikely (len + srclen + 1 > destlen))
+    __chk_fail ();
+  
+  memcpy (dest + len, src, srclen + 1);
   return dest;
 }
diff --git a/debug/strncat_chk.c b/debug/strncat_chk.c
index 2951d05..c0a68c5 100644
--- a/debug/strncat_chk.c
+++ b/debug/strncat_chk.c
@@ -17,83 +17,16 @@
 
 #include <string.h>
 
-#include <memcopy.h>
-
-
 char *
-__strncat_chk (s1, s2, n, s1len)
-     char *s1;
-     const char *s2;
-     size_t n;
-     size_t s1len;
+__strncat_chk (char *dest, const char *src, size_t n, size_t destlen)
 {
-  char c;
-  char *s = s1;
-
-  /* Find the end of S1.  */
-  do
-    {
-      if (__glibc_unlikely (s1len-- == 0))
-	__chk_fail ();
-      c = *s1++;
-    }
-  while (c != '\0');
-
-  /* Make S1 point before next character, so we can increment
-     it while memory is read (wins on pipelined cpus).  */
-  ++s1len;
-  s1 -= 2;
-
-  if (n >= 4)
-    {
-      size_t n4 = n >> 2;
-      do
-	{
-	  if (__glibc_unlikely (s1len-- == 0))
-	    __chk_fail ();
-	  c = *s2++;
-	  *++s1 = c;
-	  if (c == '\0')
-	    return s;
-	  if (__glibc_unlikely (s1len-- == 0))
-	    __chk_fail ();
-	  c = *s2++;
-	  *++s1 = c;
-	  if (c == '\0')
-	    return s;
-	  if (__glibc_unlikely (s1len-- == 0))
-	    __chk_fail ();
-	  c = *s2++;
-	  *++s1 = c;
-	  if (c == '\0')
-	    return s;
-	  if (__glibc_unlikely (s1len-- == 0))
-	    __chk_fail ();
-	  c = *s2++;
-	  *++s1 = c;
-	  if (c == '\0')
-	    return s;
-	} while (--n4 > 0);
-      n &= 3;
-    }
-
-  while (n > 0)
-    {
-      if (__glibc_unlikely (s1len-- == 0))
-	__chk_fail ();
-      c = *s2++;
-      *++s1 = c;
-      if (c == '\0')
-	return s;
-      n--;
-    }
+  size_t len = strlen (dest);
+  size_t srclen = __strnlen (src, n);
 
-  if (c != '\0')
-    {
-      if (__glibc_unlikely (s1len-- == 0))
-	__chk_fail ();
-      *++s1 = '\0';
-    }
+  if (__glibc_unlikely (len + srclen + 1 > destlen))
+    __chk_fail ();
 
-  return s;
+  dest[len + srclen] = 0;
+  memcpy (dest + len, src, srclen);
+  return dest;
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]