Skip to content

Commit 07bd77b

Browse files
committed
Ensure sizeof(GenerationChunk) is maxaligned.
Per buildfarm. Also improve some comments.
1 parent 3c49c6f commit 07bd77b

File tree

1 file changed

+24
-17
lines changed

1 file changed

+24
-17
lines changed

src/backend/utils/mmgr/generation.c

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* Portions Copyright (c) 2017, PostgreSQL Global Development Group
1010
*
1111
* IDENTIFICATION
12-
* src/backend/utils/mmgr/Generation.c
12+
* src/backend/utils/mmgr/generation.c
1313
*
1414
*
1515
* This memory context is based on the assumption that the chunks are freed
@@ -21,8 +21,8 @@
2121
* The memory context uses a very simple approach to free space management.
2222
* Instead of a complex global freelist, each block tracks a number
2323
* of allocated and freed chunks. Freed chunks are not reused, and once all
24-
* chunks on a block are freed, the whole block is thrown away. When the
25-
* chunks allocated on the same block have similar lifespan, this works
24+
* chunks in a block are freed, the whole block is thrown away. When the
25+
* chunks allocated in the same block have similar lifespan, this works
2626
* very well and is very cheap.
2727
*
2828
* The current implementation only uses a fixed block size - maybe it should
@@ -38,15 +38,15 @@
3838

3939
#include "postgres.h"
4040

41+
#include "lib/ilist.h"
4142
#include "utils/memdebug.h"
4243
#include "utils/memutils.h"
43-
#include "lib/ilist.h"
4444

4545

4646
#define Generation_BLOCKHDRSZ MAXALIGN(sizeof(GenerationBlock))
4747
#define Generation_CHUNKHDRSZ sizeof(GenerationChunk)
4848

49-
/* Portion of Generation_CHUNKHDRSZ examined outside Generation.c. */
49+
/* Portion of Generation_CHUNKHDRSZ examined outside generation.c. */
5050
#define Generation_CHUNK_PUBLIC \
5151
(offsetof(GenerationChunk, size) + sizeof(Size))
5252

@@ -65,36 +65,35 @@ typedef struct GenerationChunk GenerationChunk;
6565
typedef void *GenerationPointer;
6666

6767
/*
68-
* GenerationContext is a simple memory context not reusing allocated chunks, and
69-
* freeing blocks once all chunks are freed.
68+
* GenerationContext is a simple memory context not reusing allocated chunks,
69+
* and freeing blocks once all chunks are freed.
7070
*/
7171
typedef struct GenerationContext
7272
{
7373
MemoryContextData header; /* Standard memory-context fields */
7474

75-
/* Generationerational context parameters */
75+
/* Generational context parameters */
7676
Size blockSize; /* block size */
7777

7878
GenerationBlock *block; /* current (most recently allocated) block */
7979
dlist_head blocks; /* list of blocks */
80-
8180
} GenerationContext;
8281

8382
/*
8483
* GenerationBlock
85-
* A GenerationBlock is the unit of memory that is obtained by Generation.c
84+
* GenerationBlock is the unit of memory that is obtained by generation.c
8685
* from malloc(). It contains one or more GenerationChunks, which are
8786
* the units requested by palloc() and freed by pfree(). GenerationChunks
8887
* cannot be returned to malloc() individually, instead pfree()
89-
* updates a free counter on a block and when all chunks on a block
90-
* are freed the whole block is returned to malloc().
88+
* updates the free counter of the block and when all chunks in a block
89+
* are free the whole block is returned to malloc().
9190
*
92-
* GenerationBloc is the header data for a block --- the usable space
91+
* GenerationBlock is the header data for a block --- the usable space
9392
* within the block begins at the next alignment boundary.
9493
*/
9594
struct GenerationBlock
9695
{
97-
dlist_node node; /* doubly-linked list */
96+
dlist_node node; /* doubly-linked list of blocks */
9897
int nchunks; /* number of chunks in the block */
9998
int nfree; /* number of free chunks */
10099
char *freeptr; /* start of free space in this block */
@@ -103,7 +102,7 @@ struct GenerationBlock
103102

104103
/*
105104
* GenerationChunk
106-
* The prefix of each piece of memory in an GenerationBlock
105+
* The prefix of each piece of memory in a GenerationBlock
107106
*/
108107
struct GenerationChunk
109108
{
@@ -116,9 +115,17 @@ struct GenerationChunk
116115
/* when debugging memory usage, also store actual requested size */
117116
/* this is zero in a free chunk */
118117
Size requested_size;
119-
#endif /* MEMORY_CONTEXT_CHECKING */
118+
#define GENERATIONCHUNK_RAWSIZE (SIZEOF_VOID_P * 2 + SIZEOF_SIZE_T * 2)
119+
#else
120+
#define GENERATIONCHUNK_RAWSIZE (SIZEOF_VOID_P * 2 + SIZEOF_SIZE_T)
121+
#endif /* MEMORY_CONTEXT_CHECKING */
122+
123+
/* ensure proper alignment by adding padding if needed */
124+
#if (GENERATIONCHUNK_RAWSIZE % MAXIMUM_ALIGNOF) != 0
125+
char padding[MAXIMUM_ALIGNOF - (GENERATIONCHUNK_RAWSIZE % MAXIMUM_ALIGNOF)];
126+
#endif
120127

121-
GenerationContext *context; /* owning context */
128+
GenerationContext *context; /* owning context */
122129
/* there must not be any padding to reach a MAXALIGN boundary here! */
123130
};
124131

0 commit comments

Comments
 (0)