Push dedicated BumpBlocks to the tail of the blocks list
authorDavid Rowley
Tue, 16 Apr 2024 22:40:31 +0000 (10:40 +1200)
committerDavid Rowley
Tue, 16 Apr 2024 22:40:31 +0000 (10:40 +1200)
BumpContext relies on using the head block from its 'blocks' field to
use as the current block to allocate new chunks to.  When we receive an
allocation request larger than allocChunkLimit, we place these chunks on
a new dedicated block and, until now, we pushed the block onto the
*head* of the 'blocks' list.

This behavior caused the previous bump block to no longer be available
for new normal-sized (non-large) allocations and would result in blocks
only being partially filled if a large allocation request arrived before
the block became full.

Here adjust the code to push these dedicated blocks onto the *tail* of
the blocks list so that the head block remains intact and available to
be used by normal allocation request sizes until it becomes full.

In passing, make the elog(ERROR) calls for the unsupported callbacks
consistent.  Likewise for the header comments for those functions.

Discussion: https://postgr.es/m/CAApHDvp9___r-ayJj0nZ6GD3MeCGwGZ0_6ZptWpwj+zqHtmwCw@mail.gmail.com
Discussion: https://postgr.es/m/CAApHDvqerXpzUnuDQfUEi3DZA+9=Ud9WSt3ruxN5b6PcOosx2g@mail.gmail.com

src/backend/utils/mmgr/bump.c
src/test/regress/expected/sysviews.out

index 449bd293448c54fe109a5ab1df2627c4b764c751..a98bafbcc03c968efcda5d873270c850cd4b368c 100644 (file)
@@ -342,8 +342,12 @@ BumpAllocLarge(MemoryContext context, Size size, int flags)
    randomize_mem((char *) MemoryChunkGetPointer(chunk), size);
 #endif
 
-   /* add the block to the list of allocated blocks */
-   dlist_push_head(&set->blocks, &block->node);
+   /*
+    * Add the block to the tail of allocated blocks list.  The current block
+    * is left at the head of the list as it may still have space for
+    * non-large allocations.
+    */
+   dlist_push_tail(&set->blocks, &block->node);
 
 #ifdef MEMORY_CONTEXT_CHECKING
    /* Ensure any padding bytes are marked NOACCESS. */
@@ -612,7 +616,7 @@ BumpBlockFree(BumpContext *set, BumpBlock *block)
 void
 BumpFree(void *pointer)
 {
-   elog(ERROR, "pfree is not supported by the bump memory allocator");
+   elog(ERROR, "%s is not supported by the bump memory allocator", "pfree");
 }
 
 /*
@@ -638,10 +642,9 @@ BumpGetChunkContext(void *pointer)
 }
 
 /*
-* BumpGetChunkSpace
-*      Given a currently-allocated chunk, determine the total space
-*      it occupies (including all memory-allocation overhead).
-*/
+ * BumpGetChunkSpace
+ *     Unsupported.
+ */
 Size
 BumpGetChunkSpace(void *pointer)
 {
index 634dc8d8b8cfd7ec2b01a0d0c0c2b7f266ce4ffe..2f3eb4e7f156e57934c253dcedb88eb2e4ce0112 100644 (file)
@@ -47,7 +47,7 @@ select name, parent, total_bytes > 0, total_nblocks, free_bytes > 0, free_chunks
 from pg_backend_memory_contexts where name = 'Caller tuples';
      name      |     parent     | ?column? | total_nblocks | ?column? | free_chunks 
 ---------------+----------------+----------+---------------+----------+-------------
- Caller tuples | TupleSort sort | t        |             3 | t        |           0
+ Caller tuples | TupleSort sort | t        |             2 | t        |           0
 (1 row)
 
 rollback;