Message ID | CAGQ9bdw=-pzbi00gn5t_W8pXBjU0edFvLGMNUc+o=g9og=f9+Q@mail.gmail.com |
---|---|
State | Committed |
Headers |
Return-Path: <x14307373@homiemail-mx23.g.dreamhost.com> X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx23.g.dreamhost.com (peon2454.g.dreamhost.com [208.113.200.127]) by wilcox.dreamhost.com (Postfix) with ESMTP id 0D724360076 for <siddhesh@wilcox.dreamhost.com>; Tue, 20 May 2014 07:24:07 -0700 (PDT) Received: by homiemail-mx23.g.dreamhost.com (Postfix, from userid 14307373) id B02F063FE90C2; Tue, 20 May 2014 07:24:07 -0700 (PDT) X-Original-To: glibc@patchwork.siddhesh.in Delivered-To: x14307373@homiemail-mx23.g.dreamhost.com 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 homiemail-mx23.g.dreamhost.com (Postfix) with ESMTPS id 97CED63FE90B5 for <glibc@patchwork.siddhesh.in>; Tue, 20 May 2014 07:24:07 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-type; q=dns; s=default; b=qrh9 3vEgFfDWWprr1hNaCRojhfVUHwMEAr8wkldRwjRG09Ye67wbBZr28/ASLQNLRzDZ tcZeeuxjRxif993rgc852I0AVwsLFVF3vA+3K8cUuB6KtHKM4SyjRfNN58D5a0gx hk9aJWLejkc6RLwkxODMK1KC2KDZLigPlEc4uBU= 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:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-type; s=default; bh=tHFJF6Ytqh QkAWY7mYIczb4lutM=; b=GxnjTU6DiQXcMPzN9Hp24RRXdXYgxzjE798dkg2mq8 c5ANGhceyI6A9/vBks62pqV0xctCCjebyAys88PgDCvnk7nDopVKh75KBt029cNr 2Oh9KVpvI1PLZSdNVrD6pkKx69WX8vsZh/CiJH75o165ZytByzB/TGd6PgbCkqa0 0= Received: (qmail 3563 invoked by alias); 20 May 2014 14:24:06 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: <libc-alpha.sourceware.org> List-Unsubscribe: <mailto:libc-alpha-unsubscribe-glibc=patchwork.siddhesh.in@sourceware.org> List-Subscribe: <mailto:libc-alpha-subscribe@sourceware.org> List-Archive: <http://sourceware.org/ml/libc-alpha/> List-Post: <mailto:libc-alpha@sourceware.org> List-Help: <mailto:libc-alpha-help@sourceware.org>, <http://sourceware.org/ml/#faqs> Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 3549 invoked by uid 89); 20 May 2014 14:24:05 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-ve0-f169.google.com X-Received: by 10.58.188.115 with SMTP id fz19mr1965055vec.40.1400595840910; Tue, 20 May 2014 07:24:00 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: <20140520131314.GB14500@spoyarek.pnq.redhat.com> References: <CAGQ9bdzqT1EyXYMwACrHpPU=vPjM_b72LJRjb7BW_OzJRXG3bw@mail.gmail.com> <20140520131314.GB14500@spoyarek.pnq.redhat.com> From: Konstantin Serebryany <konstantin.s.serebryany@gmail.com> Date: Tue, 20 May 2014 18:23:40 +0400 Message-ID: <CAGQ9bdw=-pzbi00gn5t_W8pXBjU0edFvLGMNUc+o=g9og=f9+Q@mail.gmail.com> Subject: Re: [PATCH 1/25] Remove nested functions: crypt/md5-crypt.c To: Siddhesh Poyarekar <siddhesh@redhat.com> Cc: GNU C Library <libc-alpha@sourceware.org> Content-Type: multipart/mixed; boundary=089e012945fa925f1104f9d5a111 X-DH-Original-To: glibc@patchwork.siddhesh.in |
Commit Message
Kostya Serebryany
May 20, 2014, 2:23 p.m. UTC
2014-05-20 Kostya Serebryany <konstantin.s.serebryany@gmail.com> * crypt/md5-crypt.c (__md5_crypt_r): Remove a nested function. (b64_from_24bit): New function. On Tue, May 20, 2014 at 5:13 PM, Siddhesh Poyarekar <siddhesh@redhat.com> wrote: > On Tue, May 20, 2014 at 04:56:27PM +0400, Konstantin Serebryany wrote: >> Hi, >> >> This patch is the first in the series of patches that remove nested >> functions from glibc. >> Rationale: nested functions is a non-standard language feature; >> removing nested functions >> will allow to compile glibc with compilers other than GCC and thus >> benefit from other compilers >> and code analysis tools. >> Discussed previously here: >> https://sourceware.org/ml/libc-alpha/2014-05/msg00400.html >> No functionality change intended. >> >> (If approved, this will be my first commit to glibc, so some more >> actions may be required) > > I believe initially you'll need one of us to commit for you, which we > will do once the patch is found suitable. You may want to review the > contribution checklist as well: > > http://sourceware.org/glibc/wiki/Contribution%20checklist > >> >> 2014-05-20 Kostya Serebryany <konstantin.s.serebryany@gmail.com> > > Two spaces between the date and name, and name and email. An extra > newline between the ChangeLog content and header. > >> * crypt/md5-crypt.c (__md5_crypt_r): Remove a nested function. >> (b64_from_24bit): New function. >> >> >> diff --git a/crypt/md5-crypt.c b/crypt/md5-crypt.c >> index d1b92d7..29f66ce 100644 >> --- a/crypt/md5-crypt.c >> +++ b/crypt/md5-crypt.c >> @@ -88,6 +88,19 @@ extern char *__md5_crypt_r (const char *key, const >> char *salt, >> char *buffer, int buflen); >> extern char *__md5_crypt (const char *key, const char *salt); >> >> +static void b64_from_24bit (char **cp, int *buflen, > > 'static void' should be on a separate line on its own. done > >> + unsigned int b2, unsigned int b1, unsigned int b0, >> + int n) >> +{ >> + unsigned int w = (b2 << 16) | (b1 << 8) | b0; >> + while (n-- > 0 && *buflen > 0) >> + { >> + *(*cp)++ = b64t[w & 0x3f]; >> + --*buflen; >> + w >>= 6; >> + } >> +} >> + >> >> /* This entry point is equivalent to the `crypt' function in Unix >> libcs. */ >> @@ -268,24 +281,18 @@ __md5_crypt_r (key, salt, buffer, buflen) >> --buflen; >> } >> >> - void b64_from_24bit (unsigned int b2, unsigned int b1, unsigned int b0, >> - int n) >> - { >> - unsigned int w = (b2 << 16) | (b1 << 8) | b0; >> - while (n-- > 0 && buflen > 0) >> - { >> - *cp++ = b64t[w & 0x3f]; >> - --buflen; >> - w >>= 6; >> - } >> - } >> - >> - b64_from_24bit (alt_result[0], alt_result[6], alt_result[12], 4); >> - b64_from_24bit (alt_result[1], alt_result[7], alt_result[13], 4); >> - b64_from_24bit (alt_result[2], alt_result[8], alt_result[14], 4); >> - b64_from_24bit (alt_result[3], alt_result[9], alt_result[15], 4); >> - b64_from_24bit (alt_result[4], alt_result[10], alt_result[5], 4); >> - b64_from_24bit (0, 0, alt_result[11], 2); >> + b64_from_24bit (&cp, &buflen, >> + alt_result[0], alt_result[6], alt_result[12], 4); >> + b64_from_24bit (&cp, &buflen, >> + alt_result[1], alt_result[7], alt_result[13], 4); >> + b64_from_24bit (&cp, &buflen, >> + alt_result[2], alt_result[8], alt_result[14], 4); >> + b64_from_24bit (&cp, &buflen, >> + alt_result[3], alt_result[9], alt_result[15], 4); >> + b64_from_24bit (&cp, &buflen, >> + alt_result[4], alt_result[10], alt_result[5], 4); >> + b64_from_24bit (&cp, &buflen, >> + 0, 0, alt_result[11], 2); >> if (buflen <= 0) >> { >> __set_errno (ERANGE); > > It would be useful if you could post some kind of performance analysis > of the crypt or crypt_r to show that making this change does not cause > a significant drop in performance. In fact, I'd be really interested > in having a microbenchmark added for this function in benchtests. > Instructions in benchtests/README should be useful but if not, please > feel free to reach out to me for help. Do you think such a benchmarks is possible at all? I've made a simple test (attached) and profiled it with "perf": 85.26% a.out libcrypt-2.15.so [.] _ufc_doit_r 6.13% a.out libcrypt-2.15.so [.] _ufc_mk_keytab_r 2.40% a.out libcrypt-2.15.so [.] _ufc_setup_salt_r 1.56% a.out libcrypt-2.15.so [.] __crypt_r 1.51% a.out libcrypt-2.15.so [.] _ufc_output_conversion_r 1.35% a.out libcrypt-2.15.so [.] crypt As you can see, crypt_r itself takes a tiny fraction of time, most of it is spent in _ufc_* which are defined in another module. Any changes in crypt itself (unless you do something insane) will not be observable in profile. Updated patch: libcs. */ @@ -268,24 +282,18 @@ __md5_crypt_r (key, salt, buffer, buflen) --buflen; } - void b64_from_24bit (unsigned int b2, unsigned int b1, unsigned int b0, - int n) - { - unsigned int w = (b2 << 16) | (b1 << 8) | b0; - while (n-- > 0 && buflen > 0) - { - *cp++ = b64t[w & 0x3f]; - --buflen; - w >>= 6; - } - } - - b64_from_24bit (alt_result[0], alt_result[6], alt_result[12], 4); - b64_from_24bit (alt_result[1], alt_result[7], alt_result[13], 4); - b64_from_24bit (alt_result[2], alt_result[8], alt_result[14], 4); - b64_from_24bit (alt_result[3], alt_result[9], alt_result[15], 4); - b64_from_24bit (alt_result[4], alt_result[10], alt_result[5], 4); - b64_from_24bit (0, 0, alt_result[11], 2); + b64_from_24bit (&cp, &buflen, + alt_result[0], alt_result[6], alt_result[12], 4); + b64_from_24bit (&cp, &buflen, + alt_result[1], alt_result[7], alt_result[13], 4); + b64_from_24bit (&cp, &buflen, + alt_result[2], alt_result[8], alt_result[14], 4); + b64_from_24bit (&cp, &buflen, + alt_result[3], alt_result[9], alt_result[15], 4); + b64_from_24bit (&cp, &buflen, + alt_result[4], alt_result[10], alt_result[5], 4); + b64_from_24bit (&cp, &buflen, + 0, 0, alt_result[11], 2); if (buflen <= 0) { __set_errno (ERANGE);
Comments
On Tue, May 20, 2014 at 06:23:40PM +0400, Konstantin Serebryany wrote: > Do you think such a benchmarks is possible at all? > I've made a simple test (attached) and profiled it with "perf": > 85.26% a.out libcrypt-2.15.so [.] _ufc_doit_r > 6.13% a.out libcrypt-2.15.so [.] _ufc_mk_keytab_r > 2.40% a.out libcrypt-2.15.so [.] _ufc_setup_salt_r > 1.56% a.out libcrypt-2.15.so [.] __crypt_r > 1.51% a.out libcrypt-2.15.so [.] _ufc_output_conversion_r > 1.35% a.out libcrypt-2.15.so [.] crypt > > As you can see, crypt_r itself takes a tiny fraction of time, > most of it is spent in _ufc_* which are defined in another module. > Any changes in crypt itself (unless you do something insane) will not > be observable in profile. You'll need to choose inputs so that __md5_crypt_r is called - crypt/crypt-entry.c should help you with that. if __md5_crypt_r takes a tiny fraction of time again, then this change should be safe, but I would prefer that the inputs get fed into the benchtests anyway so that we can automatically track performance of crypt for those inputs in future. Siddhesh
On Tue, 20 May 2014, Siddhesh Poyarekar wrote: > On Tue, May 20, 2014 at 06:23:40PM +0400, Konstantin Serebryany wrote: > > Do you think such a benchmarks is possible at all? > > I've made a simple test (attached) and profiled it with "perf": > > 85.26% a.out libcrypt-2.15.so [.] _ufc_doit_r > > 6.13% a.out libcrypt-2.15.so [.] _ufc_mk_keytab_r > > 2.40% a.out libcrypt-2.15.so [.] _ufc_setup_salt_r > > 1.56% a.out libcrypt-2.15.so [.] __crypt_r > > 1.51% a.out libcrypt-2.15.so [.] _ufc_output_conversion_r > > 1.35% a.out libcrypt-2.15.so [.] crypt > > > > As you can see, crypt_r itself takes a tiny fraction of time, > > most of it is spent in _ufc_* which are defined in another module. > > Any changes in crypt itself (unless you do something insane) will not > > be observable in profile. > > You'll need to choose inputs so that __md5_crypt_r is called - > crypt/crypt-entry.c should help you with that. if __md5_crypt_r takes > a tiny fraction of time again, then this change should be safe, but I > would prefer that the inputs get fed into the benchtests anyway so > that we can automatically track performance of crypt for those inputs > in future. Another thing that can be done is to look at the code generated for the relevant file before and after the patch - I'd expect very little change.
On Tue, May 20, 2014 at 02:54:41PM +0000, Joseph S. Myers wrote: > On Tue, 20 May 2014, Siddhesh Poyarekar wrote: > > > On Tue, May 20, 2014 at 06:23:40PM +0400, Konstantin Serebryany wrote: > > > Do you think such a benchmarks is possible at all? > > > I've made a simple test (attached) and profiled it with "perf": > > > 85.26% a.out libcrypt-2.15.so [.] _ufc_doit_r > > > 6.13% a.out libcrypt-2.15.so [.] _ufc_mk_keytab_r > > > 2.40% a.out libcrypt-2.15.so [.] _ufc_setup_salt_r > > > 1.56% a.out libcrypt-2.15.so [.] __crypt_r > > > 1.51% a.out libcrypt-2.15.so [.] _ufc_output_conversion_r > > > 1.35% a.out libcrypt-2.15.so [.] crypt > > > > > > As you can see, crypt_r itself takes a tiny fraction of time, > > > most of it is spent in _ufc_* which are defined in another module. > > > Any changes in crypt itself (unless you do something insane) will not > > > be observable in profile. > > > > You'll need to choose inputs so that __md5_crypt_r is called - > > crypt/crypt-entry.c should help you with that. if __md5_crypt_r takes > > a tiny fraction of time again, then this change should be safe, but I > > would prefer that the inputs get fed into the benchtests anyway so > > that we can automatically track performance of crypt for those inputs > > in future. > > Another thing that can be done is to look at the code generated for the > relevant file before and after the patch - I'd expect very little change. > Yes I wanted to write that benchmarking this change is probably pointless as gcc should optimize them in same way (if there is consistently difference in one way we could report that as gcc regression.) Also perf data show that its a cold function so you should improve readability not performance (measuring difference is possible but you need to run that for few days and wait until standard deviation drops sufficiently to get statistically significant result). About only way this could make difference is if when it gets inlined in one way and does not in other. That is out of scope of microbenchmarks, instruction cache misses easily could make a function slower in wild but you would measure that inlined function is faster when you would call it in tight loop. As actual change is concerned
On Tue, May 20, 2014 at 6:46 PM, Siddhesh Poyarekar <siddhesh@redhat.com> wrote: > On Tue, May 20, 2014 at 06:23:40PM +0400, Konstantin Serebryany wrote: >> Do you think such a benchmarks is possible at all? >> I've made a simple test (attached) and profiled it with "perf": >> 85.26% a.out libcrypt-2.15.so [.] _ufc_doit_r >> 6.13% a.out libcrypt-2.15.so [.] _ufc_mk_keytab_r >> 2.40% a.out libcrypt-2.15.so [.] _ufc_setup_salt_r >> 1.56% a.out libcrypt-2.15.so [.] __crypt_r >> 1.51% a.out libcrypt-2.15.so [.] _ufc_output_conversion_r >> 1.35% a.out libcrypt-2.15.so [.] crypt >> >> As you can see, crypt_r itself takes a tiny fraction of time, >> most of it is spent in _ufc_* which are defined in another module. >> Any changes in crypt itself (unless you do something insane) will not >> be observable in profile. > > You'll need to choose inputs so that __md5_crypt_r is called - > crypt/crypt-entry.c should help you with that. With salt == "$1$" I get this profile: 84.70% a.out libcrypt-2.15.so [.] __md5_process_block 5.98% a.out libc-2.15.so [.] __memcpy_ssse3_back 4.71% a.out libcrypt-2.15.so [.] __md5_process_bytes 1.92% a.out libcrypt-2.15.so [.] __md5_crypt_r 1.62% a.out libcrypt-2.15.so [.] __md5_finish_ctx Again, __md5_crypt_r is within noise. >> Another thing that can be done is to look at the code generated for the >> relevant file before and after the patch - I'd expect very little change. I like this method much more, but there is actually a change. The original binary has calls to b64_from_24bit.7858 (the nested function), while in the binary built with my patch these calls are inlined. Of course, this is a feature of a particular version of GCC, not of the glibc code. > if __md5_crypt_r takes > a tiny fraction of time again, then this change should be safe, but I > would prefer that the inputs get fed into the benchtests anyway so > that we can automatically track performance of crypt for those inputs > in future. > > Siddhesh
On Tue, May 20, 2014 at 05:20:31PM +0200, Ondřej Bílka wrote: > Yes I wanted to write that benchmarking this change is probably > pointless as gcc should optimize them in same way (if there is > consistently difference in one way we could report that as gcc regression.) > > Also perf data show that its a cold function so you should improve > readability not performance (measuring difference is possible but you > need to run that for few days and wait until standard deviation drops > sufficiently to get statistically significant result). > > About only way this could make difference is if when it gets inlined in > one way and does not in other. > That is out of scope of microbenchmarks, instruction cache misses easily > could make a function slower in wild but you would measure that inlined > function is faster when you would call it in tight loop. Fair enough. I'll push the patch if Konstantin shows that the generated code is not drastically different. Siddhesh
On Tue, May 20, 2014 at 7:27 PM, Siddhesh Poyarekar <siddhesh@redhat.com> wrote: > On Tue, May 20, 2014 at 05:20:31PM +0200, Ondřej Bílka wrote: >> Yes I wanted to write that benchmarking this change is probably >> pointless as gcc should optimize them in same way (if there is >> consistently difference in one way we could report that as gcc regression.) >> >> Also perf data show that its a cold function so you should improve >> readability not performance (measuring difference is possible but you >> need to run that for few days and wait until standard deviation drops >> sufficiently to get statistically significant result). >> >> About only way this could make difference is if when it gets inlined in >> one way and does not in other. >> That is out of scope of microbenchmarks, instruction cache misses easily >> could make a function slower in wild but you would measure that inlined >> function is faster when you would call it in tight loop. > > Fair enough. I'll push the patch if Konstantin shows that the > generated code is not drastically different. Just a data point; I am not sure if it proves anything. If I add __attribute__ ((noinline)) to the definition of b64_from_24bit, the two binaries become more similar. The non-nested variant is a bit longer as it needs 6 instructions to pass the parameters: 15a9: 0f b6 8d 87 fe ff ff movzbl -0x179(%rbp),%ecx 15b0: 0f b6 95 81 fe ff ff movzbl -0x17f(%rbp),%edx 15b7: 41 b9 04 00 00 00 mov $0x4,%r9d 15bd: 44 0f b6 85 8d fe ff movzbl -0x173(%rbp),%r8d 15c4: ff 15c5: 48 89 de mov %rbx,%rsi 15c8: 4c 89 f7 mov %r14,%rdi 15cb: e8 40 fb ff ff callq 1110 <b64_from_24bit> The nested variant needs 5: 15bf: 0f b6 95 7e fe ff ff movzbl -0x182(%rbp),%edx 15c6: 0f b6 b5 78 fe ff ff movzbl -0x188(%rbp),%esi 15cd: 49 89 da mov %rbx,%r10 15d0: 0f b6 bd 72 fe ff ff movzbl -0x18e(%rbp),%edi 15d7: b9 04 00 00 00 mov $0x4,%ecx 15dc: e8 2f fb ff ff callq 1110 <b64_from_24bit.7858> With inlining (that happens for me only in the non-nested variant) this is irrelevant. > > Siddhesh
On Tue, May 20, 2014 at 07:25:52PM +0400, Konstantin Serebryany wrote: > With salt == "$1$" I get this profile: > 84.70% a.out libcrypt-2.15.so [.] __md5_process_block > 5.98% a.out libc-2.15.so [.] __memcpy_ssse3_back > 4.71% a.out libcrypt-2.15.so [.] __md5_process_bytes > 1.92% a.out libcrypt-2.15.so [.] __md5_crypt_r > 1.62% a.out libcrypt-2.15.so [.] __md5_finish_ctx > > Again, __md5_crypt_r is within noise. That's good. > > >> Another thing that can be done is to look at the code generated for the > >> relevant file before and after the patch - I'd expect very little change. > > I like this method much more, but there is actually a change. > The original binary has calls to b64_from_24bit.7858 (the nested function), > while in the binary built with my patch these calls are inlined. > Of course, this is a feature of a particular version of GCC, not of > the glibc code. Given that this does not have a very big impact, I'm inclined to accepting this change. I'll push it in on Thursday after noon UTC if nobody objects. Siddhesh
On Tue, May 20, 2014 at 7:46 PM, Siddhesh Poyarekar <siddhesh@redhat.com> wrote: > On Tue, May 20, 2014 at 07:25:52PM +0400, Konstantin Serebryany wrote: >> With salt == "$1$" I get this profile: >> 84.70% a.out libcrypt-2.15.so [.] __md5_process_block >> 5.98% a.out libc-2.15.so [.] __memcpy_ssse3_back >> 4.71% a.out libcrypt-2.15.so [.] __md5_process_bytes >> 1.92% a.out libcrypt-2.15.so [.] __md5_crypt_r >> 1.62% a.out libcrypt-2.15.so [.] __md5_finish_ctx >> >> Again, __md5_crypt_r is within noise. > > That's good. > >> >> >> Another thing that can be done is to look at the code generated for the >> >> relevant file before and after the patch - I'd expect very little change. >> >> I like this method much more, but there is actually a change. >> The original binary has calls to b64_from_24bit.7858 (the nested function), >> while in the binary built with my patch these calls are inlined. >> Of course, this is a feature of a particular version of GCC, not of >> the glibc code. > > Given that this does not have a very big impact, I'm inclined to > accepting this change. I'll push it in on Thursday after noon UTC if > nobody objects. I realized that two other files have the same situation with the function b64_from_24bit. md5-crypt.c, sha256-crypt.c, and sha512-crypt.c have exactly the same implementations of b64_from_24bit as a nested function. One possible fix is to move those two out and make them regular static functions, just like I did in md5-crypt.c. Another solution is to create just one implementation of b64_from_24bit and place it somewhere else. For example declare it as __b64_from_24bit in crypt-private.h and implement it in crypt_util.c. WDYT?
On Wed, May 21, 2014 at 03:35:43PM +0400, Konstantin Serebryany wrote: > I realized that two other files have the same situation with the > function b64_from_24bit. > md5-crypt.c, sha256-crypt.c, and sha512-crypt.c have exactly the same > implementations of b64_from_24bit as a nested function. > One possible fix is to move those two out and make them regular static > functions, just like I did in md5-crypt.c. > > Another solution is to create just one implementation of > b64_from_24bit and place it somewhere else. > For example declare it as __b64_from_24bit in crypt-private.h and > implement it in crypt_util.c. > > WDYT? One implementation would obviously be better. Siddhesh
On Wed, May 21, 2014 at 3:47 PM, Siddhesh Poyarekar <siddhesh@redhat.com> wrote: > On Wed, May 21, 2014 at 03:35:43PM +0400, Konstantin Serebryany wrote: >> I realized that two other files have the same situation with the >> function b64_from_24bit. >> md5-crypt.c, sha256-crypt.c, and sha512-crypt.c have exactly the same >> implementations of b64_from_24bit as a nested function. >> One possible fix is to move those two out and make them regular static >> functions, just like I did in md5-crypt.c. >> >> Another solution is to create just one implementation of >> b64_from_24bit and place it somewhere else. >> For example declare it as __b64_from_24bit in crypt-private.h and >> implement it in crypt_util.c. >> >> WDYT? > > One implementation would obviously be better. Let me prepare another patch then. Does __b64_from_24bit declared in crypt-private.h and defined in crypt_util.c sound good? > > Siddhesh
On Wed, May 21, 2014 at 03:48:32PM +0400, Konstantin Serebryany wrote: > Let me prepare another patch then. Let this patch go in as is. Move the function out with the patch to sha256-crypt.c or whatever you're changing next, assuming that this patch is in. > Does __b64_from_24bit declared in crypt-private.h and defined in > crypt_util.c sound good? Yes. Siddhesh
On Tue, May 20, 2014 at 06:23:40PM +0400, Konstantin Serebryany wrote: > 2014-05-20 Kostya Serebryany <konstantin.s.serebryany@gmail.com> > > * crypt/md5-crypt.c (__md5_crypt_r): Remove a nested function. > (b64_from_24bit): New function. > I have pushed this (and the formatting fix) now. Siddhesh
diff --git a/crypt/md5-crypt.c b/crypt/md5-crypt.c index d1b92d7..5d5fc55 100644 --- a/crypt/md5-crypt.c +++ b/crypt/md5-crypt.c @@ -88,6 +88,20 @@ extern char *__md5_crypt_r (const char *key, const char *salt, char *buffer, int buflen); extern char *__md5_crypt (const char *key, const char *salt); +static void +b64_from_24bit (char **cp, int *buflen, + unsigned int b2, unsigned int b1, unsigned int b0, + int n) +{ + unsigned int w = (b2 << 16) | (b1 << 8) | b0; + while (n-- > 0 && *buflen > 0) + { + *(*cp)++ = b64t[w & 0x3f]; + --*buflen; + w >>= 6; + } +} + /* This entry point is equivalent to the `crypt' function in Unix