/* fixedalloc.c
simple allocator for allocate once and pools
L. Stewart, March 6, 1983 2:55 PM, created
L. Stewart, March 9, 1983 7:50 PM, Zero allocated space
L. Stewart, March 10, 1983 11:59 AM, round up
*/
#include "env.h"
#include "ec.h"
#include "Queue.h"
#define memTop 0xCFFE
struct Pool {
struct Queue freeList;
int owner;
int numItems;
int lenItem;
};
#define lenPool (sizeof(struct Pool) / 2)
struct GFOb {
int owner;
int owner2;
int length;
int data[1];
};
#define lenGFOb 3
extern int end; /* See endml.asm; end of static storage */
int *endFixed;
int totAv;
/* initialize GetFixed allocator */
InitFA()
{
int ans;
ans = (int) &end;
ans = (ans + 1) & -2; /* round up */
endFixed = (int *) ans;
Zero(endFixed, FixedLeft());
};
/* how many words are available? */
int FixedLeft()
{
int ans;
ans = (int) endFixed;
totAv = (memTop - ans) >> 1;
return (totAv);
};
/* allocate nWords words */
int *GetFixed(nWords)
int nWords;
{
struct GFOb *fp;
/* reserve space for header for next cell as well */
if (Ugt(endFixed + nWords + lenGFOb + lenGFOb, memTop)) CallDebugger(ecAllocate+5);
fp = (struct GFOb *) endFixed;
endFixed += lenGFOb;
endFixed += nWords;
/* zero this header and the next header as well */
/* probably not needed */
Zero(fp, lenGFOb + nWords + lenGFOb);
fp->length = nWords;
fp->owner = ReturnLoc(MyFrame());
fp->owner2 = ReturnLoc(CallersFrame(MyFrame()));
return(&fp->data[0]);
};
/* use GetFixed to create a pool of items which can thereafter
be allocated or freed using GetItem and FreeItem
*/
struct Pool *CreatePool(itemSize, nItems)
int itemSize, nItems;
{
struct Pool *pool;
int i;
pool = (struct Pool *) GetFixed(lenPool);
InitQueue(&pool->freeList);
pool->owner = ReturnLoc(MyFrame());
pool->numItems = nItems;
pool->lenItem = itemSize;
for (i = 0; i < nItems; i += 1) Enqueue(&pool->freeList, GetFixed(itemSize));
};
int *GetItem(pool)
struct Pool *pool;
{
return(Dequeue(&pool->freeList));
};
FreeItem(pool, item)
struct Pool *pool;
int *item;
{
Enqueue(&pool->freeList, item);
};