PostgreSQL Source Code git master
alignedalloc.c File Reference
#include "postgres.h"
#include "utils/memdebug.h"
#include "utils/memutils_memorychunk.h"
Include dependency graph for alignedalloc.c:

Go to the source code of this file.

Functions

void AlignedAllocFree (void *pointer)
 
void * AlignedAllocRealloc (void *pointer, Size size, int flags)
 
MemoryContext AlignedAllocGetChunkContext (void *pointer)
 
Size AlignedAllocGetChunkSpace (void *pointer)
 

Function Documentation

◆ AlignedAllocFree()

void AlignedAllocFree ( void *  pointer)

Definition at line 29 of file alignedalloc.c.

30{
31 MemoryChunk *chunk = PointerGetMemoryChunk(pointer);
32 void *unaligned;
33
35
37
38 /* obtain the original (unaligned) allocated pointer */
39 unaligned = MemoryChunkGetBlock(chunk);
40
41#ifdef MEMORY_CONTEXT_CHECKING
42 /* Test for someone scribbling on unused space in chunk */
43 if (!sentinel_ok(pointer, chunk->requested_size))
44 elog(WARNING, "detected write past chunk end in %s %p",
45 GetMemoryChunkContext(unaligned)->name, chunk);
46#endif
47
48 /* Recursively pfree the unaligned chunk */
49 pfree(unaligned);
50}
#define WARNING
Definition: elog.h:36
#define elog(elevel,...)
Definition: elog.h:225
Assert(PointerIsAligned(start, uint64))
void pfree(void *pointer)
Definition: mcxt.c:1528
MemoryContext GetMemoryChunkContext(void *pointer)
Definition: mcxt.c:707
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
Definition: memdebug.h:26
static bool MemoryChunkIsExternal(MemoryChunk *chunk)
static void * MemoryChunkGetBlock(MemoryChunk *chunk)
#define PointerGetMemoryChunk(p)
const char * name

References Assert(), elog, GetMemoryChunkContext(), MemoryChunkGetBlock(), MemoryChunkIsExternal(), name, pfree(), PointerGetMemoryChunk, VALGRIND_MAKE_MEM_DEFINED, and WARNING.

◆ AlignedAllocGetChunkContext()

MemoryContext AlignedAllocGetChunkContext ( void *  pointer)

Definition at line 136 of file alignedalloc.c.

137{
138 MemoryChunk *redirchunk = PointerGetMemoryChunk(pointer);
139 MemoryContext cxt;
140
141 VALGRIND_MAKE_MEM_DEFINED(redirchunk, sizeof(MemoryChunk));
142
143 Assert(!MemoryChunkIsExternal(redirchunk));
144
146
147 VALGRIND_MAKE_MEM_NOACCESS(redirchunk, sizeof(MemoryChunk));
148
149 return cxt;
150}
#define VALGRIND_MAKE_MEM_NOACCESS(addr, size)
Definition: memdebug.h:27

References Assert(), GetMemoryChunkContext(), MemoryChunkGetBlock(), MemoryChunkIsExternal(), PointerGetMemoryChunk, VALGRIND_MAKE_MEM_DEFINED, and VALGRIND_MAKE_MEM_NOACCESS.

◆ AlignedAllocGetChunkSpace()

Size AlignedAllocGetChunkSpace ( void *  pointer)

Definition at line 158 of file alignedalloc.c.

159{
160 MemoryChunk *redirchunk = PointerGetMemoryChunk(pointer);
161 void *unaligned;
162 Size space;
163
164 VALGRIND_MAKE_MEM_DEFINED(redirchunk, sizeof(MemoryChunk));
165
166 unaligned = MemoryChunkGetBlock(redirchunk);
167 space = GetMemoryChunkSpace(unaligned);
168
169 VALGRIND_MAKE_MEM_NOACCESS(redirchunk, sizeof(MemoryChunk));
170
171 return space;
172}
size_t Size
Definition: c.h:576
Size GetMemoryChunkSpace(void *pointer)
Definition: mcxt.c:721

References GetMemoryChunkSpace(), MemoryChunkGetBlock(), PointerGetMemoryChunk, VALGRIND_MAKE_MEM_DEFINED, and VALGRIND_MAKE_MEM_NOACCESS.

