9
9
* Portions Copyright (c) 2017, PostgreSQL Global Development Group
10
10
*
11
11
* IDENTIFICATION
12
- * src/backend/utils/mmgr/Generation .c
12
+ * src/backend/utils/mmgr/generation .c
13
13
*
14
14
*
15
15
* This memory context is based on the assumption that the chunks are freed
21
21
* The memory context uses a very simple approach to free space management.
22
22
* Instead of a complex global freelist, each block tracks a number
23
23
* 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
26
26
* very well and is very cheap.
27
27
*
28
28
* The current implementation only uses a fixed block size - maybe it should
38
38
39
39
#include "postgres.h"
40
40
41
+ #include "lib/ilist.h"
41
42
#include "utils/memdebug.h"
42
43
#include "utils/memutils.h"
43
- #include "lib/ilist.h"
44
44
45
45
46
46
#define Generation_BLOCKHDRSZ MAXALIGN(sizeof(GenerationBlock))
47
47
#define Generation_CHUNKHDRSZ sizeof(GenerationChunk)
48
48
49
- /* Portion of Generation_CHUNKHDRSZ examined outside Generation .c. */
49
+ /* Portion of Generation_CHUNKHDRSZ examined outside generation .c. */
50
50
#define Generation_CHUNK_PUBLIC \
51
51
(offsetof(GenerationChunk, size) + sizeof(Size))
52
52
@@ -65,36 +65,35 @@ typedef struct GenerationChunk GenerationChunk;
65
65
typedef void * GenerationPointer ;
66
66
67
67
/*
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.
70
70
*/
71
71
typedef struct GenerationContext
72
72
{
73
73
MemoryContextData header ; /* Standard memory-context fields */
74
74
75
- /* Generationerational context parameters */
75
+ /* Generational context parameters */
76
76
Size blockSize ; /* block size */
77
77
78
78
GenerationBlock * block ; /* current (most recently allocated) block */
79
79
dlist_head blocks ; /* list of blocks */
80
-
81
80
} GenerationContext ;
82
81
83
82
/*
84
83
* 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
86
85
* from malloc(). It contains one or more GenerationChunks, which are
87
86
* the units requested by palloc() and freed by pfree(). GenerationChunks
88
87
* 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().
91
90
*
92
- * GenerationBloc is the header data for a block --- the usable space
91
+ * GenerationBlock is the header data for a block --- the usable space
93
92
* within the block begins at the next alignment boundary.
94
93
*/
95
94
struct GenerationBlock
96
95
{
97
- dlist_node node ; /* doubly-linked list */
96
+ dlist_node node ; /* doubly-linked list of blocks */
98
97
int nchunks ; /* number of chunks in the block */
99
98
int nfree ; /* number of free chunks */
100
99
char * freeptr ; /* start of free space in this block */
@@ -103,7 +102,7 @@ struct GenerationBlock
103
102
104
103
/*
105
104
* GenerationChunk
106
- * The prefix of each piece of memory in an GenerationBlock
105
+ * The prefix of each piece of memory in a GenerationBlock
107
106
*/
108
107
struct GenerationChunk
109
108
{
@@ -116,9 +115,17 @@ struct GenerationChunk
116
115
/* when debugging memory usage, also store actual requested size */
117
116
/* this is zero in a free chunk */
118
117
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
120
127
121
- GenerationContext * context ; /* owning context */
128
+ GenerationContext * context ; /* owning context */
122
129
/* there must not be any padding to reach a MAXALIGN boundary here! */
123
130
};
124
131
0 commit comments