postgresql/src/include/utils/memutils.h

124 lines
4.0 KiB
C
Raw Normal View History

/*-------------------------------------------------------------------------
*
* memutils.h
* This file contains declarations for memory allocation utility
* functions. These are functions that are not quite widely used
* enough to justify going in utils/palloc.h, but are still part
* of the API of the memory management subsystem.
*
*
2002-06-20 22:29:54 +02:00
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
2002-09-04 22:31:48 +02:00
* $Id: memutils.h,v 1.48 2002/09/04 20:31:45 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef MEMUTILS_H
#define MEMUTILS_H
#include "nodes/memnodes.h"
/*
* MaxAllocSize
* Quasi-arbitrary limit on size of allocations.
*
* Note:
* There is no guarantee that allocations smaller than MaxAllocSize
* will succeed. Allocation requests larger than MaxAllocSize will
* be summarily denied.
*
* XXX This is deliberately chosen to correspond to the limiting size
2001-03-22 05:01:46 +01:00
* of varlena objects under TOAST. See VARATT_MASK_SIZE in postgres.h.
*/
2001-03-22 05:01:46 +01:00
#define MaxAllocSize ((Size) 0x3fffffff) /* 1 gigabyte - 1 */
#define AllocSizeIsValid(size) (0 < (size) && (size) <= MaxAllocSize)
/*
* All chunks allocated by any memory context manager are required to be
* preceded by a StandardChunkHeader at a spacing of STANDARDCHUNKHEADERSIZE.
* A currently-allocated chunk must contain a backpointer to its owning
2001-03-22 05:01:46 +01:00
* context as well as the allocated size of the chunk. The backpointer is
* used by pfree() and repalloc() to find the context to call. The allocated
* size is not absolutely essential, but it's expected to be needed by any
* reasonable implementation.
*/
typedef struct StandardChunkHeader
{
2001-03-22 05:01:46 +01:00
MemoryContext context; /* owning context */
Size size; /* size of data space allocated in chunk */
Here is the patch with memory leak checker. This checker allow detect in-chunk leaks, overwrite-next-chunk leaks and overwrite block-freeptr leaks. A in-chunk leak --- if something overwrite space after wanted (via palloc() size, but it is still inside chunk. For example x = palloc(12); /* create 16b chunk */ memset(x, '#', 13); this leak is in the current source total invisible, because chunk is 16b and leak is in the "align space". For this feature I add data_size to StandardChunk, and all memory which go from AllocSetAlloc() is marked as 0x7F. The MemoryContextCheck() is compiled '#ifdef USE_ASSERT_CHECKING'. I add this checking to 'tcop/postgres.c' and is active after each backend query, but it is probably not sufficient, because some MemoryContext exist only during memory processing --- will good if someone who known where it is needful (Tom:-) add it for others contexts; A problem in the current source is that we have still some malloc() allocation that is not needful and this allocation is total invisible for all context routines. For example Dllist in backend (pretty dirty it is in catcache where values in Dllist are palloc-ed, but list is malloc-ed). --- and BTW. this Dllist design stand in the way for query cache :-) Tom, if you agree I start replace some mallocs. BTW. --- Tom, have you idea for across transaction presistent allocation for SQL functions? (like regex - now it is via malloc) I almost forget. I add one if() to AllocSetAlloc(), for 'size' that are greater than ALLOC_BIGCHUNK_LIMIT is not needful check AllocSetFreeIndex(), because 'fidx' is always 'ALLOCSET_NUM_FREELISTS - 1'. It a little brisk up allocation for very large chunks. Right? Karel
2000-07-11 16:30:37 +02:00
#ifdef MEMORY_CONTEXT_CHECKING
/* when debugging memory usage, also store actual requested size */
Size requested_size;
Here is the patch with memory leak checker. This checker allow detect in-chunk leaks, overwrite-next-chunk leaks and overwrite block-freeptr leaks. A in-chunk leak --- if something overwrite space after wanted (via palloc() size, but it is still inside chunk. For example x = palloc(12); /* create 16b chunk */ memset(x, '#', 13); this leak is in the current source total invisible, because chunk is 16b and leak is in the "align space". For this feature I add data_size to StandardChunk, and all memory which go from AllocSetAlloc() is marked as 0x7F. The MemoryContextCheck() is compiled '#ifdef USE_ASSERT_CHECKING'. I add this checking to 'tcop/postgres.c' and is active after each backend query, but it is probably not sufficient, because some MemoryContext exist only during memory processing --- will good if someone who known where it is needful (Tom:-) add it for others contexts; A problem in the current source is that we have still some malloc() allocation that is not needful and this allocation is total invisible for all context routines. For example Dllist in backend (pretty dirty it is in catcache where values in Dllist are palloc-ed, but list is malloc-ed). --- and BTW. this Dllist design stand in the way for query cache :-) Tom, if you agree I start replace some mallocs. BTW. --- Tom, have you idea for across transaction presistent allocation for SQL functions? (like regex - now it is via malloc) I almost forget. I add one if() to AllocSetAlloc(), for 'size' that are greater than ALLOC_BIGCHUNK_LIMIT is not needful check AllocSetFreeIndex(), because 'fidx' is always 'ALLOCSET_NUM_FREELISTS - 1'. It a little brisk up allocation for very large chunks. Right? Karel
2000-07-11 16:30:37 +02:00
#endif
} StandardChunkHeader;
#define STANDARDCHUNKHEADERSIZE MAXALIGN(sizeof(StandardChunkHeader))
/*
* Standard top-level memory contexts.
*
* Only TopMemoryContext and ErrorContext are initialized by
* MemoryContextInit() itself.
*/
extern DLLIMPORT MemoryContext TopMemoryContext;
extern DLLIMPORT MemoryContext ErrorContext;
extern DLLIMPORT MemoryContext PostmasterContext;
extern DLLIMPORT MemoryContext CacheMemoryContext;
extern DLLIMPORT MemoryContext QueryContext;
extern DLLIMPORT MemoryContext TopTransactionContext;
extern DLLIMPORT MemoryContext TransactionCommandContext;
/*
* Memory-context-type-independent functions in mcxt.c
*/
extern void MemoryContextInit(void);
extern void MemoryContextReset(MemoryContext context);
extern void MemoryContextDelete(MemoryContext context);
extern void MemoryContextResetChildren(MemoryContext context);
extern void MemoryContextDeleteChildren(MemoryContext context);
extern void MemoryContextResetAndDeleteChildren(MemoryContext context);
extern Size GetMemoryChunkSpace(void *pointer);
extern void MemoryContextStats(MemoryContext context);
2002-09-04 22:31:48 +02:00
#ifdef MEMORY_CONTEXT_CHECKING
Here is the patch with memory leak checker. This checker allow detect in-chunk leaks, overwrite-next-chunk leaks and overwrite block-freeptr leaks. A in-chunk leak --- if something overwrite space after wanted (via palloc() size, but it is still inside chunk. For example x = palloc(12); /* create 16b chunk */ memset(x, '#', 13); this leak is in the current source total invisible, because chunk is 16b and leak is in the "align space". For this feature I add data_size to StandardChunk, and all memory which go from AllocSetAlloc() is marked as 0x7F. The MemoryContextCheck() is compiled '#ifdef USE_ASSERT_CHECKING'. I add this checking to 'tcop/postgres.c' and is active after each backend query, but it is probably not sufficient, because some MemoryContext exist only during memory processing --- will good if someone who known where it is needful (Tom:-) add it for others contexts; A problem in the current source is that we have still some malloc() allocation that is not needful and this allocation is total invisible for all context routines. For example Dllist in backend (pretty dirty it is in catcache where values in Dllist are palloc-ed, but list is malloc-ed). --- and BTW. this Dllist design stand in the way for query cache :-) Tom, if you agree I start replace some mallocs. BTW. --- Tom, have you idea for across transaction presistent allocation for SQL functions? (like regex - now it is via malloc) I almost forget. I add one if() to AllocSetAlloc(), for 'size' that are greater than ALLOC_BIGCHUNK_LIMIT is not needful check AllocSetFreeIndex(), because 'fidx' is always 'ALLOCSET_NUM_FREELISTS - 1'. It a little brisk up allocation for very large chunks. Right? Karel
2000-07-11 16:30:37 +02:00
extern void MemoryContextCheck(MemoryContext context);
#endif
extern bool MemoryContextContains(MemoryContext context, void *pointer);
/*
* This routine handles the context-type-independent part of memory
* context creation. It's intended to be called from context-type-
* specific creation routines, and noplace else.
*/
extern MemoryContext MemoryContextCreate(NodeTag tag, Size size,
2001-03-22 05:01:46 +01:00
MemoryContextMethods *methods,
MemoryContext parent,
const char *name);
/*
* Memory-context-type-specific functions
*/
/* aset.c */
extern MemoryContext AllocSetContextCreate(MemoryContext parent,
2001-03-22 05:01:46 +01:00
const char *name,
Size minContextSize,
Size initBlockSize,
Size maxBlockSize);
/*
* Recommended default alloc parameters, suitable for "ordinary" contexts
* that might hold quite a lot of data.
*/
#define ALLOCSET_DEFAULT_MINSIZE (8 * 1024)
#define ALLOCSET_DEFAULT_INITSIZE (8 * 1024)
#define ALLOCSET_DEFAULT_MAXSIZE (8 * 1024 * 1024)
#endif /* MEMUTILS_H */