home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
216.lha
/
Tail
/
alloc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-02-15
|
3KB
|
123 lines
/* alloc.c - memory allocator
*
* The point of this is that it is about 4 times faster than MANX malloc/free
* in c.lib. Malloc in heapmem.o will not allocate a second heap if the first
* is exhausted.
* :ts=8
*/
#define NULL 0L
#define HOWMUCH 4096L /* how much memory to AllocMem() at a time */
typedef struct header {
struct header *next; /* next block */
unsigned long size; /* block size */
};
struct header first;
struct header *head = NULL; /* start of list */
char *alloc (bytes)
unsigned bytes;
{
struct header *getmem ();
register struct header *p, *q;
register long size;
size = (((bytes + 2 * sizeof (struct header) - 1) >> 3) << 3);
if ((q = head) == NULL) {
first.next = head = q = &first;
first.size = 0L;
}
for (p = q->next; ; q = p, p = p->next) {
if (p->size >= size) { /* if this block is large enough */
if (p->size == size)
q ->next = p->next;
else { /* remove memory from tail of block */
p->size -= size;
p = (struct header *) ((char *) p + p->size);
p->size = size;
}
head = q;
p->next = NULL;
return ((char *) (p+1));
}
if (p == head) /* back where we started */
if ((p = getmem ()) == NULL)
return (NULL); /* cannot allocate memory */
}
}
/* freeit - put block back in free list */
freeit (ptr)
char *ptr;
{
register struct header *p, *q;
p = (struct header *) ptr - 1;
for (q = head; ; q = q->next) {
if (p > q && p < q->next)
break; /* new block goes between q & q->next */
if (q >= q->next && p > q)
break; /* new block goes at end of list */
if (q >= q->next && p < q->next)
break; /* new block goes at beginning of list */
}
if ((struct header *) ((char *) p + p->size) == q->next) {
p->size += q->next->size;
p->next = q->next->next;
} else {
p->next = q->next;
}
if ((struct header *) ((char *) q + q->size) == p) {
q->size += p->size;
q->next = p->next;
} else {
q->next = p;
}
head = q;
}
/* getmem - request more memory from system */
struct header *getmem ()
{
char *AllocMem ();
register struct header *up;
if ((up = (struct header *) AllocMem (HOWMUCH, 0L)) == NULL)
return (NULL); /* can't get more memory */
up->next = NULL;
up->size = HOWMUCH;
freeit ((char *) (up + 1));
return (head);
}
quit (code)
int code;
{
register struct header *p, *q;
unsigned long size;
p = head;
do {
if (p == NULL)
break;
q = p->next;
if ((size = p->size) > 0L) {
p->size = 0L;
FreeMem (p, size);
}
p = q;
} while (p != head);
exit (code);
}