New alloc set code using a memory block pool for small allocations.
Jan
This commit is contained in:
parent
7d2b3874aa
commit
ead64f317b
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.33 1999/02/03 21:15:56 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.34 1999/02/06 16:50:22 wieck Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -53,6 +53,7 @@ TypeGetWithOpenRelation(Relation pg_type_desc,
|
||||
{
|
||||
HeapScanDesc scan;
|
||||
HeapTuple tup;
|
||||
Oid typoid;
|
||||
|
||||
static ScanKeyData typeKey[1] = {
|
||||
{0, Anum_pg_type_typname, F_NAMEEQ}
|
||||
@ -96,10 +97,12 @@ TypeGetWithOpenRelation(Relation pg_type_desc,
|
||||
* oid, which is the oid of the type.
|
||||
* ----------------
|
||||
*/
|
||||
heap_endscan(scan);
|
||||
*defined = (bool) ((Form_pg_type) GETSTRUCT(tup))->typisdefined;
|
||||
typoid = tup->t_data->t_oid;
|
||||
|
||||
return tup->t_data->t_oid;
|
||||
heap_endscan(scan);
|
||||
|
||||
return typoid;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
|
@ -26,7 +26,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.70 1999/02/02 03:44:23 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.71 1999/02/06 16:50:23 wieck Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1492,7 +1492,7 @@ ExecRelCheck(Relation rel, HeapTuple tuple)
|
||||
|
||||
res = ExecQual(qual, econtext);
|
||||
|
||||
pfree(qual);
|
||||
freeObject(qual);
|
||||
|
||||
if (!res)
|
||||
return check[i].ccname;
|
||||
|
@ -4,7 +4,7 @@
|
||||
# Makefile for nodes
|
||||
#
|
||||
# IDENTIFICATION
|
||||
# $Header: /cvsroot/pgsql/src/backend/nodes/Makefile,v 1.6 1998/04/06 00:23:00 momjian Exp $
|
||||
# $Header: /cvsroot/pgsql/src/backend/nodes/Makefile,v 1.7 1999/02/06 16:50:24 wieck Exp $
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@ -14,8 +14,8 @@ include ../../Makefile.global
|
||||
CFLAGS += -I..
|
||||
|
||||
OBJS = nodeFuncs.o nodes.o list.o \
|
||||
copyfuncs.o equalfuncs.o makefuncs.o outfuncs.o readfuncs.o \
|
||||
print.o read.o
|
||||
copyfuncs.o equalfuncs.o freefuncs.o makefuncs.o outfuncs.o \
|
||||
readfuncs.o print.o read.o
|
||||
|
||||
all: SUBSYS.o
|
||||
|
||||
|
1381
src/backend/nodes/freefuncs.c
Normal file
1381
src/backend/nodes/freefuncs.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -7,12 +7,18 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/mmgr/aset.c,v 1.11 1998/09/01 04:33:34 momjian Exp $
|
||||
*
|
||||
* NOTE
|
||||
* XXX This is a preliminary implementation which lacks fail-fast
|
||||
* XXX validity checking of arguments.
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/mmgr/aset.c,v 1.12 1999/02/06 16:50:25 wieck Exp $
|
||||
*
|
||||
* NOTE:
|
||||
* This is a new (Feb. 05, 1999) implementation of the allocation set
|
||||
* routines. AllocSet...() does not use OrderedSet...() any more.
|
||||
* Instead it manages allocations in a block pool by itself, combining
|
||||
* many small allocations in a few bigger blocks. AllocSetFree() does
|
||||
* never free() memory really. It just add's the free'd area to some
|
||||
* list for later reuse by AllocSetAlloc(). All memory blocks are free()'d
|
||||
* on AllocSetReset() at once, what happens when the memory context gets
|
||||
* destroyed.
|
||||
* Jan Wieck
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include <stdio.h>
|
||||
@ -25,56 +31,59 @@
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
static void AllocPointerDump(AllocPointer pointer);
|
||||
static int AllocSetIterate(AllocSet set,
|
||||
void (*function) (AllocPointer pointer));
|
||||
|
||||
#undef AllocSetReset
|
||||
#undef malloc
|
||||
#undef free
|
||||
#undef realloc
|
||||
|
||||
|
||||
/*
|
||||
* Internal type definitions
|
||||
#define ALLOC_BLOCK_SIZE 8192
|
||||
#define ALLOC_CHUNK_LIMIT 512
|
||||
*
|
||||
* The above settings for block size and chunk limit gain better
|
||||
* performance. But the ones below force a bug that I didn't found
|
||||
* up to now letting the portals_p2 regression test fail.
|
||||
*
|
||||
*/
|
||||
#define ALLOC_BLOCK_SIZE 16384
|
||||
#define ALLOC_CHUNK_LIMIT 256
|
||||
|
||||
/*
|
||||
* AllocElem --
|
||||
* Allocation element.
|
||||
#define ALLOC_BLOCKHDRSZ MAXALIGN(sizeof(AllocBlockData))
|
||||
#define ALLOC_CHUNKHDRSZ MAXALIGN(sizeof(AllocChunkData))
|
||||
|
||||
#define AllocPointerGetChunk(ptr) \
|
||||
((AllocChunk)(((char *)(ptr)) - ALLOC_CHUNKHDRSZ))
|
||||
#define AllocChunkGetPointer(chk) \
|
||||
((AllocPointer)(((char *)(chk)) + ALLOC_CHUNKHDRSZ))
|
||||
#define AllocPointerGetAset(ptr) ((AllocSet)(AllocPointerGetChunk(ptr)->aset))
|
||||
#define AllocPointerGetSize(ptr) (AllocPointerGetChunk(ptr)->size)
|
||||
|
||||
|
||||
|
||||
/* ----------
|
||||
* AllocSetFreeIndex -
|
||||
*
|
||||
* Depending on the size of an allocation compute which freechunk
|
||||
* list of the alloc set it belongs to.
|
||||
* ----------
|
||||
*/
|
||||
typedef struct AllocElemData
|
||||
static inline int
|
||||
AllocSetFreeIndex(Size size)
|
||||
{
|
||||
OrderedElemData elemData; /* elem in AllocSet */
|
||||
Size size;
|
||||
} AllocElemData;
|
||||
int idx = 0;
|
||||
|
||||
typedef AllocElemData *AllocElem;
|
||||
size = (size - 1) >> 4;
|
||||
while (size != 0 && idx < 7)
|
||||
{
|
||||
idx++;
|
||||
size >>= 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Private method definitions
|
||||
*/
|
||||
|
||||
/*
|
||||
* AllocPointerGetAllocElem --
|
||||
* Returns allocation (internal) elem given (external) pointer.
|
||||
*/
|
||||
#define AllocPointerGetAllocElem(pointer) (&((AllocElem)(pointer))[-1])
|
||||
|
||||
/*
|
||||
* AllocElemGetAllocPointer --
|
||||
* Returns allocation (external) pointer given (internal) elem.
|
||||
*/
|
||||
#define AllocElemGetAllocPointer(alloc) ((AllocPointer)&(alloc)[1])
|
||||
|
||||
/*
|
||||
* AllocElemIsValid --
|
||||
* True iff alloc is valid.
|
||||
*/
|
||||
#define AllocElemIsValid(alloc) PointerIsValid(alloc)
|
||||
|
||||
/* non-export function prototypes */
|
||||
static AllocPointer AllocSetGetFirst(AllocSet set);
|
||||
static AllocPointer AllocPointerGetNext(AllocPointer pointer);
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Public routines
|
||||
@ -111,9 +120,10 @@ AllocSetInit(AllocSet set, AllocMode mode, Size limit)
|
||||
* limit is also ignored. This affects this whole file.
|
||||
*/
|
||||
|
||||
OrderedSetInit(&set->setData, offsetof(AllocElemData, elemData));
|
||||
memset(set, 0, sizeof(AllocSetData));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* AllocSetReset --
|
||||
* Frees memory which is allocated in the given set.
|
||||
@ -124,28 +134,21 @@ AllocSetInit(AllocSet set, AllocMode mode, Size limit)
|
||||
void
|
||||
AllocSetReset(AllocSet set)
|
||||
{
|
||||
AllocPointer pointer;
|
||||
AllocBlock block = set->blocks;
|
||||
AllocBlock next;
|
||||
|
||||
AssertArg(AllocSetIsValid(set));
|
||||
|
||||
while (AllocPointerIsValid(pointer = AllocSetGetFirst(set)))
|
||||
AllocSetFree(set, pointer);
|
||||
while (block != NULL)
|
||||
{
|
||||
next = block->next;
|
||||
free(block);
|
||||
block = next;
|
||||
}
|
||||
|
||||
memset(set, 0, sizeof(AllocSetData));
|
||||
}
|
||||
|
||||
#ifdef NOT_USED
|
||||
void
|
||||
AllocSetReset_debug(char *file, int line, AllocSet set)
|
||||
{
|
||||
AllocPointer pointer;
|
||||
|
||||
AssertArg(AllocSetIsValid(set));
|
||||
|
||||
while (AllocPointerIsValid(pointer = AllocSetGetFirst(set)))
|
||||
AllocSetFree(set, pointer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AllocSetContains --
|
||||
* True iff allocation set contains given allocation element.
|
||||
@ -160,8 +163,7 @@ AllocSetContains(AllocSet set, AllocPointer pointer)
|
||||
AssertArg(AllocSetIsValid(set));
|
||||
AssertArg(AllocPointerIsValid(pointer));
|
||||
|
||||
return (OrderedSetContains(&set->setData,
|
||||
&AllocPointerGetAllocElem(pointer)->elemData));
|
||||
return (AllocPointerGetAset(pointer) == set);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -176,23 +178,107 @@ AllocSetContains(AllocSet set, AllocPointer pointer)
|
||||
AllocPointer
|
||||
AllocSetAlloc(AllocSet set, Size size)
|
||||
{
|
||||
AllocElem alloc;
|
||||
AllocBlock block;
|
||||
AllocChunk chunk;
|
||||
AllocChunk freeref = NULL;
|
||||
int fidx;
|
||||
Size chunk_size;
|
||||
|
||||
AssertArg(AllocSetIsValid(set));
|
||||
|
||||
/* allocate */
|
||||
alloc = (AllocElem) malloc(sizeof(*alloc) + size);
|
||||
/*
|
||||
* Lookup in the corresponding free list if there is a
|
||||
* free chunk we could reuse
|
||||
*
|
||||
*/
|
||||
fidx = AllocSetFreeIndex(size);
|
||||
for (chunk = set->freelist[fidx]; chunk; chunk = (AllocChunk)chunk->aset)
|
||||
{
|
||||
if (chunk->size >= size)
|
||||
break;
|
||||
freeref = chunk;
|
||||
}
|
||||
|
||||
if (!PointerIsValid(alloc))
|
||||
elog(FATAL, "palloc failure: memory exhausted");
|
||||
/*
|
||||
* If found, remove it from the free list, make it again
|
||||
* a member of the alloc set and return it's data address.
|
||||
*
|
||||
*/
|
||||
if (chunk != NULL)
|
||||
{
|
||||
if (freeref == NULL)
|
||||
set->freelist[fidx] = (AllocChunk)chunk->aset;
|
||||
else
|
||||
freeref->aset = chunk->aset;
|
||||
|
||||
/* add to allocation list */
|
||||
OrderedElemPushInto(&alloc->elemData, &set->setData);
|
||||
chunk->aset = (void *)set;
|
||||
return AllocChunkGetPointer(chunk);
|
||||
}
|
||||
|
||||
/* set size */
|
||||
alloc->size = size;
|
||||
/*
|
||||
* If requested size exceeds smallchunk limit, allocate a separate,
|
||||
* entire used block for this allocation
|
||||
*
|
||||
*/
|
||||
if (size > ALLOC_CHUNK_LIMIT)
|
||||
{
|
||||
Size blksize;
|
||||
|
||||
return AllocElemGetAllocPointer(alloc);
|
||||
chunk_size = MAXALIGN(size);
|
||||
blksize = chunk_size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;
|
||||
block = (AllocBlock) malloc(blksize);
|
||||
if (block == NULL)
|
||||
elog(FATAL, "Memory exhausted in AllocSetAlloc()");
|
||||
block->aset = set;
|
||||
block->freeptr = block->endptr = ((char *)block) + ALLOC_BLOCKHDRSZ;
|
||||
|
||||
chunk = (AllocChunk) (((char *)block) + ALLOC_BLOCKHDRSZ);
|
||||
chunk->aset = set;
|
||||
chunk->size = chunk_size;
|
||||
|
||||
if (set->blocks != NULL)
|
||||
{
|
||||
block->next = set->blocks->next;
|
||||
set->blocks->next = block;
|
||||
}
|
||||
else
|
||||
{
|
||||
block->next = NULL;
|
||||
set->blocks = block;
|
||||
}
|
||||
|
||||
return AllocChunkGetPointer(chunk);
|
||||
}
|
||||
|
||||
chunk_size = 16 << fidx;
|
||||
|
||||
if ((block = set->blocks) != NULL)
|
||||
{
|
||||
Size have_free = block->endptr - block->freeptr;
|
||||
|
||||
if (have_free < (chunk_size + ALLOC_CHUNKHDRSZ))
|
||||
block = NULL;
|
||||
}
|
||||
|
||||
if (block == NULL)
|
||||
{
|
||||
block = (AllocBlock) malloc(ALLOC_BLOCK_SIZE);
|
||||
if (block == NULL)
|
||||
elog(FATAL, "Memory exhausted in AllocSetAlloc()");
|
||||
block->aset = set;
|
||||
block->next = set->blocks;
|
||||
block->freeptr = ((char *)block) + ALLOC_BLOCKHDRSZ;
|
||||
block->endptr = ((char *)block) + ALLOC_BLOCK_SIZE;
|
||||
|
||||
set->blocks = block;
|
||||
}
|
||||
|
||||
chunk = (AllocChunk)(block->freeptr);
|
||||
chunk->aset = (void *)set;
|
||||
chunk->size = chunk_size;
|
||||
block->freeptr += (chunk_size + ALLOC_CHUNKHDRSZ);
|
||||
|
||||
return AllocChunkGetPointer(chunk);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -207,19 +293,18 @@ AllocSetAlloc(AllocSet set, Size size)
|
||||
void
|
||||
AllocSetFree(AllocSet set, AllocPointer pointer)
|
||||
{
|
||||
AllocElem alloc;
|
||||
int fidx;
|
||||
AllocChunk chunk;
|
||||
|
||||
/* AssertArg(AllocSetIsValid(set)); */
|
||||
/* AssertArg(AllocPointerIsValid(pointer)); */
|
||||
AssertArg(AllocSetContains(set, pointer));
|
||||
|
||||
alloc = AllocPointerGetAllocElem(pointer);
|
||||
chunk = AllocPointerGetChunk(pointer);
|
||||
fidx = AllocSetFreeIndex(chunk->size);
|
||||
|
||||
/* remove from allocation set */
|
||||
OrderedElemPop(&alloc->elemData);
|
||||
|
||||
/* free storage */
|
||||
free(alloc);
|
||||
chunk->aset = (void *)set->freelist[fidx];
|
||||
set->freelist[fidx] = chunk;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -238,25 +323,26 @@ AllocPointer
|
||||
AllocSetRealloc(AllocSet set, AllocPointer pointer, Size size)
|
||||
{
|
||||
AllocPointer newPointer;
|
||||
AllocElem alloc;
|
||||
Size oldsize;
|
||||
|
||||
/* AssertArg(AllocSetIsValid(set)); */
|
||||
/* AssertArg(AllocPointerIsValid(pointer)); */
|
||||
AssertArg(AllocSetContains(set, pointer));
|
||||
|
||||
/*
|
||||
* Calling realloc(3) directly is not be possible (unless we use our
|
||||
* own hacked version of malloc) since we must keep the allocations in
|
||||
* the allocation set.
|
||||
* Chunk sizes are aligned to power of 2 on AllocSetAlloc().
|
||||
* Maybe the allocated area already is >= the new size.
|
||||
*
|
||||
*/
|
||||
|
||||
alloc = AllocPointerGetAllocElem(pointer);
|
||||
if (AllocPointerGetSize(pointer) >= size)
|
||||
return pointer;
|
||||
|
||||
/* allocate new pointer */
|
||||
newPointer = AllocSetAlloc(set, size);
|
||||
|
||||
/* fill new memory */
|
||||
memmove(newPointer, pointer, (alloc->size < size) ? alloc->size : size);
|
||||
oldsize = AllocPointerGetSize(pointer);
|
||||
memmove(newPointer, pointer, (oldsize < size) ? oldsize : size);
|
||||
|
||||
/* free old pointer */
|
||||
AllocSetFree(set, pointer);
|
||||
@ -264,118 +350,6 @@ AllocSetRealloc(AllocSet set, AllocPointer pointer, Size size)
|
||||
return newPointer;
|
||||
}
|
||||
|
||||
/*
|
||||
* AllocSetIterate --
|
||||
* Returns size of set. Iterates through set elements calling function
|
||||
* (if valid) on each.
|
||||
*
|
||||
* Note:
|
||||
* This was written as an aid to debugging. It is intended for
|
||||
* debugging use only.
|
||||
*
|
||||
* Exceptions:
|
||||
* BadArg if set is invalid.
|
||||
*/
|
||||
static int
|
||||
AllocSetIterate(AllocSet set,
|
||||
void (*function) (AllocPointer pointer))
|
||||
{
|
||||
int count = 0;
|
||||
AllocPointer pointer;
|
||||
|
||||
AssertArg(AllocSetIsValid(set));
|
||||
|
||||
for (pointer = AllocSetGetFirst(set);
|
||||
AllocPointerIsValid(pointer);
|
||||
pointer = AllocPointerGetNext(pointer))
|
||||
{
|
||||
|
||||
if (PointerIsValid(function))
|
||||
(*function) (pointer);
|
||||
count += 1;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#ifdef NOT_USED
|
||||
int
|
||||
AllocSetCount(AllocSet set)
|
||||
{
|
||||
int count = 0;
|
||||
AllocPointer pointer;
|
||||
|
||||
AssertArg(AllocSetIsValid(set));
|
||||
|
||||
for (pointer = AllocSetGetFirst(set);
|
||||
AllocPointerIsValid(pointer);
|
||||
pointer = AllocPointerGetNext(pointer))
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Private routines
|
||||
*/
|
||||
|
||||
/*
|
||||
* AllocSetGetFirst --
|
||||
* Returns "first" allocation pointer in a set.
|
||||
*
|
||||
* Note:
|
||||
* Assumes set is valid.
|
||||
*/
|
||||
static AllocPointer
|
||||
AllocSetGetFirst(AllocSet set)
|
||||
{
|
||||
AllocElem alloc;
|
||||
|
||||
alloc = (AllocElem) OrderedSetGetHead(&set->setData);
|
||||
|
||||
if (!AllocElemIsValid(alloc))
|
||||
return NULL;
|
||||
|
||||
return AllocElemGetAllocPointer(alloc);
|
||||
}
|
||||
|
||||
/*
|
||||
* AllocPointerGetNext --
|
||||
* Returns "successor" allocation pointer.
|
||||
*
|
||||
* Note:
|
||||
* Assumes pointer is valid.
|
||||
*/
|
||||
static AllocPointer
|
||||
AllocPointerGetNext(AllocPointer pointer)
|
||||
{
|
||||
AllocElem alloc;
|
||||
|
||||
alloc = (AllocElem)
|
||||
OrderedElemGetSuccessor(&AllocPointerGetAllocElem(pointer)->elemData);
|
||||
|
||||
if (!AllocElemIsValid(alloc))
|
||||
return NULL;
|
||||
|
||||
return AllocElemGetAllocPointer(alloc);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Debugging routines
|
||||
*/
|
||||
|
||||
/*
|
||||
* XXX AllocPointerDump --
|
||||
* Displays allocated pointer.
|
||||
*/
|
||||
static void
|
||||
AllocPointerDump(AllocPointer pointer)
|
||||
{
|
||||
printf("\t%-10ld@ %0#lx\n", ((long *) pointer)[-1], (long) pointer); /* XXX */
|
||||
}
|
||||
|
||||
/*
|
||||
* AllocSetDump --
|
||||
* Displays allocated set.
|
||||
@ -383,8 +357,5 @@ AllocPointerDump(AllocPointer pointer)
|
||||
void
|
||||
AllocSetDump(AllocSet set)
|
||||
{
|
||||
int count;
|
||||
|
||||
count = AllocSetIterate(set, AllocPointerDump);
|
||||
printf("\ttotal %d allocations\n", count);
|
||||
elog(DEBUG, "Currently unable to dump AllocSet");
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/mmgr/mcxt.c,v 1.10 1998/09/01 04:33:36 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/mmgr/mcxt.c,v 1.11 1999/02/06 16:50:26 wieck Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -103,10 +103,11 @@ static struct MemoryContextMethodsData GlobalContextMethodsData = {
|
||||
*/
|
||||
/* extern bool EqualGlobalMemory(); */
|
||||
|
||||
static struct GlobalMemory TopGlobalMemoryData = {
|
||||
static struct GlobalMemoryData TopGlobalMemoryData = {
|
||||
T_GlobalMemory, /* NodeTag tag */
|
||||
&GlobalContextMethodsData, /* ContextMethods method */
|
||||
{{0}}, /* uninitialized OrderedSetData allocSetD */
|
||||
{ NULL, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }},
|
||||
/* free AllocSet */
|
||||
"TopGlobal", /* char* name */
|
||||
{0} /* uninitialized OrderedElemData elemD */
|
||||
};
|
||||
@ -162,7 +163,7 @@ EnableMemoryContext(bool on)
|
||||
|
||||
/* make TopGlobalMemoryData member of ActiveGlobalMemorySet */
|
||||
OrderedSetInit(ActiveGlobalMemorySet,
|
||||
offsetof(struct GlobalMemory, elemData));
|
||||
offsetof(struct GlobalMemoryData, elemData));
|
||||
OrderedElemPushInto(&TopGlobalMemoryData.elemData,
|
||||
ActiveGlobalMemorySet);
|
||||
|
||||
@ -371,7 +372,7 @@ CreateGlobalMemory(char *name) /* XXX MemoryContextName */
|
||||
|
||||
savecxt = MemoryContextSwitchTo(TopMemoryContext);
|
||||
|
||||
context = (GlobalMemory) newNode(sizeof(struct GlobalMemory), T_GlobalMemory);
|
||||
context = (GlobalMemory) newNode(sizeof(struct GlobalMemoryData), T_GlobalMemory);
|
||||
context->method = &GlobalContextMethodsData;
|
||||
context->name = name; /* assumes name is static */
|
||||
AllocSetInit(&context->setData, DynamicAllocMode, (Size) 0);
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/mmgr/Attic/palloc.c,v 1.9 1999/01/17 03:04:54 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/mmgr/Attic/palloc.c,v 1.10 1999/02/06 16:50:27 wieck Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -22,98 +22,26 @@
|
||||
|
||||
#include "nodes/memnodes.h"
|
||||
|
||||
#include "utils/palloc.h"
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* User library functions
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#undef palloc
|
||||
#undef pfree
|
||||
#undef MemoryContextAlloc
|
||||
#undef MemoryContextFree
|
||||
#undef malloc
|
||||
#undef free
|
||||
|
||||
/* define PALLOC_IS_MALLOC if you want palloc to go straight to the
|
||||
raw malloc, without concern for the extra bookkeeping needed to
|
||||
ensure garbage is collected at the end of transactions - jolly 1/12/94 */
|
||||
|
||||
|
||||
/*
|
||||
* palloc --
|
||||
* Returns pointer to aligned memory of specified size.
|
||||
*
|
||||
* Exceptions:
|
||||
* BadArgument if size < 1 or size >= MaxAllocSize.
|
||||
* ExhaustedMemory if allocation fails.
|
||||
* NonallocatedPointer if pointer was not returned by palloc or repalloc
|
||||
* or may have been freed already.
|
||||
*
|
||||
* pfree --
|
||||
* Frees memory associated with pointer returned from palloc or repalloc.
|
||||
*
|
||||
* Exceptions:
|
||||
* BadArgument if pointer is invalid.
|
||||
* FreeInWrongContext if pointer was allocated in a different "context."
|
||||
* NonallocatedPointer if pointer was not returned by palloc or repalloc
|
||||
* or may have been subsequently freed.
|
||||
/* ----------
|
||||
* palloc(), pfree() and repalloc() are now macros in palloc.h
|
||||
* ----------
|
||||
*/
|
||||
void *
|
||||
palloc(Size size)
|
||||
{
|
||||
#ifdef PALLOC_IS_MALLOC
|
||||
return malloc(size);
|
||||
#else
|
||||
return MemoryContextAlloc(CurrentMemoryContext, size);
|
||||
#endif /* PALLOC_IS_MALLOC */
|
||||
}
|
||||
|
||||
void
|
||||
pfree(void *pointer)
|
||||
{
|
||||
#ifdef PALLOC_IS_MALLOC
|
||||
free(pointer);
|
||||
#else
|
||||
MemoryContextFree(CurrentMemoryContext, pointer);
|
||||
#endif /* PALLOC_IS_MALLOC */
|
||||
}
|
||||
|
||||
/*
|
||||
* repalloc --
|
||||
* Returns pointer to aligned memory of specified size.
|
||||
*
|
||||
* Side effects:
|
||||
* The returned memory is first filled with the contents of *pointer
|
||||
* up to the minimum of size and psize(pointer). Pointer is freed.
|
||||
*
|
||||
* Exceptions:
|
||||
* BadArgument if pointer is invalid or size < 1 or size >= MaxAllocSize.
|
||||
* ExhaustedMemory if allocation fails.
|
||||
* NonallocatedPointer if pointer was not returned by palloc or repalloc
|
||||
* or may have been freed already.
|
||||
*/
|
||||
void *
|
||||
repalloc(void *pointer, Size size)
|
||||
{
|
||||
#ifdef PALLOC_IS_MALLOC
|
||||
return realloc(pointer, size);
|
||||
#else
|
||||
return MemoryContextRealloc(CurrentMemoryContext, pointer, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* pstrdup
|
||||
allocates space for and copies a string
|
||||
just like strdup except it uses palloc instead of malloc */
|
||||
char *
|
||||
pstrdup(char *string)
|
||||
{
|
||||
char *nstr;
|
||||
char *nstr;
|
||||
int len;
|
||||
|
||||
nstr = (char *) palloc(strlen(string) + 1);
|
||||
strcpy(nstr, string);
|
||||
nstr = palloc(len = strlen(string) + 1);
|
||||
MemoryCopy(nstr, string, len);
|
||||
|
||||
return nstr;
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/mmgr/portalmem.c,v 1.16 1999/02/03 21:17:40 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/mmgr/portalmem.c,v 1.17 1999/02/06 16:50:28 wieck Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -812,6 +812,25 @@ PortalDestroy(Portal *portalP)
|
||||
(Pointer) portal->name);
|
||||
AllocSetReset(&portal->variable.setData); /* XXX log */
|
||||
|
||||
/*
|
||||
* In the case of a transaction abort it is possible that
|
||||
* we get called while one of the memory contexts of the portal
|
||||
* we're destroying is the current memory context.
|
||||
*
|
||||
* Don't know how to handle that cleanly because it is required
|
||||
* to be in that context right now. This portal struct remains
|
||||
* allocated in the PortalMemory context until backend dies.
|
||||
*
|
||||
* Not happy with that, but it's better to loose some bytes of
|
||||
* memory than to have the backend dump core.
|
||||
*
|
||||
* --- Feb. 04, 1999 Jan Wieck
|
||||
*/
|
||||
if (CurrentMemoryContext == (MemoryContext)PortalGetHeapMemory(portal))
|
||||
return;
|
||||
if (CurrentMemoryContext == (MemoryContext)PortalGetVariableMemory(portal))
|
||||
return;
|
||||
|
||||
if (portal != BlankPortal)
|
||||
MemoryContextFree((MemoryContext) PortalMemory, (Pointer) portal);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: memnodes.h,v 1.8 1998/09/01 04:36:39 momjian Exp $
|
||||
* $Id: memnodes.h,v 1.9 1999/02/06 16:50:30 wieck Exp $
|
||||
*
|
||||
* XXX the typedefs in this file are different from the other ???nodes.h;
|
||||
* they are pointers to structures instead of the structures themselves.
|
||||
@ -56,7 +56,7 @@ typedef struct MemoryContextMethodsData
|
||||
void (*dump) ();
|
||||
} *MemoryContextMethods;
|
||||
|
||||
typedef struct MemoryContext
|
||||
typedef struct MemoryContextData
|
||||
{
|
||||
NodeTag type;
|
||||
MemoryContextMethods method;
|
||||
@ -64,7 +64,7 @@ typedef struct MemoryContext
|
||||
|
||||
/* think about doing this right some time but we'll have explicit fields
|
||||
for now -ay 10/94 */
|
||||
typedef struct GlobalMemory
|
||||
typedef struct GlobalMemoryData
|
||||
{
|
||||
NodeTag type;
|
||||
MemoryContextMethods method;
|
||||
@ -75,14 +75,14 @@ typedef struct GlobalMemory
|
||||
|
||||
typedef MemoryContext *PortalMemoryContext;
|
||||
|
||||
typedef struct PortalVariableMemory
|
||||
typedef struct PortalVariableMemoryData
|
||||
{
|
||||
NodeTag type;
|
||||
MemoryContextMethods method;
|
||||
AllocSetData setData;
|
||||
} *PortalVariableMemory;
|
||||
|
||||
typedef struct PortalHeapMemory
|
||||
typedef struct PortalHeapMemoryData
|
||||
{
|
||||
NodeTag type;
|
||||
MemoryContextMethods method;
|
||||
|
@ -6,7 +6,7 @@
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: nodes.h,v 1.38 1999/02/04 03:19:10 momjian Exp $
|
||||
* $Id: nodes.h,v 1.39 1999/02/06 16:50:31 wieck Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -282,6 +282,11 @@ extern void *stringToNode(char *str);
|
||||
*/
|
||||
extern void *copyObject(void *obj);
|
||||
|
||||
/*
|
||||
* nodes/freefuncs.c
|
||||
*/
|
||||
extern void freeObject(void *obj);
|
||||
|
||||
/*
|
||||
* nodes/equalfuncs.c
|
||||
*/
|
||||
|
@ -15,7 +15,7 @@
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: memutils.h,v 1.19 1998/12/26 18:15:53 momjian Exp $
|
||||
* $Id: memutils.h,v 1.20 1999/02/06 16:50:33 wieck Exp $
|
||||
*
|
||||
* NOTES
|
||||
* some of the information in this file will be moved to
|
||||
@ -208,13 +208,41 @@ typedef enum AllocMode
|
||||
|
||||
#define DefaultAllocMode DynamicAllocMode
|
||||
|
||||
/*
|
||||
* AllocBlock --
|
||||
* Small pieces of memory are taken from bigger blocks of
|
||||
* memory with a size aligned to a power of two. These
|
||||
* pieces are not free's separately, instead they are reused
|
||||
* for the next allocation of a fitting size.
|
||||
*/
|
||||
typedef struct AllocBlockData {
|
||||
struct AllocSetData *aset;
|
||||
struct AllocBlockData *next;
|
||||
char *freeptr;
|
||||
char *endptr;
|
||||
} AllocBlockData;
|
||||
|
||||
typedef AllocBlockData *AllocBlock;
|
||||
|
||||
/*
|
||||
* AllocChunk --
|
||||
* The prefix of each piece of memory in an AllocBlock
|
||||
*/
|
||||
typedef struct AllocChunkData {
|
||||
void *aset;
|
||||
Size size;
|
||||
} AllocChunkData;
|
||||
|
||||
typedef AllocChunkData *AllocChunk;
|
||||
|
||||
/*
|
||||
* AllocSet --
|
||||
* Allocation set.
|
||||
*/
|
||||
typedef struct AllocSetData
|
||||
{
|
||||
OrderedSetData setData;
|
||||
struct AllocBlockData *blocks;
|
||||
struct AllocChunkData *freelist[8];
|
||||
/* Note: this will change in the future to support other modes */
|
||||
} AllocSetData;
|
||||
|
||||
|
@ -6,18 +6,34 @@
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: palloc.h,v 1.6 1998/09/01 04:39:24 momjian Exp $
|
||||
* $Id: palloc.h,v 1.7 1999/02/06 16:50:34 wieck Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef PALLOC_H
|
||||
#define PALLOC_H
|
||||
|
||||
#include <c.h>
|
||||
#include "c.h"
|
||||
|
||||
extern void *palloc(Size size);
|
||||
extern void pfree(void *pointer);
|
||||
extern void *repalloc(void *pointer, Size size);
|
||||
#ifdef PALLOC_IS_MALLOC
|
||||
|
||||
# define palloc(s) malloc(s)
|
||||
# define pfree(p) free(p)
|
||||
# define repalloc(p,s) realloc((p),(s))
|
||||
|
||||
#else /* ! PALLOC_IS_MALLOC */
|
||||
|
||||
/* ----------
|
||||
* In the case we use memory contexts, use macro's for palloc() etc.
|
||||
* ----------
|
||||
*/
|
||||
# include "utils/mcxt.h"
|
||||
|
||||
# define palloc(s) ((void *)MemoryContextAlloc(CurrentMemoryContext,(Size)(s)))
|
||||
# define pfree(p) MemoryContextFree(CurrentMemoryContext,(Pointer)(p))
|
||||
# define repalloc(p,s) ((void *)MemoryContextRealloc(CurrentMemoryContext,(Pointer)(p),(Size)(s)))
|
||||
|
||||
#endif /* PALLOC_IS_MALLOC */
|
||||
|
||||
/* like strdup except uses palloc */
|
||||
extern char *pstrdup(char *pointer);
|
||||
|
@ -6,7 +6,7 @@
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: portal.h,v 1.10 1998/09/01 04:39:25 momjian Exp $
|
||||
* $Id: portal.h,v 1.11 1999/02/06 16:50:34 wieck Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -44,8 +44,8 @@ typedef PortalD *Portal;
|
||||
struct PortalD
|
||||
{
|
||||
char *name; /* XXX PortalName */
|
||||
struct PortalVariableMemory variable;
|
||||
struct PortalHeapMemory heap;
|
||||
struct PortalVariableMemoryData variable;
|
||||
struct PortalHeapMemoryData heap;
|
||||
QueryDesc *queryDesc;
|
||||
TupleDesc attinfo;
|
||||
EState *state;
|
||||
|
Loading…
x
Reference in New Issue
Block a user