On 11/25/2011 04:24 PM, Bruno Haible wrote: > Eric Blake wrote: >>>> If gnulib would give >>>> us posix_memalign on mingw, we could nuke this #if altogether. >>> >>> That's pretty difficult (unless you also add a posix_memalign_free) >>> because at the time posix_memalign returns you have lost the base >>> pointer for free(). >> >> Providing a posix_memalign_free defeats the purpose - POSIX requires >> that plain free() will cover the memory returned by posix_memalign. The >> list of platforms missing posix_memalign is a bit daunting: >> >> MacOS X 10.5, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, >> HP-UX 11, >> IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 1.5.x, mingw, MSVC 9, Interix 3.5, >> BeOS. >> >> but what would be interesting to know is how many of those platforms >> return page-aligned pointers for any malloc() request of a page or more >> of memory. > > Tested with the attached program:
Thanks for that research. > > However, over-allocating wastes memory. We have a 'pagealign_alloc' module > that does not waste memory. Alas, pagealign_alloc is currently GPLv3+, although if libvirt were to use it in place of posix_memalign, it would have to be LGPLv2+. It looks like Jim, Paul, and Bruno are the only contributors so far. I'm not yet sure whether to request a license relaxation. >> Another alternative is to override free() at the same time as providing >> posix_memalign(). > > I wouldn't like to slow down free(), which is used in many places, for the > sake of posix_memalign() (as opposed to pagealign_alloc()) which is rarely > used. It would only be slowed down on systems where we cannot otherwise get aligned allocations. Per your research: Minix 3.1.8 not page-aligned at all AIX 5.1 not page-aligned at all HP-UX 11 not page-aligned at all IRIX 6.5 not page-aligned at all OSF/1 5.1 not page-aligned at all Solaris 10 not page-aligned at all Cygwin 1.5.x not page-aligned at all mingw not page-aligned at all MSVC 9 not page-aligned at all Of those, I don't know if Solaris 11 has improved, and cygwin 1.7 provides posix_memalign. But several of the remaining are still in heavy use, and the fact that mingw lacks any way to coerce an aligned malloc() without overriding free() does seem pretty troublesome to any approach that penalizes the common case. How important is it that our special-case allocation/free in pagealign_alloc() remain GPL? I agree that using it just for the rare needs of aligned memory makes more sense. Or maybe we introduce an LGPLv2+ posix_memalign that wastefully overallocates and slows down free(), and leave pagealign_alloc() as GPLv3+, as a way to encourage licensing improvements for people that care about efficiency on deficient platforms. Thinking aloud here, another possibility might be to use mmap() to provide posix_memalign() at page boundaries, as well as reserving the previous page as an unmapped guard page. Most implementations of malloc() have a free() that assumes a header was present immediately before the pointer returned by malloc(), and would thus fault in free() while trying to access the header just before a pointer returned by posix_memalign. If we then have a SIGSEGV handler in place that recognizes the guard pages that we installed for every use of posix_memalign, and such a handler can also rewrite the call stack so that on return, the faulting free() is safely bypassed, then we could avoid penalizing the common case free() while still making the overall program behave as if free works on posix_memalign pointers. But this thought experiment is probably not worth actually trying, since libsigsegv is GPL rather than LGPL, and since portably rewriting call stacks to bypass a faulting free() is probably out of the question. -- Eric Blake ebl...@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature