diff options
Diffstat (limited to 'src/backend/utils/mmgr/aset.c')
-rw-r--r-- | src/backend/utils/mmgr/aset.c | 381 |
1 files changed, 381 insertions, 0 deletions
diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c new file mode 100644 index 00000000000..bbb7cd66f20 --- /dev/null +++ b/src/backend/utils/mmgr/aset.c @@ -0,0 +1,381 @@ +/*------------------------------------------------------------------------- + * + * aset.c-- + * Allocation set definitions. + * + * Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/aset.c,v 1.1.1.1 1996/07/09 06:22:09 scrappy Exp $ + * + * NOTE + * XXX This is a preliminary implementation which lacks fail-fast + * XXX validity checking of arguments. + * + *------------------------------------------------------------------------- + */ +#include <stdio.h> +#include "c.h" +#include "utils/excid.h" /* for ExhaustedMemory */ +#include "utils/memutils.h" /* where funnction declarations go */ +#include "utils/elog.h" +#include "utils/palloc.h" + +#undef AllocSetReset +#undef malloc +#undef free + +/* + * Internal type definitions + */ + +/* + * AllocElem -- + * Allocation element. + */ +typedef struct AllocElemData { + OrderedElemData elemData; /* elem in AllocSet */ + Size size; +} AllocElemData; + +typedef AllocElemData *AllocElem; + + +/* + * 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); + +/* + * Public routines + */ + +/* + * AllocPointerIsValid(pointer) + * AllocSetIsValid(set) + * + * .. are now macros in aset.h -cim 4/27/91 + */ + +/* + * AllocSetInit -- + * Initializes given allocation set. + * + * Note: + * The semantics of the mode are explained above. Limit is ignored + * for dynamic and static modes. + * + * Exceptions: + * BadArg if set is invalid pointer. + * BadArg if mode is invalid. + */ +void +AllocSetInit(AllocSet set, AllocMode mode, Size limit) +{ + AssertArg(PointerIsValid(set)); + AssertArg((int)DynamicAllocMode <= (int)mode); + AssertArg((int)mode <= (int)BoundedAllocMode); + + /* + * XXX mode is currently ignored and treated as DynamicAllocMode. + * XXX limit is also ignored. This affects this whole file. + */ + + OrderedSetInit(&set->setData, offsetof(AllocElemData, elemData)); +} + +/* + * AllocSetReset -- + * Frees memory which is allocated in the given set. + * + * Exceptions: + * BadArg if set is invalid. + */ +void +AllocSetReset(AllocSet set) +{ + AllocPointer pointer; + + AssertArg(AllocSetIsValid(set)); + + while (AllocPointerIsValid(pointer = AllocSetGetFirst(set))) { + AllocSetFree(set, pointer); + } +} + +void +AllocSetReset_debug(char *file, int line, AllocSet set) +{ + AllocPointer pointer; + + AssertArg(AllocSetIsValid(set)); + + while (AllocPointerIsValid(pointer = AllocSetGetFirst(set))) { + AllocSetFree(set, pointer); + } +} + +/* + * AllocSetContains -- + * True iff allocation set contains given allocation element. + * + * Exceptions: + * BadArg if set is invalid. + * BadArg if pointer is invalid. + */ +bool +AllocSetContains(AllocSet set, AllocPointer pointer) +{ + AssertArg(AllocSetIsValid(set)); + AssertArg(AllocPointerIsValid(pointer)); + + return (OrderedSetContains(&set->setData, + &AllocPointerGetAllocElem(pointer)->elemData)); +} + +/* + * AllocSetAlloc -- + * Returns pointer to allocated memory of given size; memory is added + * to the set. + * + * Exceptions: + * BadArg if set is invalid. + * MemoryExhausted if allocation fails. + */ +AllocPointer +AllocSetAlloc(AllocSet set, Size size) +{ + AllocElem alloc; + + AssertArg(AllocSetIsValid(set)); + + /* allocate */ + alloc = (AllocElem)malloc(sizeof (*alloc) + size); + + if (!PointerIsValid(alloc)) { + elog (FATAL, "palloc failure: memory exhausted"); + } + + /* add to allocation list */ + OrderedElemPushInto(&alloc->elemData, &set->setData); + + /* set size */ + alloc->size = size; + + return (AllocElemGetAllocPointer(alloc)); +} + +/* + * AllocSetFree -- + * Frees allocated memory; memory is removed from the set. + * + * Exceptions: + * BadArg if set is invalid. + * BadArg if pointer is invalid. + * BadArg if pointer is not member of set. + */ +void +AllocSetFree(AllocSet set, AllocPointer pointer) +{ + AllocElem alloc; + + /* AssertArg(AllocSetIsValid(set)); */ + /* AssertArg(AllocPointerIsValid(pointer)); */ + AssertArg(AllocSetContains(set, pointer)); + + alloc = AllocPointerGetAllocElem(pointer); + + /* remove from allocation set */ + OrderedElemPop(&alloc->elemData); + + /* free storage */ + free(alloc); +} + +/* + * AllocSetRealloc -- + * Returns new pointer to allocated memory of given size; this memory + * is added to the set. Memory associated with given pointer is copied + * into the new memory, and the old memory is freed. + * + * Exceptions: + * BadArg if set is invalid. + * BadArg if pointer is invalid. + * BadArg if pointer is not member of set. + * MemoryExhausted if allocation fails. + */ +AllocPointer +AllocSetRealloc(AllocSet set, AllocPointer pointer, Size size) +{ + AllocPointer newPointer; + AllocElem alloc; + + /* 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. + */ + + alloc = AllocPointerGetAllocElem(pointer); + + /* allocate new pointer */ + newPointer = AllocSetAlloc(set, size); + + /* fill new memory */ + memmove(newPointer, pointer, (alloc->size < size) ? alloc->size : size); + + /* free old pointer */ + AllocSetFree(set, pointer); + + 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. + */ +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); +} + +int +AllocSetCount(AllocSet set) +{ + int count = 0; + AllocPointer pointer; + + AssertArg(AllocSetIsValid(set)); + + for (pointer = AllocSetGetFirst(set); + AllocPointerIsValid(pointer); + pointer = AllocPointerGetNext(pointer)) { + count++; + } + return count; +} + +/* + * 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. + */ +void +AllocPointerDump(AllocPointer pointer) +{ + printf("\t%-10d@ %0#x\n", ((long*)pointer)[-1], pointer); /* XXX */ +} + +/* + * AllocSetDump -- + * Displays allocated set. + */ +void +AllocSetDump(AllocSet set) +{ + int count; + count = AllocSetIterate(set, AllocPointerDump); + printf("\ttotal %d allocations\n", count); +} |