From patchwork Tue Dec 16 20:24:38 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?T25kxZllaiBCw61sa2E=?= X-Patchwork-Id: 422066 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 931281400DE for ; Wed, 17 Dec 2014 07:24:57 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:subject:message-id:mime-version :content-type; q=dns; s=default; b=cm6NlvuuK86Mveykn/PF+zBmPJ6cz 1YNslH0pr5OhRwAVOIbLs0dDc0nNeiVWa4f9t+qF6ZpT+LaYDV7ecK4oT87YerzT pDU+YKEsSaTMuG4dJOrcqzeTEjG5Fo3kJCFoadQyzUwQrlwvmaYj4CLGrOk4qYHS /lV3VjfL1DmrOc= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:subject:message-id:mime-version :content-type; s=default; bh=00sX7McdFTZELyNnCYH2EKu0OaU=; b=tBQ +7m1LOFKxLgU4ZNLMwDmxiTy9HXnem7bKn149A8ebCTsPCubGZX5JWeZ89tYpems zs+Wfn29sWSv75cHG0LqI+sbcuTcGLzmAdJiVbUVD6dkCPTRUpyQWoM24wB3OIO7 3q1Yh72+u1KoBiW0zjefgfeJn0n2wsbNA+bkKC1w= Received: (qmail 31915 invoked by alias); 16 Dec 2014 20:24:51 -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 31906 invoked by uid 89); 16 Dec 2014 20:24:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.7 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, SPF_NEUTRAL autolearn=no version=3.3.2 X-HELO: popelka.ms.mff.cuni.cz Date: Tue, 16 Dec 2014 21:24:38 +0100 From: =?utf-8?B?T25kxZllaiBCw61sa2E=?= To: libc-alpha@sourceware.org Subject: [PATCH] Simplify strncat. Message-ID: <20141216202438.GA5612@domone> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) Hi, as in another thread found warning in default strncat implementation I looked to code and best way looks to replace loop by memcpy (dest, src, strnlen (src, n)); Its because code look misoptimized, a loop does byte-by-byte copy instead copying 4 bytes at once like for (i = 0; i < n; i += 4) { uint32 srcm = *((uint32_t *)(src + i)); if (has_zero (srcm)) /* use trick from strlen */ break; *((uint32_t *)(dst + i)) = *srcm; } where I for simplicity ommited aligning dest and simulating unaligned read when architecture does not allow it. As even generic memcpy and strnlen do these trick code will be lot faster unless you do most of calls to append 1-4 bytes. As strncat should not be used for performance sensitive task I decided to keep that simple. Also on my machine its almost never used. Only application that I could find is google-chrome which called strnlen 44 times total with following lenghts. dest src n 56 198 198 254 75 75 329 94 94 423 24 24 56 198 198 254 75 75 329 94 94 423 24 24 56 198 198 254 75 75 329 94 94 423 24 24 Tested on x64 with modified test, OK to commit? * string/strncat.c (STRNCAT): Simplify implementation. diff --git a/string/strncat.c b/string/strncat.c index 6d29114..e130a1f 100644 --- a/string/strncat.c +++ b/string/strncat.c @@ -29,52 +29,15 @@ char * STRNCAT (char *s1, const char *s2, size_t n) { - char c; char *s = s1; /* Find the end of S1. */ s1 += strlen (s1); - /* Make S1 point before next character, so we can increment - it while memory is read (wins on pipelined cpus). */ - s1 -= 1; + size_t ss = __strnlen (s2, n); - if (n >= 4) - { - size_t n4 = n >> 2; - do - { - c = *s2++; - *++s1 = c; - if (c == '\0') - return s; - c = *s2++; - *++s1 = c; - if (c == '\0') - return s; - c = *s2++; - *++s1 = c; - if (c == '\0') - return s; - c = *s2++; - *++s1 = c; - if (c == '\0') - return s; - } while (--n4 > 0); - n &= 3; - } - - while (n > 0) - { - c = *s2++; - *++s1 = c; - if (c == '\0') - return s; - n--; - } - - if (c != '\0') - *++s1 = '\0'; + memcpy (s1, s2, ss); + s1[ss] = '\000'; return s; }