mirror of
https://github.com/postgres/postgres.git
synced 2025-11-21 00:42:43 +03:00
Postgres95 1.01 Distribution - Virgin Sources
This commit is contained in:
381
src/backend/utils/mmgr/aset.c
Normal file
381
src/backend/utils/mmgr/aset.c
Normal file
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user