*
* memnodes.h
* openGauss memory context node definitions.
*
*
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/nodes/memnodes.h
*
* -------------------------------------------------------------------------
*/
#ifndef MEMNODES_H
#define MEMNODES_H
typedef struct MemoryTrackData* MemoryTrack;
typedef struct MemoryTrackData {
NodeTag type;
MemoryTrack parent;
MemoryTrack firstchild;
MemoryTrack nextchild;
char* name;
Size peakSpace;
Size allBytesPeak;
Size allBytesAlloc;
Size allBytesFreed;
int sequentCount;
#ifdef MEMORY_CONTEXT_CHECKING
bool isTracking;
#endif
} MemoryTrackData;
#define MemoryContextIsShared(context) (((MemoryContextData*)(context))->is_shared)
#define MemoryContextLock(context) \
do { \
HOLD_INTERRUPTS(); \
int err = pthread_rwlock_wrlock(&((MemoryContextData*)(context))->lock); \
if (err != 0) { \
RESUME_INTERRUPTS(); \
ereport(ERROR, \
(errcode(ERRCODE_LOCK_NOT_AVAILABLE), \
errmsg("system call failed when lock, errno:%d.", err))); \
} \
} while (0)
#define MemoryContextUnlock(context) \
do { \
int unlock_err = pthread_rwlock_unlock(&((MemoryContextData*)(context))->lock); \
if (unlock_err != 0) { \
RESUME_INTERRUPTS(); \
ereport(PANIC, \
(errcode(ERRCODE_LOCK_NOT_AVAILABLE), \
errmsg("system call failed when unlock, errno:%d.", unlock_err))); \
} \
RESUME_INTERRUPTS(); \
} while (0)
typedef struct AllocBlockData* AllocBlock;
typedef struct AllocChunkData* AllocChunk;
typedef struct AsanBlockData* AsanBlock;
* AllocPointer
* Aligned pointer which may be a member of an allocation set.
*/
typedef void* AllocPointer;
#define ALLOCSET_NUM_FREELISTS 11
* AllocSetContext is our standard implementation of MemoryContext.
*
* Note: header.isReset means there is nothing for AllocSetReset to do.
* This is different from the aset being physically empty (empty blocks list)
* because we may still have a keeper block. It's also different from the set
* being logically empty, because we don't attempt to detect pfree'ing the
* last active chunk.
*/
typedef struct AllocSetContext {
MemoryContextData header;
AllocBlock blocks;
AllocChunk freelist[ALLOCSET_NUM_FREELISTS];
Size initBlockSize;
Size maxBlockSize;
Size nextBlockSize;
Size allocChunkLimit;
AllocBlock keeper;
Size totalSpace;
Size freeSpace;
Size maxSpaceSize;
int freeListIndex;
MemoryTrack track;
} AllocSetContext;
typedef AllocSetContext* AllocSet;
* AllocBlock
* An AllocBlock is the unit of memory that is obtained by aset.c
* from malloc(). It contains one or more AllocChunks, which are
* the units requested by palloc() and freed by pfree(). AllocChunks
* cannot be returned to malloc() individually, instead they are put
* on freelists by pfree() and re-used by the next palloc() that has
* a matching request size.
*
* AllocBlockData is the header data for a block --- the usable space
* within the block begins at the next alignment boundary.
*/
typedef struct AllocBlockData {
AllocSet aset;
AllocBlock prev;
AllocBlock next;
char* freeptr;
char* endptr;
Size allocSize;
#ifdef MEMORY_CONTEXT_CHECKING
uint64 magicNum;
#endif
} AllocBlockData;
* AllocChunk
* The prefix of each piece of memory in an AllocBlock
*
* NB: this MUST match StandardChunkHeader as defined by utils/memutils.h.
*/
typedef struct AllocChunkData {
void* aset;
Size size;
#ifdef MEMORY_CONTEXT_CHECKING
Size requested_size;
#endif
#ifdef MEMORY_CONTEXT_TRACK
const char* file;
int line;
#endif
#ifdef MEMORY_CONTEXT_CHECKING
uint32 prenum;
#endif
} AllocChunkData;
#define ALLOC_CHUNKHDRSZ MAXALIGN(sizeof(AllocChunkData))
#define ALLOC_BLOCKHDRSZ MAXALIGN(sizeof(AllocBlockData))
* Note:
* AsanSetContext's structure must be consistent with AllocSetContext.
* header.isReset means there is nothing for AsanSetContext to do.
* This is different from the aset being physically empty (empty blocks list)
* because we may still have a keeper block. It's also different from the set
* being logically empty, because we don't attempt to detect pfree'ing the * last active chunk. */
typedef struct AsanSetContext {
MemoryContextData header;
AsanBlock blocks;
char* reserve[ALLOCSET_NUM_FREELISTS];
Size initBlockSize;
Size maxBlockSize;
Size nextBlockSize;
Size allocChunkLimit;
AsanBlock keeper;
Size totalSpace;
Size freeSpace;
Size maxSpaceSize;
MemoryTrack track;
} AsanSetContext;
typedef AsanSetContext* AsanSet;
typedef struct AsanBlockData {
AsanSet aset;
AsanBlock prev;
AsanBlock next;
uint32 requestSize;
int line;
const char* file;
} AsanBlockData;
#define ASAN_BLOCKHDRSZ MAXALIGN(sizeof(AsanBlockData))
typedef struct StackBlockData* StackBlock;
typedef struct StackSetContext {
MemoryContextData header;
StackBlock blocks;
StackBlock freelist[ALLOCSET_NUM_FREELISTS];
Size initBlockSize;
Size maxBlockSize;
Size nextBlockSize;
Size allocChunkLimit;
StackBlock keeper;
Size totalSpace;
Size freeSpace;
* Otherwise the pointer of MemoryContextMethods will be out-of-order.
* So AllocSetContext is.You can see @AllocSetContext
*/
Size maxSpaceSize;
MemoryTrack track;
} StackSetContext;
typedef struct MemoryProtectFuncDef {
void* (*malloc)(Size sz, bool needProtect);
void (*free)(void* ptr, Size sz);
void* (*realloc)(void* ptr, Size oldsz, Size newsz, bool needProtect);
int (*memalign)(void** memptr, Size alignment, Size sz, bool needProtect);
} MemoryProtectFuncDef;
extern MemoryProtectFuncDef GenericFunctions;
extern MemoryProtectFuncDef SessionFunctions;
extern MemoryProtectFuncDef SharedFunctions;
#define IsOptAllocSetContext(cxt) \
((cxt) != NULL && (IsA((cxt), OptAllocSetContext)))
* MemoryContextIsValid
* True iff memory context is valid.
*
* Add new context types to the set accepted by this macro.
*/
#define MemoryContextIsValid(context) \
((context) != NULL && \
(IsA((context), AllocSetContext) || IsA((context), AsanSetContext) || IsA((context), StackAllocSetContext) || \
IsA((context), SharedAllocSetContext) || IsA((context), MemalignAllocSetContext) || \
IsA((context), MemalignSharedAllocSetContext) || IsA((context), OptAllocSetContext) || \
IsA((context), RackAllocSetContext) || IsA((context), RackSharedAllocSetContext)))
#define AllocSetContextUsedSpace(aset) ((aset)->totalSpace - (aset)->freeSpace)
typedef struct SessMemoryUsage {
uint64 sessid;
int64 usedSize;
int state;
} SessMemoryUsage;
#endif