palloc.h 7.7 KB
Newer Older
1 2
/*-------------------------------------------------------------------------
 *
3
 * palloc.h
4
 *	  POSTGRES memory allocator definitions.
5
 *
6 7 8
 * 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
B
Bruce Momjian 已提交
9
 * everywhere.	Keep it lean!
10
 *
B
Bruce Momjian 已提交
11
 * Memory allocation occurs within "contexts".	Every chunk obtained from
12 13 14 15 16 17 18 19
 * 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.
 *
20
 *
21 22
 * Portions Copyright (c) 2007-2008, Greenplum inc
 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
B
Add:  
Bruce Momjian 已提交
23
 * Portions Copyright (c) 1994, Regents of the University of California
24
 *
25
 * $PostgreSQL: pgsql/src/include/utils/palloc.h,v 1.38 2008/01/01 19:45:59 momjian Exp $
26 27 28
 *
 *-------------------------------------------------------------------------
 */
29
#ifndef PALLOC_H
30 31
#define PALLOC_H

32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
/*
 * Optional #defines for debugging...
 *
 * If CDB_PALLOC_CALLER_ID is defined, MemoryContext error and warning
 * messages (such as "out of memory" and "invalid memory alloc request
 * size") will include the caller's source file name and line number.
 * This can be useful in optimized builds where the error handler's
 * stack trace doesn't accurately identify the call site.  Overhead
 * is minimal: two extra parameters to memory allocation functions,
 * and 8 to 16 bytes per context.
 *
 * If CDB_PALLOC_TAGS is defined, every allocation from a standard
 * memory context (aset.c) is tagged with an extra 16 to 32 bytes of
 * debugging info preceding the first byte of the area.  The added
 * header fields identify the allocation call site (source file name
 * and line number).  Also each context keeps a linked list of all
 * of its allocated areas.  The dump_memory_allocation() and
 * dump_memory_allocation_ctxt() functions in aset.c may be called 
 * from a debugger to write the area headers to a file.
 */

/*
#define CDB_PALLOC_CALLER_ID
*/

#define CDB_PALLOC_TAGS
58
#define ALLOC_SITE_KEY_SIZE 255
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80

/* CDB_PALLOC_TAGS implies CDB_PALLOC_CALLER_ID */
#if defined(CDB_PALLOC_TAGS) && !defined(CDB_PALLOC_CALLER_ID)
#define CDB_PALLOC_CALLER_ID
#endif

#include "pg_trace.h"
#include "utils/memaccounting.h"

/*
 * We track last OOM time to identify culprit processes that
 * consume too much memory. For 64-bit platform we have high
 * precision time variable based on TimeStampTz. However, on
 * 32-bit platform we only have "per-second" precision.
 * OOMTimeType abstracts this different types.
 */
#if defined(__x86_64__)
typedef int64 OOMTimeType;
#else
typedef uint32 OOMTimeType;
#endif

81
/*
B
Bruce Momjian 已提交
82
 * Type MemoryContextData is declared in nodes/memnodes.h.	Most users
83 84 85 86 87
 * of memory allocation should just treat it as an abstract type, so we
 * do not provide the struct contents here.
 */
typedef struct MemoryContextData *MemoryContext;

88 89 90 91 92 93 94 95 96 97
typedef struct
{
	char hash_key[ALLOC_SITE_KEY_SIZE];
	char* file_name;
	int line_no;
	int64 alloc_count;
	int64 alloc_size;
	uint64 gen_allocated; // which generations did we allocate from this site
} AllocSiteInfo;

98 99
/*
 * CurrentMemoryContext is the default allocation context for palloc().
B
Bruce Momjian 已提交
100
 * We declare it here so that palloc() can be a macro.	Avoid accessing it
101 102
 * directly!  Instead, use MemoryContextSwitchTo() to change the setting.
 */
103 104 105 106 107 108
extern PGDLLIMPORT MemoryContext CurrentMemoryContext;

extern bool gp_mp_inited;
extern volatile OOMTimeType* segmentOOMTime;
extern volatile OOMTimeType oomTrackerStartTime;
extern volatile OOMTimeType alreadyReportedOOMTime;
109 110 111 112

/*
 * Fundamental memory-allocation operations (more are in utils/memutils.h)
 */
