mirror of
https://github.com/postgres/postgres.git
synced 2025-05-09 18:21:05 +03:00
Ensure sizeof(GenerationChunk) is maxaligned.
Per buildfarm. Also improve some comments.
This commit is contained in:
parent
3c49c6facb
commit
07bd77b95a
@ -9,7 +9,7 @@
|
|||||||
* Portions Copyright (c) 2017, PostgreSQL Global Development Group
|
* Portions Copyright (c) 2017, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* src/backend/utils/mmgr/Generation.c
|
* src/backend/utils/mmgr/generation.c
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* This memory context is based on the assumption that the chunks are freed
|
* This memory context is based on the assumption that the chunks are freed
|
||||||
@ -21,8 +21,8 @@
|
|||||||
* The memory context uses a very simple approach to free space management.
|
* The memory context uses a very simple approach to free space management.
|
||||||
* Instead of a complex global freelist, each block tracks a number
|
* Instead of a complex global freelist, each block tracks a number
|
||||||
* of allocated and freed chunks. Freed chunks are not reused, and once all
|
* of allocated and freed chunks. Freed chunks are not reused, and once all
|
||||||
* chunks on a block are freed, the whole block is thrown away. When the
|
* chunks in a block are freed, the whole block is thrown away. When the
|
||||||
* chunks allocated on the same block have similar lifespan, this works
|
* chunks allocated in the same block have similar lifespan, this works
|
||||||
* very well and is very cheap.
|
* very well and is very cheap.
|
||||||
*
|
*
|
||||||
* The current implementation only uses a fixed block size - maybe it should
|
* The current implementation only uses a fixed block size - maybe it should
|
||||||
@ -38,15 +38,15 @@
|
|||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "lib/ilist.h"
|
||||||
#include "utils/memdebug.h"
|
#include "utils/memdebug.h"
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
#include "lib/ilist.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define Generation_BLOCKHDRSZ MAXALIGN(sizeof(GenerationBlock))
|
#define Generation_BLOCKHDRSZ MAXALIGN(sizeof(GenerationBlock))
|
||||||
#define Generation_CHUNKHDRSZ sizeof(GenerationChunk)
|
#define Generation_CHUNKHDRSZ sizeof(GenerationChunk)
|
||||||
|
|
||||||
/* Portion of Generation_CHUNKHDRSZ examined outside Generation.c. */
|
/* Portion of Generation_CHUNKHDRSZ examined outside generation.c. */
|
||||||
#define Generation_CHUNK_PUBLIC \
|
#define Generation_CHUNK_PUBLIC \
|
||||||
(offsetof(GenerationChunk, size) + sizeof(Size))
|
(offsetof(GenerationChunk, size) + sizeof(Size))
|
||||||
|
|
||||||
@ -65,36 +65,35 @@ typedef struct GenerationChunk GenerationChunk;
|
|||||||
typedef void *GenerationPointer;
|
typedef void *GenerationPointer;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GenerationContext is a simple memory context not reusing allocated chunks, and
|
* GenerationContext is a simple memory context not reusing allocated chunks,
|
||||||
* freeing blocks once all chunks are freed.
|
* and freeing blocks once all chunks are freed.
|
||||||
*/
|
*/
|
||||||
typedef struct GenerationContext
|
typedef struct GenerationContext
|
||||||
{
|
{
|
||||||
MemoryContextData header; /* Standard memory-context fields */
|
MemoryContextData header; /* Standard memory-context fields */
|
||||||
|
|
||||||
/* Generationerational context parameters */
|
/* Generational context parameters */
|
||||||
Size blockSize; /* block size */
|
Size blockSize; /* block size */
|
||||||
|
|
||||||
GenerationBlock *block; /* current (most recently allocated) block */
|
GenerationBlock *block; /* current (most recently allocated) block */
|
||||||
dlist_head blocks; /* list of blocks */
|
dlist_head blocks; /* list of blocks */
|
||||||
|
|
||||||
} GenerationContext;
|
} GenerationContext;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GenerationBlock
|
* GenerationBlock
|
||||||
* A GenerationBlock is the unit of memory that is obtained by Generation.c
|
* GenerationBlock is the unit of memory that is obtained by generation.c
|
||||||
* from malloc(). It contains one or more GenerationChunks, which are
|
* from malloc(). It contains one or more GenerationChunks, which are
|
||||||
* the units requested by palloc() and freed by pfree(). GenerationChunks
|
* the units requested by palloc() and freed by pfree(). GenerationChunks
|
||||||
* cannot be returned to malloc() individually, instead pfree()
|
* cannot be returned to malloc() individually, instead pfree()
|
||||||
* updates a free counter on a block and when all chunks on a block
|
* updates the free counter of the block and when all chunks in a block
|
||||||
* are freed the whole block is returned to malloc().
|
* are free the whole block is returned to malloc().
|
||||||
*
|
*
|
||||||
* GenerationBloc is the header data for a block --- the usable space
|
* GenerationBlock is the header data for a block --- the usable space
|
||||||
* within the block begins at the next alignment boundary.
|
* within the block begins at the next alignment boundary.
|
||||||
*/
|
*/
|
||||||
struct GenerationBlock
|
struct GenerationBlock
|
||||||
{
|
{
|
||||||
dlist_node node; /* doubly-linked list */
|
dlist_node node; /* doubly-linked list of blocks */
|
||||||
int nchunks; /* number of chunks in the block */
|
int nchunks; /* number of chunks in the block */
|
||||||
int nfree; /* number of free chunks */
|
int nfree; /* number of free chunks */
|
||||||
char *freeptr; /* start of free space in this block */
|
char *freeptr; /* start of free space in this block */
|
||||||
@ -103,7 +102,7 @@ struct GenerationBlock
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* GenerationChunk
|
* GenerationChunk
|
||||||
* The prefix of each piece of memory in an GenerationBlock
|
* The prefix of each piece of memory in a GenerationBlock
|
||||||
*/
|
*/
|
||||||
struct GenerationChunk
|
struct GenerationChunk
|
||||||
{
|
{
|
||||||
@ -116,9 +115,17 @@ struct GenerationChunk
|
|||||||
/* when debugging memory usage, also store actual requested size */
|
/* when debugging memory usage, also store actual requested size */
|
||||||
/* this is zero in a free chunk */
|
/* this is zero in a free chunk */
|
||||||
Size requested_size;
|
Size requested_size;
|
||||||
#endif /* MEMORY_CONTEXT_CHECKING */
|
#define GENERATIONCHUNK_RAWSIZE (SIZEOF_VOID_P * 2 + SIZEOF_SIZE_T * 2)
|
||||||
|
#else
|
||||||
|
#define GENERATIONCHUNK_RAWSIZE (SIZEOF_VOID_P * 2 + SIZEOF_SIZE_T)
|
||||||
|
#endif /* MEMORY_CONTEXT_CHECKING */
|
||||||
|
|
||||||
GenerationContext *context; /* owning context */
|
/* ensure proper alignment by adding padding if needed */
|
||||||
|
#if (GENERATIONCHUNK_RAWSIZE % MAXIMUM_ALIGNOF) != 0
|
||||||
|
char padding[MAXIMUM_ALIGNOF - (GENERATIONCHUNK_RAWSIZE % MAXIMUM_ALIGNOF)];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GenerationContext *context; /* owning context */
|
||||||
/* there must not be any padding to reach a MAXALIGN boundary here! */
|
/* there must not be any padding to reach a MAXALIGN boundary here! */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user