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)
 
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 
34  VALGRIND_MAKE_MEM_DEFINED(chunk, sizeof(MemoryChunk));
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  pfree(unaligned);
49 }
#define WARNING
Definition: elog.h:36
Assert(fmt[strlen(fmt) - 1] !='\n')
void pfree(void *pointer)
Definition: mcxt.c:1456
MemoryContext GetMemoryChunkContext(void *pointer)
Definition: mcxt.c:616
#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 118 of file alignedalloc.c.

119 {
120  MemoryChunk *redirchunk = PointerGetMemoryChunk(pointer);
121  MemoryContext cxt;
122 
123  VALGRIND_MAKE_MEM_DEFINED(redirchunk, sizeof(MemoryChunk));
124 
125  Assert(!MemoryChunkIsExternal(redirchunk));
126 
127  cxt = GetMemoryChunkContext(MemoryChunkGetBlock(redirchunk));
128 
129  VALGRIND_MAKE_MEM_NOACCESS(redirchunk, sizeof(MemoryChunk));
130 
131  return cxt;
132 }
#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 140 of file alignedalloc.c.

141 {
142  MemoryChunk *redirchunk = PointerGetMemoryChunk(pointer);
143  void *unaligned;
144  Size space;
145 
146  VALGRIND_MAKE_MEM_DEFINED(redirchunk, sizeof(MemoryChunk));
147 
148  unaligned = MemoryChunkGetBlock(redirchunk);
149  space = GetMemoryChunkSpace(unaligned);
150 
151  VALGRIND_MAKE_MEM_NOACCESS(redirchunk, sizeof(MemoryChunk));
152 
153  return space;
154 }
size_t Size
Definition: c.h:594
Size GetMemoryChunkSpace(void *pointer)
Definition: mcxt.c:630

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

◆ AlignedAllocRealloc()

void* AlignedAllocRealloc ( void *  pointer,
Size  size 
)

Definition at line 60 of file alignedalloc.c.

61 {
62  MemoryChunk *redirchunk = PointerGetMemoryChunk(pointer);
63  Size alignto;
64  void *unaligned;
65  MemoryContext ctx;
66  Size old_size;
67  void *newptr;
68 
69  VALGRIND_MAKE_MEM_DEFINED(redirchunk, sizeof(MemoryChunk));
70 
71  alignto = MemoryChunkGetValue(redirchunk);
72  unaligned = MemoryChunkGetBlock(redirchunk);
73 
74  /* sanity check this is a power of 2 value */
75  Assert((alignto & (alignto - 1)) == 0);
76 
77  /*
78  * Determine the size of the original allocation. We can't determine this
79  * exactly as GetMemoryChunkSpace() returns the total space used for the
80  * allocation, which for contexts like aset includes rounding up to the
81  * next power of 2. However, this value is just used to memcpy() the old
82  * data into the new allocation, so we only need to concern ourselves with
83  * not reading beyond the end of the original allocation's memory. The
84  * drawback here is that we may copy more bytes than we need to, which
85  * only amounts to wasted effort. We can safely subtract the extra bytes
86  * that we requested to allow us to align the pointer. We must also
87  * subtract the space for the unaligned pointer's MemoryChunk since
88  * GetMemoryChunkSpace should have included that. This does assume that
89  * all context types use MemoryChunk as a chunk header.
90  */
91  old_size = GetMemoryChunkSpace(unaligned) -
92  PallocAlignedExtraBytes(alignto) - sizeof(MemoryChunk);
93 
94 #ifdef MEMORY_CONTEXT_CHECKING
95  /* check that GetMemoryChunkSpace returned something realistic */
96  Assert(old_size >= redirchunk->requested_size);
97 #endif
98 
99  ctx = GetMemoryChunkContext(unaligned);
100  newptr = MemoryContextAllocAligned(ctx, size, alignto, 0);
101 
102  /*
103  * We may memcpy beyond the end of the original allocation request size,
104  * so we must mark the entire allocation as defined.
105  */
106  VALGRIND_MAKE_MEM_DEFINED(pointer, old_size);
107  memcpy(newptr, pointer, Min(size, old_size));
108  pfree(unaligned);
109 
110  return newptr;
111 }
#define Min(x, y)
Definition: c.h:993
void * MemoryContextAllocAligned(MemoryContext context, Size size, Size alignto, int flags)
Definition: mcxt.c:1344
#define PallocAlignedExtraBytes(alignto)
static Size MemoryChunkGetValue(MemoryChunk *chunk)
struct MemoryChunk MemoryChunk

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