/* ------------------------------------------------------------------------- * * 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; /* forward reference */ typedef struct MemoryTrackData { NodeTag type; /* identifies exact kind of context */ MemoryTrack parent; /* NULL if no parent (toplevel context) */ MemoryTrack firstchild; /* head of linked list of children */ MemoryTrack nextchild; /* next child of same parent */ char* name; /* context name */ Size peakSpace; /* the peak bytes allocated by this context */ Size allBytesPeak; /* the peak bytes allocated by this and its children's context */ Size allBytesAlloc; /* all bytes allocated by this and its children's context */ Size allBytesFreed; /* all bytes freed by this and its children's context */ int sequentCount; /* the sequent count when creating in the thread */ #ifdef MEMORY_CONTEXT_CHECKING bool isTracking; /* flag to indicate which is tracked by memory_detail_tracking setting */ #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; /* forward reference */ 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; /* Standard memory-context fields */ /* Info about storage allocated in this context: */ AllocBlock blocks; /* head of list of blocks in this set */ AllocChunk freelist[ALLOCSET_NUM_FREELISTS]; /* free chunk lists */ /* Allocation parameters for this context: */ Size initBlockSize; /* initial block size */ Size maxBlockSize; /* maximum block size */ Size nextBlockSize; /* next block size to allocate */ Size allocChunkLimit; /* effective chunk size limit */ AllocBlock keeper; /* if not NULL, keep this block over resets */ Size totalSpace; /* all bytes allocated by this context */ Size freeSpace; /* all bytes freed by this context */ /* maximum memory allocation of MemoryContext.For more information,we could see @StackSetContext too. */ Size maxSpaceSize; int freeListIndex; MemoryTrack track; /* used to track the memory allocation information */ } 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; /* aset that owns this block */ AllocBlock prev; /* prev block in aset's blocks list, if any */ AllocBlock next; /* next block in aset's blocks list */ char* freeptr; /* start of free space in this block */ char* endptr; /* end of space in this block */ Size allocSize; /* allocated size */ #ifdef MEMORY_CONTEXT_CHECKING uint64 magicNum; /* DADA */ #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 { /* aset is the owning aset if allocated, or the freelist link if free */ void* aset; /* size is always the size of the usable space in the chunk */ Size size; #ifdef MEMORY_CONTEXT_CHECKING /* when debugging memory usage, also store actual requested size */ /* this is zero in a free chunk */ Size requested_size; #endif #ifdef MEMORY_CONTEXT_TRACK const char* file; /* __FILE__ of palloc/palloc0 call */ int line; /* __LINE__ of palloc/palloc0 call */ #endif #ifdef MEMORY_CONTEXT_CHECKING uint32 prenum; /* prefix magic number */ #endif } AllocChunkData; #define ALLOC_CHUNKHDRSZ MAXALIGN(sizeof(AllocChunkData)) #define ALLOC_BLOCKHDRSZ MAXALIGN(sizeof(AllocBlockData)) /* AsanSetContext is our asan implementation of MemoryContext. * 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; /* Standard memory-context fields */ /* Info about storage allocated in this context: */ AsanBlock blocks; /* head of list of blocks in this set */ char* reserve[ALLOCSET_NUM_FREELISTS]; /* Allocation parameters for this context: */ Size initBlockSize; /* initial block size */ Size maxBlockSize; /* maximum block size */ Size nextBlockSize; /* next block size to allocate */ Size allocChunkLimit; /* effective chunk size limit */ AsanBlock keeper; /* if not NULL, keep this block over resets */ Size totalSpace; /* all bytes allocated by this context */ Size freeSpace; /* all bytes freed by this context */ /* maximum memory allocation of MemoryContext.For more information,we could see @StackSetContext too. */ Size maxSpaceSize; MemoryTrack track; /* used to track the memory allocation information */ } AsanSetContext; typedef AsanSetContext* AsanSet; typedef struct AsanBlockData { AsanSet aset; /* aset that owns this block */ AsanBlock prev; /* prev block in aset's blocks list, if any */ AsanBlock next; /* next block in aset's blocks list */ uint32 requestSize; /* request size */ int line; /* __LINE__ of palloc/palloc0 call */ const char* file; /* __FILE__ of palloc/palloc0 call */ } AsanBlockData; #define ASAN_BLOCKHDRSZ MAXALIGN(sizeof(AsanBlockData)) /* utils/palloc.h contains typedef struct MemoryContextData *MemoryContext */ typedef struct StackBlockData* StackBlock; typedef struct StackSetContext { MemoryContextData header; /* Standard memory-context fields */ StackBlock blocks; StackBlock freelist[ALLOCSET_NUM_FREELISTS]; /* free chunk lists */ // Allocation parameters for this context: // Size initBlockSize; // initial block size Size maxBlockSize; // maximum block size Size nextBlockSize; // next block size Size allocChunkLimit; // limit chunk StackBlock keeper; Size totalSpace; Size freeSpace; /* The parameter named maxSpaceSize is an allocation parameter,but this parameter must be here. * Otherwise the pointer of MemoryContextMethods will be out-of-order. * So AllocSetContext is.You can see @AllocSetContext */ Size maxSpaceSize; MemoryTrack track; /* used to track the memory allocation information */ } 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 /* MEMNODES_H */