Re: Add palloc_aligned() to allow arbitrary power of 2 memory alignment - Mailing list pgsql-hackers
From | Andres Freund |
---|---|
Subject | Re: Add palloc_aligned() to allow arbitrary power of 2 memory alignment |
Date | |
Msg-id | 20221107162419.jfj5sv2p44xyic3f@awork3.anarazel.de Whole thread Raw |
In response to | Add palloc_aligned() to allow arbitrary power of 2 memory alignment (David Rowley <dgrowleyml@gmail.com>) |
Responses |
Re: Add palloc_aligned() to allow arbitrary power of 2 memory alignment
|
List | pgsql-hackers |
Hi, On 2022-11-02 00:28:46 +1300, David Rowley wrote: > Part of the work that Thomas mentions in [1], regarding Direct I/O, > diff --git a/src/backend/utils/mmgr/alignedalloc.c b/src/backend/utils/mmgr/alignedalloc.c > new file mode 100644 > index 0000000000..e581772758 > --- /dev/null > +++ b/src/backend/utils/mmgr/alignedalloc.c > @@ -0,0 +1,93 @@ > +/*------------------------------------------------------------------------- > + * > + * alignedalloc.c > + * Allocator functions to implement palloc_aligned FWIW, to me this is really more part of mcxt.c than its own allocator... Particularly because MemoryContextAllocAligned() et al are implemented there. > +void * > +AlignedAllocRealloc(void *pointer, Size size) I doubtthere's ever a need to realloc such a pointer? Perhaps we could just elog(ERROR)? > +/* > + * MemoryContextAllocAligned > + * Allocate 'size' bytes of memory in 'context' aligned to 'alignto' > + * bytes. > + * > + * 'flags' may be 0 or set the same as MemoryContextAllocExtended(). > + * 'alignto' must be a power of 2. > + */ > +void * > +MemoryContextAllocAligned(MemoryContext context, > + Size size, Size alignto, int flags) > +{ > + Size alloc_size; > + void *unaligned; > + void *aligned; > + > + /* wouldn't make much sense to waste that much space */ > + Assert(alignto < (128 * 1024 * 1024)); > + > + /* ensure alignto is a power of 2 */ > + Assert((alignto & (alignto - 1)) == 0); Hm, not that I can see a case for ever not using a power of two alignment... There's not really a "need" for the restriction, right? Perhaps we should note that? > + /* > + * We implement aligned pointers by simply allocating enough memory for > + * the requested size plus the alignment and an additional MemoryChunk. > + * This additional MemoryChunk is required for operations such as pfree > + * when used on the pointer returned by this function. We use this > + * "redirection" MemoryChunk in order to find the pointer to the memory > + * that was returned by the MemoryContextAllocExtended call below. We do > + * that by "borrowing" the block offset field and instead of using that to > + * find the offset into the owning block, we use it to find the original > + * allocated address. > + * > + * Here we must allocate enough extra memory so that we can still align > + * the pointer returned by MemoryContextAllocExtended and also have enough > + * space for the redirection MemoryChunk. > + */ > + alloc_size = size + alignto + sizeof(MemoryChunk); > + > + /* perform the actual allocation */ > + unaligned = MemoryContextAllocExtended(context, alloc_size, flags); Should we handle the case where we get a suitably aligned pointer from MemoryContextAllocExtended() differently? > + /* XXX: should we adjust valgrind state here? */ Probably still need to do this... Kinda hard to get right without the code getting exercised. Wonder if there's some minimal case we could actually use it for? Thanks, Andres
pgsql-hackers by date: