blob: 3c43907992ec60495ea1c243230a5371561589b8 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*-------------------------------------------------------------------------
*
* 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) 2007-2008, Greenplum inc
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/palloc.h,v 1.35 2006/03/05 15:59:07 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef PALLOC_H
#define PALLOC_H
/*
* 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
*/
#ifdef USE_ASSERT_CHECKING
#define CDB_PALLOC_TAGS
#endif
/* 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
/*
* 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;
/*
* CurrentMemoryContext is the default allocation context for palloc().
* We declare it here so that palloc() can be a macro. Avoid accessing it
* directly! Instead, use MemoryContextSwitchTo() to change the setting.
*/
extern PGDLLIMPORT MemoryContext CurrentMemoryContext;
/* GP vmem protect */
extern bool gp_mp_inited;
extern volatile OOMTimeType* segmentOOMTime;
extern volatile OOMTimeType oomTrackerStartTime;
extern volatile OOMTimeType alreadyReportedOOMTime;
/*
* Fundamental memory-allocation operations (more are in utils/memutils.h)
*/
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);
#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))
#define MemoryContextAllocZero(ctxt, sz) MemoryContextAllocZeroImpl((ctxt), (sz), __FILE__, PG_FUNCNAME_MACRO, __LINE__)
#define palloc0(sz) MemoryContextAllocZero(CurrentMemoryContext, (sz))
#define repalloc(ptr, sz) MemoryContextReallocImpl(ptr, (sz), __FILE__, PG_FUNCNAME_MACRO, __LINE__)
#define pfree(ptr) MemoryContextFreeImpl(ptr, __FILE__, PG_FUNCNAME_MACRO, __LINE__)
/*
* 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)) ? \
MemoryContextAllocZeroAlignedImpl(CurrentMemoryContext, (sz), __FILE__, PG_FUNCNAME_MACRO, __LINE__) : \
MemoryContextAllocZeroImpl(CurrentMemoryContext, (sz), __FILE__, PG_FUNCNAME_MACRO, __LINE__))
/*
* MemoryContextSwitchTo can't be a macro in standard C compilers.
* But we can make it an inline function when using GCC.
*/
static inline MemoryContext
MemoryContextSwitchTo(MemoryContext context)
{
MemoryContext old = CurrentMemoryContext;
CurrentMemoryContext = context;
return old;
}
/*
* These are like standard strdup() except the copied string is
* allocated in a context, not with malloc().
*/
extern char * __attribute__((malloc)) MemoryContextStrdup(MemoryContext context, const char *string);
extern void MemoryContextStats(MemoryContext context);
#define pstrdup(str) MemoryContextStrdup(CurrentMemoryContext, (str))
extern char *pnstrdup(const char *in, Size len);
#if defined(WIN32) || defined(__CYGWIN__)
extern void *pgport_palloc(Size sz);
extern char *pgport_pstrdup(const char *str);
extern void pgport_pfree(void *pointer);
#endif
/* 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);\
}\
}
#ifdef USE_SYSV_SEMAPHORES
extern void *gp_malloc(int64 sz);
extern void *gp_calloc(int64 nmemb, int64 sz);
extern void *gp_realloc(void *ptr, int64 sz, int64 newsz);
extern void gp_free2(void *ptr, int64 sz);
/* Current available memory quota */
extern int64 gp_vmem_avail(void);
/* Current dynamic memory allocation in bytes. */
extern uint64 gp_vmem_used(void);
/* Maximum allowed dynamic memory allocation in bytes. */
extern uint64 gp_vmem_max(void);
/* Increase/Decrease memory quota in MB */
extern int gp_update_mem_quota(int mem_quota_total);
#else
#define gp_malloc(sz) malloc(sz)
#define gp_calloc(sz1, sz2) calloc((sz1), (sz2))
#define gp_realloc(ptr, sz1, sz2) realloc((ptr), (sz2))
#define gp_free2(ptr, sz) free(ptr)
/* Increase/Decrease memory quota in MB */
extern int gp_update_mem_quota(int mem_quota_total);
#endif
#endif /* PALLOC_H */