113 114 115 116 117
extern void * __attribute__((malloc)) MemoryContextAllocImpl(MemoryContext context, Size size, const char* file, const char *func, int line);
extern void * __attribute__((malloc)) MemoryContextAllocZeroImpl(MemoryContext context, Size size, const char* file, const char *func, int line);
extern void * __attribute__((malloc)) MemoryContextAllocZeroAlignedImpl(MemoryContext context, Size size, const char* file, const char *func, int line);
extern void * __attribute__((malloc)) MemoryContextReallocImpl(void *pointer, Size size, const char* file, const char *func, int line);
extern void MemoryContextFreeImpl(void *pointer, const char* file, const char *func, int sline);
118

119 120 121
#define MemoryContextAlloc(ctxt, sz) MemoryContextAllocImpl((ctxt), (sz), __FILE__, PG_FUNCNAME_MACRO, __LINE__)
#define palloc(sz) MemoryContextAlloc(CurrentMemoryContext, (sz)) 
#define ctxt_alloc(ctxt, sz) MemoryContextAlloc((ctxt), (sz)) 
122

123
#define MemoryContextAllocZero(ctxt, sz) MemoryContextAllocZeroImpl((ctxt), (sz), __FILE__, PG_FUNCNAME_MACRO, __LINE__)
B
Bruce Momjian 已提交
124
#define palloc0(sz) MemoryContextAllocZero(CurrentMemoryContext, (sz))
125

126 127 128
#define repalloc(ptr, sz) MemoryContextReallocImpl(ptr, (sz), __FILE__, PG_FUNCNAME_MACRO, __LINE__)
#define pfree(ptr) MemoryContextFreeImpl(ptr, __FILE__, PG_FUNCNAME_MACRO, __LINE__)

129 130 131 132 133 134 135 136
/*
 * 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.
 */
B
Bruce Momjian 已提交
137
#define palloc0fast(sz) \
138 139 140
	( MemSetTest(0, (sz)) ? \
		MemoryContextAllocZeroAlignedImpl(CurrentMemoryContext, (sz), __FILE__, PG_FUNCNAME_MACRO, __LINE__) : \
		MemoryContextAllocZeroImpl(CurrentMemoryContext, (sz), __FILE__, PG_FUNCNAME_MACRO, __LINE__))
141

142 143 144 145
/*
 * MemoryContextSwitchTo can't be a macro in standard C compilers.
 * But we can make it an inline function when using GCC.
 */
146
static inline MemoryContext
147 148 149
MemoryContextSwitchTo(MemoryContext context)
{
	MemoryContext old = CurrentMemoryContext;
B
Bruce Momjian 已提交
150

151 152 153 154
	CurrentMemoryContext = context;
	return old;
}

155 156 157 158
/*
 * These are like standard strdup() except the copied string is
 * allocated in a context, not with malloc().
 */
159 160
extern char * __attribute__((malloc)) MemoryContextStrdup(MemoryContext context, const char *string);
extern void MemoryContextStats(MemoryContext context);
161 162 163

#define pstrdup(str)  MemoryContextStrdup(CurrentMemoryContext, (str))

164 165
extern char *pnstrdup(const char *in, Size len);

166
#if defined(WIN32) || defined(__CYGWIN__)
167 168 169 170
extern void *pgport_palloc(Size sz);
extern char *pgport_pstrdup(const char *str);
extern void pgport_pfree(void *pointer);
#endif
171

172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
/* Mem Protection */
extern int max_chunks_per_query;

extern PGDLLIMPORT MemoryContext TopMemoryContext;

extern bool MemoryProtection_IsOwnerThread(void);
extern void InitPerProcessOOMTracking(void);
extern void GPMemoryProtect_ShmemInit(void);
extern void GPMemoryProtect_Init(void);
extern void GPMemoryProtect_Shutdown(void);
extern void UpdateTimeAtomically(volatile OOMTimeType* time_var);

/*
 * ReportOOMConsumption
 *
 * Checks if there was any new OOM event in this segment.
 * In case of a new OOM, it reports the memory consumption
 * of the current process.
 */
#define ReportOOMConsumption()\
{\
	if (gp_mp_inited && *segmentOOMTime >= oomTrackerStartTime && *segmentOOMTime > alreadyReportedOOMTime)\
	{\
		Assert(MemoryProtection_IsOwnerThread());\
		UpdateTimeAtomically(&alreadyReportedOOMTime);\
		write_stderr("One or more query execution processes ran out of memory on this segment. Logging memory usage.");\
		MemoryAccounting_SaveToLog();\
		MemoryContextStats(TopMemoryContext);\
	}\
}

203
#endif   /* PALLOC_H */