From patchwork Thu Aug 20 07:35:17 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ondrej Bilka X-Patchwork-Id: 8312 Received: (qmail 14860 invoked by alias); 20 Aug 2015 07:35:30 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 14832 invoked by uid 89); 20 Aug 2015 07:35:29 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.3 required=5.0 tests=AWL, BAYES_40, FREEMAIL_FROM, SPF_NEUTRAL autolearn=no version=3.3.2 X-HELO: popelka.ms.mff.cuni.cz Date: Thu, 20 Aug 2015 09:35:17 +0200 From: =?utf-8?B?T25kxZllaiBCw61sa2E=?= To: libc-alpha@sourceware.org Subject: [PATCH] Improve str(n)cat_chk performance. Message-ID: <20150820073517.GA6785@domone> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) 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 @@ . */ #include -#include - /* 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 -#include - - 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; }