Sindbad~EG File Manager
/* Manage multiple heaps, using functions for a single heap in heap.c */
/* M. Beeson, for Mathpert */
/*
5.31.94 original date
1.14.97 last modified before release of Mathpert 1.06
1.29.98 last modified
*/
#include <assert.h>
#include "heap.h"
#include "heaps.h"
#include "avail.h"
typedef struct
{ int heapnumber; /* an identifying number */
/* these can be arbitrary, they are not indices into
the heaps array */
heapunit *mem;
unsigned heapsize;
unsigned avail;
unsigned lastnode;
} heap;
#define MAXHEAPS 10 /* maximum number of heaps to be managed */
static heap heaps[MAXHEAPS];
static int activeheap = -1; /* the current heap, or last-active heap if none is
active now, is heaps[activeheap], provided
activeheap >= 0. If it is -1 it means that the
previously active heap has been destroyed, so at
the moment there is no active heap and the most-recently
active heap no longer exists. */
static int nheaps; /* the number of heaps currently usable */
/*___________________________________________________________*/
int number_of_heaps(void)
{ return nheaps;
}
/*___________________________________________________________*/
int create_heap(int identifier, heapunit *space, unsigned heapsize)
/* Create a new heap with the given identifying number; space is
presumed already allocated to size heapsize, measured in units.
return 0 for success;
return 1 if there are already MAXHEAPS heaps.
If no heap was active, make this new heap active.
*/
{ if(nheaps==MAXHEAPS)
return 1;
if(activeheap >= 0)
{ heaps[activeheap].avail = avail;
heaps[activeheap].lastnode = lastnode;
}
heaps[nheaps].heapnumber = identifier;
mem = heaps[nheaps].mem = space;
heaps[nheaps].heapsize = heapsize;
heaps[nheaps].avail = 0;
heaps[nheaps].lastnode = 0;
init_heap(heapsize);
heaps[nheaps].lastnode = lastnode;
++nheaps;
if(activeheap < 0)
activeheap = nheaps-1; /* make this new heap active */
else /* restore the old active heap */
{ mem = heaps[activeheap].mem;
avail = heaps[activeheap].avail;
// lastnode =heaps[activeheap].lastnode;
/* lastnode gets set at the first mallocate. If we
set it here then heapmax doesn't work right. */
}
return 0;
}
/*___________________________________________________________*/
void remove_heap(int identifier)
/* when a document closes, we get rid of its heap using this function.
You ARE allowed to remove the active heap; in that case 'activeheap'
is set to -1.
Remove all trace of the heap with the given identifier.
Assumes that 'identifier' refers to a heap in the heaps array.
However, this does NOT deallocate the memory of the heap, which should
be done before calling this function.
*/
{ int i;
for(i=0;i<nheaps;i++)
{ if(identifier == heaps[i].heapnumber)
break;
}
if(i == nheaps)
assert(0); /* you MUST find it */
if(activeheap == i)
activeheap = -1; /* active heap is being destroyed */
if(activeheap > i)
--activeheap;
for(; i<nheaps-1;i++)
heaps[i] = heaps[i+1];
--nheaps;
}
/*___________________________________________________________*/
int switch_heaps(int identifier)
/* switch to the heap with the given identifying number. */
/* It is presumed that such a heap exists */
/* Returns the identifying number of the heap in use when this
function was called. (There must be one in use!)
*/
{ int i;
int oldheap;
assert(identifier > 0); /* heaps must always have positive id numbers */
if(activeheap >= 0)
{ heaps[activeheap].avail = avail; /* save it */
heaps[activeheap].lastnode = lastnode;
oldheap = heaps[activeheap].heapnumber;
}
else
oldheap = -1; /* so never give heaps negative id numbers */
for(i=0;i<nheaps;i++)
{ if(heaps[i].heapnumber == identifier)
{ /* found it */
mem = heaps[i].mem;
avail = heaps[i].avail;
lastnode = heaps[i].lastnode;
activeheap = i;
return oldheap;
}
}
assert(0); /* the given identifier MUST be valid */
return oldheap;
}
/*_____________________________________________________________*/
static void (*nospace_ptr)(void);
void set_nospace_handler( void (*f)(void))
/* set the out-of-space handler */
{ nospace_ptr = f;
}
void nospace(void)
{ if(!*nospace_ptr)
assert(0); // maybe the code to recover from assertion failures will work.
(*nospace_ptr)();
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists