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


Reply via email to