◆ AlignedAllocRealloc()

void * AlignedAllocRealloc ( void *  pointer,
Size  size,
int  flags 
)

Definition at line 61 of file alignedalloc.c.

62{
63 MemoryChunk *redirchunk = PointerGetMemoryChunk(pointer);
64 Size alignto;
65 void *unaligned;
66 MemoryContext ctx;
67 Size old_size;
68 void *newptr;
69
70 VALGRIND_MAKE_MEM_DEFINED(redirchunk, sizeof(MemoryChunk));
71
72 alignto = MemoryChunkGetValue(redirchunk);
73 unaligned = MemoryChunkGetBlock(redirchunk);
74
75 /* sanity check this is a power of 2 value */
76 Assert((alignto & (alignto - 1)) == 0);
77
78 /*
79 * Determine the size of the original allocation. We can't determine this
80 * exactly as GetMemoryChunkSpace() returns the total space used for the
81 * allocation, which for contexts like aset includes rounding up to the
82 * next power of 2. However, this value is just used to memcpy() the old
83 * data into the new allocation, so we only need to concern ourselves with
84 * not reading beyond the end of the original allocation's memory. The
85 * drawback here is that we may copy more bytes than we need to, which
86 * only amounts to wasted effort. We can safely subtract the extra bytes
87 * that we requested to allow us to align the pointer. We must also
88 * subtract the space for the unaligned pointer's MemoryChunk since
89 * GetMemoryChunkSpace should have included that. This does assume that
90 * all context types use MemoryChunk as a chunk header.
91 */
92 old_size = GetMemoryChunkSpace(unaligned) -
93 PallocAlignedExtraBytes(alignto) - sizeof(MemoryChunk);
94
95#ifdef MEMORY_CONTEXT_CHECKING
96 /* check that GetMemoryChunkSpace returned something realistic */
97 Assert(old_size >= redirchunk->requested_size);
98#endif
99
100 /*
101 * To keep things simple, we always allocate a new aligned chunk and copy
102 * data into it. Because of the above inaccuracy, this may end in copying
103 * more data than was in the original allocation request size, but that
104 * should be OK.
105 */
106 ctx = GetMemoryChunkContext(unaligned);
107 newptr = MemoryContextAllocAligned(ctx, size, alignto, flags);
108
109 /* Cope cleanly with OOM */
110 if (unlikely(newptr == NULL))
111 {
112 VALGRIND_MAKE_MEM_NOACCESS(redirchunk, sizeof(MemoryChunk));
113 return MemoryContextAllocationFailure(ctx, size, flags);
114 }
115
116 /*
117 * We may memcpy more than the original allocation request size, which
118 * would result in trying to copy trailing bytes that the original
119 * MemoryContextAllocAligned call marked NOACCESS. So we must mark the
120 * entire old_size as defined. That's slightly annoying, but probably not
121 * worth improving.
122 */
123 VALGRIND_MAKE_MEM_DEFINED(pointer, old_size);
124 memcpy(newptr, pointer, Min(size, old_size));
125
126 pfree(unaligned);
127
128 return newptr;
129}
#define Min(x, y)
Definition: c.h:975
#define unlikely(x)
Definition: c.h:347
void * MemoryContextAllocAligned(MemoryContext context, Size size, Size alignto, int flags)
Definition: mcxt.c:1416
void * MemoryContextAllocationFailure(MemoryContext context, Size size, int flags)
Definition: mcxt.c:1151
#define PallocAlignedExtraBytes(alignto)
static Size MemoryChunkGetValue(MemoryChunk *chunk)
struct MemoryChunk MemoryChunk

References Assert(), GetMemoryChunkContext(), GetMemoryChunkSpace(), MemoryChunkGetBlock(), MemoryChunkGetValue(), MemoryContextAllocAligned(), MemoryContextAllocationFailure(), Min, PallocAlignedExtraBytes, pfree(), PointerGetMemoryChunk, unlikely, VALGRIND_MAKE_MEM_DEFINED, and VALGRIND_MAKE_MEM_NOACCESS.