/*------------------------------------------------------------------------- * * palloc.h * POSTGRES memory allocator definitions. * * This file contains the basic memory allocation interface that is * needed by almost every backend module. It is included directly by * postgres.h, so the definitions here are automatically available * everywhere. Keep it lean! * * Memory allocation occurs within "contexts". Every chunk obtained from * palloc()/MemoryContextAlloc() is allocated within a specific context. * The entire contents of a context can be freed easily and quickly by * resetting or deleting the context --- this is both faster and less * prone to memory-leakage bugs than releasing chunks individually. * We organize contexts into context trees to allow fine-grain control * over chunk lifetime while preserving the certainty that we will free * everything that should be freed. See utils/mmgr/README for more info. * * * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/palloc.h * *------------------------------------------------------------------------- */ #ifndef PALLOC_H #define PALLOC_H /* * Type MemoryContextData is declared in nodes/memnodes.h. Most users * of memory allocation should just treat it as an abstract type, so we * do not provide the struct contents here. */ typedef struct MemoryContextData *MemoryContext; /* * A memory context can have callback functions registered on it. Any such * function will be called once just before the context is next reset or * deleted. The MemoryContextCallback struct describing such a callback * typically would be allocated within the context itself, thereby avoiding * any need to manage it explicitly (the reset/delete action will free it). */ typedef void (*MemoryContextCallbackFunction) (void *arg); typedef struct MemoryContextCallback { MemoryContextCallbackFunction func; /* function to call */ void *arg; /* argument to pass it */ struct MemoryContextCallback *next; /* next in list of callbacks */ } MemoryContextCallback; /* * CurrentMemoryContext is the default allocation context for palloc(). * Avoid accessing it directly! Instead, use MemoryContextSwitchTo() * to change the setting. */ extern PGDLLIMPORT MemoryContext CurrentMemoryContext; /* * Flags for MemoryContextAllocExtended. */ #define MCXT_ALLOC_HUGE 0x01 /* allow huge allocation (> 1 GB) */ #define MCXT_ALLOC_NO_OOM 0x02 /* no failure if out-of-memory */ #define MCXT_ALLOC_ZERO 0x04 /* zero allocated memory */ /* * Fundamental memory-allocation operations (more are in utils/memutils.h) */ extern void *MemoryContextAlloc(MemoryContext context, Size size); extern void *MemoryContextAllocZero(MemoryContext context, Size size); extern void *MemoryContextAllocZeroAligned(MemoryContext context, Size size); extern void *MemoryContextAllocExtended(MemoryContext context, Size size, int flags); extern void *MemoryContextAllocAligned(MemoryContext context, Size size, Size alignto, int flags); extern void *palloc(Size size); extern void *palloc0(Size size); extern void *palloc_extended(Size size, int flags); extern void *palloc_aligned(Size size, Size alignto, int flags); extern pg_nodiscard void *repalloc(void *pointer, Size size); extern pg_nodiscard void *repalloc_extended(void *pointer, Size size, int flags); extern pg_nodiscard void *repalloc0(void *pointer, Size oldsize, Size size); extern void pfree(void *pointer); /* * Variants with easier notation and more type safety */ /* * Allocate space for one object of type "type" */ #define palloc_object(type) ((type *) palloc(sizeof(type))) #define palloc0_object(type) ((type *) palloc0(sizeof(type))) /* * Allocate space for "count" objects of type "type" */ #define palloc_array(type, count) ((type *) palloc(sizeof(type) * (count))) #define palloc0_array(type, count) ((type *) palloc0(sizeof(type) * (count))) /* * Change size of allocation pointed to by "pointer" to have space for "count" * objects of type "type" */ #define repalloc_array(pointer, type, count) ((type *) repalloc(pointer, sizeof(type) * (count))) #define repalloc0_array(pointer, type, oldcount, count) ((type *) repalloc0(pointer, sizeof(type) * (oldcount), sizeof(type) * (count))) /* * The result of palloc() is always word-aligned, so we can skip testing * alignment of the pointer when deciding which MemSet variant to use. * Note that this variant does not offer any advantage, and should not be * used, unless its "sz" argument is a compile-time constant; therefore, the * issue that it evaluates the argument multiple times isn't a problem in * practice. */ #define palloc0fast(sz) \ ( MemSetTest(0, sz) ? \ MemoryContextAllocZeroAligned(CurrentMemoryContext, sz) : \ MemoryContextAllocZero(CurrentMemoryContext, sz) ) /* Higher-limit allocators. */ extern void *MemoryContextAllocHuge(MemoryContext context, Size size); extern pg_nodiscard void *repalloc_huge(void *pointer, Size size); /* * Although this header file is nominally backend-only, certain frontend * programs like pg_controldata include it via postgres.h. For some compilers * it's necessary to hide the inline definition of MemoryContextSwitchTo in * this scenario; hence the #ifndef FRONTEND. */ #ifndef FRONTEND static inline MemoryContext MemoryContextSwitchTo(MemoryContext context) { MemoryContext old = CurrentMemoryContext; CurrentMemoryContext = context; return old; } #endif /* FRONTEND */ /* Registration of memory context reset/delete callbacks */ extern void MemoryContextRegisterResetCallback(MemoryContext context, MemoryContextCallback *cb); /* * These are like standard strdup() except the copied string is * allocated in a context, not with malloc(). */ extern char *MemoryContextStrdup(MemoryContext context, const char *string); extern char *pstrdup(const char *in); extern char *pnstrdup(const char *in, Size len); extern char *pchomp(const char *in); /* sprintf into a palloc'd buffer --- these are in psprintf.c */ extern char *psprintf(const char *fmt,...) pg_attribute_printf(1, 2); extern size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args) pg_attribute_printf(3, 0); #endif /* PALLOC_H */