* ARM memcpy post-0.9.12-release thread @ 2013-07-31 2:26 Rich Felker 2013-07-31 3:13 ` Harald Becker 2013-08-02 20:41 ` Rich Felker 0 siblings, 2 replies; 9+ messages in thread From: Rich Felker @ 2013-07-31 2:26 UTC (permalink / raw) To: musl Hi all (especially Andre), I've been doing some experimenting with ARM memcpy, and I have not found any way to beat the Bionic asm file for misaligned copies. The best I could do with simple inline asm (reading multi-words and writing byte-at-a-time or vice versa) improved the performance nearly 40% compared to musl's current code, but it was still worse than half the speed of the Bionic asm. For the aligned case, however, as I've said before, the Bionic code runs 10% slower for me than the C-with-inline-asm I posted to the list. Commenting out the prefetch code in the Bionic version brings the performance up to the same as my version. I also found that the Bionic code was mysteriously crashing on the real system I test on (it worked on my toolchain with qemu). On further investigation, the test system's toolchain had -mthumb (with thumb2) as the default; adding -marm made it work. Both ways the asm was being interpreted as arm; the problem was that the *calling* code being thumb broke it. The solution was adding .type memcpy,%function to the asm file. Without that, the linker cannot know that the symbol it's resolving is a function name and thus that it has to adjust the low bit of the relocated address as a flag for whether the code is arm or thumb. I've now got the code working reliably it seems. Sizes so far: Current C code: 260 bytes My best-attempt inline asm: 352 bytes Bionic (with prefetch removed): 764 bytes Obviously the Bionic code is a bit larger than the others and than I'd like it to be, but it looks really hard to trim it down without ruining performance for misaligned copies; roughly half of the asm covers the misaligned case, which is expensive because you have three different code paths for different ways it can be off mod 4. One other issue we have to consider if we go with the Bionic code is that we'd need to add sub-arch asm dirs to use it. As-is, the code is hard-coded for little endian. It will shuffle the byte order badly when copying on a big endian machine. Some rough times (128k copy repeated 10000 times): Aligned case: Current C code: 1.2s My best-attempt C code: 0.75s My best-attempt inline asm: 0.57s Bionic asm: 0.63s Bionic asm without prefetch: 0.57s Misaligned case: Current C code: 4.7s My best-attempt inline asm: 2.9s Bionic asm: 1.1s Rich ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: ARM memcpy post-0.9.12-release thread 2013-07-31 2:26 ARM memcpy post-0.9.12-release thread Rich Felker @ 2013-07-31 3:13 ` Harald Becker 2013-07-31 3:23 ` Rich Felker 2013-08-02 20:41 ` Rich Felker 1 sibling, 1 reply; 9+ messages in thread From: Harald Becker @ 2013-07-31 3:13 UTC (permalink / raw) Cc: musl, dalias Hi Rich ! 30-07-2013 22:26 Rich Felker <dalias@aerifal.cx>: > Some rough times (128k copy repeated 10000 times): > > Aligned case: > Current C code: 1.2s > My best-attempt C code: 0.75s > My best-attempt inline asm: 0.57s > Bionic asm: 0.63s > Bionic asm without prefetch: 0.57s > > Misaligned case: > Current C code: 4.7s > My best-attempt inline asm: 2.9s > Bionic asm: 1.1s I like to throw in a question, as my cent to this topic: Does modern C Compiler not try to align all data types? So following this path in most cases aligned data structures are used and copying them around usually hit the aligned case. The misaligned case happens mostly due to working with strings, and those are usually short. Can't we consider other misaligned cases violation of the programmer or code generator? If so, I would prefer the best-attempt inline asm versions of code or even best attempt C code over arch specific asm versions ... and add a warning for performance lose on misaligned data in documentation, with giving a rough percentage of this lose. Those who really need to work with misaligned data may follow the link and consider to add an optimized memcpy to there work. May be, musl archive or web sit may hold a contribution directory with such optimized replacement functions, (nearly) ready for inclusion in other projects, but as officially unmaintained code. -- Harald ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: ARM memcpy post-0.9.12-release thread 2013-07-31 3:13 ` Harald Becker @ 2013-07-31 3:23 ` Rich Felker 2013-07-31 4:18 ` Harald Becker 0 siblings, 1 reply; 9+ messages in thread From: Rich Felker @ 2013-07-31 3:23 UTC (permalink / raw) To: Harald Becker; +Cc: musl On Wed, Jul 31, 2013 at 05:13:47AM +0200, Harald Becker wrote: > Hi Rich ! > > 30-07-2013 22:26 Rich Felker <dalias@aerifal.cx>: > > > Some rough times (128k copy repeated 10000 times): > > > > Aligned case: > > Current C code: 1.2s > > My best-attempt C code: 0.75s > > My best-attempt inline asm: 0.57s > > Bionic asm: 0.63s > > Bionic asm without prefetch: 0.57s > > > > Misaligned case: > > Current C code: 4.7s > > My best-attempt inline asm: 2.9s > > Bionic asm: 1.1s > > I like to throw in a question, as my cent to this topic: > > Does modern C Compiler not try to align all data types? So > following this path in most cases aligned data structures are > used and copying them around usually hit the aligned case. The Yes but these are small anyway and the compiler will be generating inline code to copy them with ldmia/stmia. > misaligned case happens mostly due to working with strings, and > those are usually short. Can't we consider other misaligned cases > violation of the programmer or code generator? If so, I would > prefer the best-attempt inline asm versions of code or even > best attempt C code over arch specific asm versions ... and add Part of the problem discussed on #musl was that I was having to be really careful with "best attempt C" since GCC will _generate_ calls to memcpy for some code, even when -ffreestanding is used. The folks on #gcc claim this is not a bug. So, if compilers deem themselves at liberty to make this kind of transformation, any C implementation of memcpy that's not intentionally crippled (e.g. using volatile temps and 20x slower than it should be) is a time-bomb that might blow up on us with the next GCC version... This makes asm (either inline or standalone) a lot more appealing for memcpy than it otherwise would be. > a warning for performance lose on misaligned data in > documentation, with giving a rough percentage of this lose. You'd prefer video processing being 4 to 5 times slower? Video typically consists of single-byte samples (planar YUV) and operations like cropping to a non-multiple-of-4 size, motion compensation, etc. all involve misaligned memcpy. Same goes for image transformations in gimp, image blitting in web browsers (not necessarily aligned to multiple-of-4 boundaries unless you're using 32bpp), etc... Rich ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: ARM memcpy post-0.9.12-release thread 2013-07-31 3:23 ` Rich Felker @ 2013-07-31 4:18 ` Harald Becker 2013-07-31 6:13 ` Rich Felker 0 siblings, 1 reply; 9+ messages in thread From: Harald Becker @ 2013-07-31 4:18 UTC (permalink / raw) To: Rich Felker; +Cc: musl Hi Rich ! 30-07-2013 23:23 Rich Felker <dalias@aerifal.cx>: > > misaligned case happens mostly due to working with strings, > > and those are usually short. Can't we consider other > > misaligned cases violation of the programmer or code > > generator? If so, I would prefer the best-attempt inline asm > > versions of code or even best attempt C code over arch > > specific asm versions ... and add > > Part of the problem discussed on #musl was that I was having to > be really careful with "best attempt C" since GCC will > _generate_ calls to memcpy for some code, even when > -ffreestanding is used. The folks on #gcc claim this is not a > bug. So, if compilers deem themselves at liberty to make this > kind of transformation, any C implementation of memcpy that's > not intentionally crippled (e.g. using volatile temps and 20x > slower than it should be) is a time-bomb that might blow up on > us with the next GCC version... I never deal with the details of this type of gcc code generation, but doesn't this only happen on small and structure copies? Structure copies which shall usually be aligned? So if they are aligned the simpler version saves code space. > This makes asm (either inline or standalone) a lot more > appealing for memcpy than it otherwise would be. Optimization is always a question of decision, which I consider the hard part of the job ... :( > > a warning for performance lose on misaligned data in > > documentation, with giving a rough percentage of this lose. > > You'd prefer video processing being 4 to 5 times slower? No, definitely not, but video processing is one of the cases I consider candidate for optimized processing. So such projects shall include an optimize version of of low level processing functions (including memcpy, but not only - candidate for library with optimized functions?). > Video typically consists of single-byte samples (planar YUV) and > operations like cropping to a non-multiple-of-4 size, motion > compensation, etc. all involve misaligned memcpy. Same goes for > image transformations in gimp, image blitting in web browsers > (not necessarily aligned to multiple-of-4 boundaries unless > you're using 32bpp), etc... You are all right, but the programmer shall know of this and consider to use appropriate functions. You can write the code for those parts which need the speed in a way, which call optimized functions. A way which usually does not conflict with gcc self inserted calls. So this self inserted calls usually hit the aligned scope, or the programmer did not behave well (not the compiler). -- Harald ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: ARM memcpy post-0.9.12-release thread 2013-07-31 4:18 ` Harald Becker @ 2013-07-31 6:13 ` Rich Felker 0 siblings, 0 replies; 9+ messages in thread From: Rich Felker @ 2013-07-31 6:13 UTC (permalink / raw) To: musl On Wed, Jul 31, 2013 at 06:18:58AM +0200, Harald Becker wrote: > Hi Rich ! > > 30-07-2013 23:23 Rich Felker <dalias@aerifal.cx>: > > > > misaligned case happens mostly due to working with strings, > > > and those are usually short. Can't we consider other > > > misaligned cases violation of the programmer or code > > > generator? If so, I would prefer the best-attempt inline asm > > > versions of code or even best attempt C code over arch > > > specific asm versions ... and add > > > > Part of the problem discussed on #musl was that I was having to > > be really careful with "best attempt C" since GCC will > > _generate_ calls to memcpy for some code, even when > > -ffreestanding is used. The folks on #gcc claim this is not a > > bug. So, if compilers deem themselves at liberty to make this > > kind of transformation, any C implementation of memcpy that's > > not intentionally crippled (e.g. using volatile temps and 20x > > slower than it should be) is a time-bomb that might blow up on > > us with the next GCC version... > > I never deal with the details of this type of gcc code > generation, but doesn't this only happen on small and structure > copies? Structure copies which shall usually be aligned? So if > they are aligned the simpler version saves code space. I'm sorry, I don't think I was clear. The issue is that GCC recognizes certain patterns and generates calls to memcpy rather than doing the work inline. If it does this in memcpy.c, you end up with a version of memcpy that invokes infinite recursion and is thereby unusable. The issue I hit was that GCC was generating memcpy calls for copying struct { char block[32]; }, which has no alignment requirement. This technique was probably the best bet at getting the compiler to generate an efficient memcpy (in fact, it works quite well on some other archs), but on ARM it blew away the stack. When looking for a solution, however, I came across this: http://gcc.gnu.org/bugzilla//show_bug.cgi?id=56888 It looks to me like the situation is that, as compilers get smarter and smarter, it's going to become increasingly difficult to ensure that memcpy doesn't get compiled to a call to memcpy. So, my long term plan (this is still open to discussion) is to do something like this: Have one or more C memcpy implementations on-hand that empirically generate good code. For important archs, have hand-optimized asm; this is both smaller and better-performing than anything decent we can achieve with C. For archs where we don't yet have arm, generate asm from whichever C implementation works best. Then, instead of having the performance-oriented C in the source tree, have a fail-safe C version that the compiler can't possibly mess up; this ensures that future ports can get started without having to worry about whether the compiler breaks memcpy. > > This makes asm (either inline or standalone) a lot more > > appealing for memcpy than it otherwise would be. > > Optimization is always a question of decision, which I consider > the hard part of the job ... :( > > > > a warning for performance lose on misaligned data in > > > documentation, with giving a rough percentage of this lose. > > > > You'd prefer video processing being 4 to 5 times slower? > > No, definitely not, but video processing is one of the cases I > consider candidate for optimized processing. So such projects > shall include an optimize version of of low level processing > functions (including memcpy, but not only - candidate for > library with optimized functions?). Are you aware that redefining functions with the standardf names invokes undefined behavior? Yes you could write your own memcpy by another name, but then it can't get used by things like stdio (where, if it's slow, it's likely a large portion of time spent on file io), TLS image copying (per-thread startup cost), etc. Of all the functions in libc, memcpy is definitely the most performance-critical to the most applications. The other things that matter are malloc/free, math (sometimes), stdio, qsort, and searching/matching functions like regex, strstr, etc. > > Video typically consists of single-byte samples (planar YUV) and > > operations like cropping to a non-multiple-of-4 size, motion > > compensation, etc. all involve misaligned memcpy. Same goes for > > image transformations in gimp, image blitting in web browsers > > (not necessarily aligned to multiple-of-4 boundaries unless > > you're using 32bpp), etc... > > You are all right, but the programmer shall know of this and > consider to use appropriate functions. You can write the code for The programmer should write asm for 20 different archs? Most people have better things to do with their time.. Back to the point, musl is not dietlibc. If you want the smallest, lowest-quality imaginable libc, there's dietlibc you can use. musl's aim is to be a robust general-purpose libc. "Switch from Bionic to musl and make your apps run five times slower" is not appealing to anybody. If the choice were between having fully general, clean C code that runs 5-10% slower or giant gobs of asm with a heavy maintenance burden that runs 5-10% faster, I would probably agree and just figure the people who really need that last 5-10% can drop in some fancy asm. But that's not the situation we're in. The current code is half the speed of a decent (still probably not even the fastest) implementation for aligned copies and nearly five times slower for misaligned copies. That's well outside the range of "special interest" and into the range of "our implementation sucks". Moreover, the choice here is not between clean C and dirty asm. It's between dirty C and, well, whatever you think of the asm. The only "clean" C memcpy is: while (n--) *d++ = *s++; Our C memcpy depends on implementation-defined behavior (casting pointers to integers to inspect their alignment) as well as undefined behavior (aliasing violations to copy as size_t units). The latter cannot be detected by a compiler that's not performing LTO/whole program optimization, so it's "safe" for the most part, but it's still wrong. So from a standpoint of clean code, getting decent asm on all the archs and then possibly replacing the C with something more naive would probably be a step forward. Rich ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: ARM memcpy post-0.9.12-release thread 2013-07-31 2:26 ARM memcpy post-0.9.12-release thread Rich Felker 2013-07-31 3:13 ` Harald Becker @ 2013-08-02 20:41 ` Rich Felker 2013-08-02 22:03 ` Andre Renaud 1 sibling, 1 reply; 9+ messages in thread From: Rich Felker @ 2013-08-02 20:41 UTC (permalink / raw) To: musl; +Cc: Andre Renaud Andre, do you have any input on this? (Cc'ing) Rich On Tue, Jul 30, 2013 at 10:26:31PM -0400, Rich Felker wrote: > Hi all (especially Andre), > > I've been doing some experimenting with ARM memcpy, and I have not > found any way to beat the Bionic asm file for misaligned copies. The > best I could do with simple inline asm (reading multi-words and > writing byte-at-a-time or vice versa) improved the performance nearly > 40% compared to musl's current code, but it was still worse than half > the speed of the Bionic asm. > > For the aligned case, however, as I've said before, the Bionic code > runs 10% slower for me than the C-with-inline-asm I posted to the > list. Commenting out the prefetch code in the Bionic version brings > the performance up to the same as my version. > > I also found that the Bionic code was mysteriously crashing on the > real system I test on (it worked on my toolchain with qemu). On > further investigation, the test system's toolchain had -mthumb (with > thumb2) as the default; adding -marm made it work. Both ways the asm > was being interpreted as arm; the problem was that the *calling* code > being thumb broke it. The solution was adding .type memcpy,%function > to the asm file. Without that, the linker cannot know that the symbol > it's resolving is a function name and thus that it has to adjust the > low bit of the relocated address as a flag for whether the code is arm > or thumb. I've now got the code working reliably it seems. > > Sizes so far: > Current C code: 260 bytes > My best-attempt inline asm: 352 bytes > Bionic (with prefetch removed): 764 bytes > > Obviously the Bionic code is a bit larger than the others and than I'd > like it to be, but it looks really hard to trim it down without > ruining performance for misaligned copies; roughly half of the asm > covers the misaligned case, which is expensive because you have three > different code paths for different ways it can be off mod 4. > > One other issue we have to consider if we go with the Bionic code is > that we'd need to add sub-arch asm dirs to use it. As-is, the code is > hard-coded for little endian. It will shuffle the byte order badly > when copying on a big endian machine. > > Some rough times (128k copy repeated 10000 times): > > Aligned case: > Current C code: 1.2s > My best-attempt C code: 0.75s > My best-attempt inline asm: 0.57s > Bionic asm: 0.63s > Bionic asm without prefetch: 0.57s > > Misaligned case: > Current C code: 4.7s > My best-attempt inline asm: 2.9s > Bionic asm: 1.1s > > Rich ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: ARM memcpy post-0.9.12-release thread 2013-08-02 20:41 ` Rich Felker @ 2013-08-02 22:03 ` Andre Renaud 2013-08-03 0:01 ` Rich Felker 2013-08-05 21:24 ` Rich Felker 0 siblings, 2 replies; 9+ messages in thread From: Andre Renaud @ 2013-08-02 22:03 UTC (permalink / raw) To: musl; +Cc: Andre Renaud Hi Rich, On 3 August 2013 08:41, Rich Felker <dalias@aerifal.cx> wrote: > Andre, do you have any input on this? (Cc'ing) > > Rich Sorry, I've been reading the emails, but haven't had a chance to get back to the code. I don't really have an opinion on the gcc memcpy issue, however I was still hopeful that we could come up with a relatively clean mixed C/asm solution for the misaligned/non-congruent copy scenario. Having said that, I haven't done anything on it yet. To be honest, although a solution probably exists, I doubt it's ever going to be much better than the bionic code (with the exception of possibly being less to read). Regards, Andre ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: ARM memcpy post-0.9.12-release thread 2013-08-02 22:03 ` Andre Renaud @ 2013-08-03 0:01 ` Rich Felker 2013-08-05 21:24 ` Rich Felker 1 sibling, 0 replies; 9+ messages in thread From: Rich Felker @ 2013-08-03 0:01 UTC (permalink / raw) To: musl; +Cc: Andre Renaud On Sat, Aug 03, 2013 at 10:03:14AM +1200, Andre Renaud wrote: > Hi Rich, > > On 3 August 2013 08:41, Rich Felker <dalias@aerifal.cx> wrote: > > Andre, do you have any input on this? (Cc'ing) > > > > Rich > > Sorry, I've been reading the emails, but haven't had a chance to get > back to the code. I don't really have an opinion on the gcc memcpy > issue, however I was still hopeful that we could come up with a > relatively clean mixed C/asm solution for the misaligned/non-congruent > copy scenario. Having said that, I haven't done anything on it yet. > > To be honest, although a solution probably exists, I doubt it's ever > going to be much better than the bionic code (with the exception of > possibly being less to read). I'm not sure about the "less to read" either. I would very much _like_ some generic C code for this, since the same basic strategy is applicable to all RISC-y archs with lots of registers but no misaligned memory access: 1. Read several aligned words. 2. Bitshift them with carry to adjust for the relative misalignment of the destination. 3. Write several aligned words. Unfortunately what this amounts to is N-1, where N is the alignment (4 for ARM, 8 for 64-bit-register archs), versions of the misaligned copy code, one for each value of (dest-src)%N. Oh, and you need separate cases for little and big endian too, since the bitshifts work with values rather than just representations. My guess is that at best we'll only get about 80% of the performance of the bionic asm, but I could be pleasantly surprised. What makes it nice is that this could get us acceptable memcpy performance on mips, powerpc, microblaze, etc. without having to write assembly for them all. I'll probably add the bionic asm for now, but I can't do it without first adding a way to disable it for "armeb". Rich ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: ARM memcpy post-0.9.12-release thread 2013-08-02 22:03 ` Andre Renaud 2013-08-03 0:01 ` Rich Felker @ 2013-08-05 21:24 ` Rich Felker 1 sibling, 0 replies; 9+ messages in thread From: Rich Felker @ 2013-08-05 21:24 UTC (permalink / raw) To: musl [-- Attachment #1: Type: text/plain, Size: 1389 bytes --] On Sat, Aug 03, 2013 at 10:03:14AM +1200, Andre Renaud wrote: > Hi Rich, > > On 3 August 2013 08:41, Rich Felker <dalias@aerifal.cx> wrote: > > Andre, do you have any input on this? (Cc'ing) > > > > Rich > > Sorry, I've been reading the emails, but haven't had a chance to get > back to the code. I don't really have an opinion on the gcc memcpy > issue, however I was still hopeful that we could come up with a > relatively clean mixed C/asm solution for the misaligned/non-congruent > copy scenario. Having said that, I haven't done anything on it yet. > > To be honest, although a solution probably exists, I doubt it's ever > going to be much better than the bionic code (with the exception of > possibly being less to read). Attached is a "C version of the concept in the Bionic asm". Without spending any effort getting the compiler to optimize it better, it's only taking about 80% longer than the asm to run on misaligned input. I would say something like this is _potentially_ a candidate for replacing memcpy.c in musl, since it should do well on most RISC architectures (and does decently even on x86). Of course this is no replacement for the asm, as it's much slower, but it would allow us to get by longer without adding asm for new archs. The aligned case should probably be changed to use structure copies if we can be sure they won't generate calls to memcpy. Rich [-- Attachment #2: memcpy_risc.c --] [-- Type: text/plain, Size: 1901 bytes --] #include <string.h> #include <stdlib.h> #include <stdint.h> void *memcpy(void *restrict dest, const void *restrict src, size_t n) { unsigned char *d = dest; const unsigned char *s = src; uint32_t w, x; for (; (uintptr_t)s % 8 && n; n--) *d++ = *s++; if (!n) return dest; if (n>=4) switch ((uintptr_t)d % 4) { case 0: if (!(uintptr_t)d % 8) for (; n>=8; s+=8, d+=8, n-=8) *(uint64_t *)d = *(uint64_t *)s; else for (; n>=4; s+=4, d+=4, n-=4) *(uint32_t *)d = *(uint32_t *)s; break; case 1: if (!(union { int i; char c; }){1}.c) break; w = *(uint32_t *)s; *d++ = *s++; *d++ = *s++; *d++ = *s++; n -= 3; for (; n>=17; s+=16, d+=16, n-=16) { x = *(uint32_t *)(s+1); *(uint32_t *)(d+0) = (w>>24) | (x<<8); w = *(uint32_t *)(s+5); *(uint32_t *)(d+4) = (x>>24) | (w<<8); x = *(uint32_t *)(s+9); *(uint32_t *)(d+8) = (w>>24) | (x<<8); w = *(uint32_t *)(s+13); *(uint32_t *)(d+12) = (x>>24) | (w<<8); } break; case 2: if (!(union { int i; char c; }){1}.c) break; w = *(uint32_t *)s; *d++ = *s++; *d++ = *s++; n -= 2; for (; n>=18; s+=16, d+=16, n-=16) { x = *(uint32_t *)(s+2); *(uint32_t *)(d+0) = (w>>16) | (x<<16); w = *(uint32_t *)(s+6); *(uint32_t *)(d+4) = (x>>16) | (w<<16); x = *(uint32_t *)(s+10); *(uint32_t *)(d+8) = (w>>16) | (x<<16); w = *(uint32_t *)(s+14); *(uint32_t *)(d+12) = (x>>16) | (w<<16); } break; case 3: if (!(union { int i; char c; }){1}.c) break; w = *(uint32_t *)s; *d++ = *s++; n -= 1; for (; n>=19; s+=16, d+=16, n-=16) { x = *(uint32_t *)(s+3); *(uint32_t *)(d+0) = (w>>8) | (x<<24); w = *(uint32_t *)(s+7); *(uint32_t *)(d+4) = (x>>8) | (w<<24); x = *(uint32_t *)(s+11); *(uint32_t *)(d+8) = (w>>8) | (x<<24); w = *(uint32_t *)(s+15); *(uint32_t *)(d+12) = (x>>8) | (w<<24); } break; } for (; n; n--) *d++ = *s++; return dest; } ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2013-08-05 21:24 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2013-07-31 2:26 ARM memcpy post-0.9.12-release thread Rich Felker 2013-07-31 3:13 ` Harald Becker 2013-07-31 3:23 ` Rich Felker 2013-07-31 4:18 ` Harald Becker 2013-07-31 6:13 ` Rich Felker 2013-08-02 20:41 ` Rich Felker 2013-08-02 22:03 ` Andre Renaud 2013-08-03 0:01 ` Rich Felker 2013-08-05 21:24 ` Rich Felker
Code repositories for project(s) associated with this public inbox https://git.vuxu.org/mirror/musl/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).