88 lines
1.9 KiB
C
88 lines
1.9 KiB
C
|
/* $Header$ */
|
||
|
/*
|
||
|
* (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||
|
*
|
||
|
* This product is part of the Amsterdam Compiler Kit.
|
||
|
*
|
||
|
* Permission to use, sell, duplicate or disclose this software must be
|
||
|
* obtained in writing. Requests for such permissions may be sent to
|
||
|
*
|
||
|
* Dr. Andrew S. Tanenbaum
|
||
|
* Wiskundig Seminarium
|
||
|
* Vrije Universiteit
|
||
|
* Postbox 7161
|
||
|
* 1007 MC Amsterdam
|
||
|
* The Netherlands
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
/* Author: J.W. Stevenson */
|
||
|
|
||
|
#include <pc_err.h>
|
||
|
|
||
|
#define assert() /* nothing */
|
||
|
|
||
|
/*
|
||
|
* use circular list of free blocks from low to high addresses
|
||
|
* _highp points to free block with highest address
|
||
|
*/
|
||
|
struct adm {
|
||
|
struct adm *next;
|
||
|
int size;
|
||
|
};
|
||
|
|
||
|
extern struct adm *_lastp;
|
||
|
extern struct adm *_highp;
|
||
|
extern _trp();
|
||
|
|
||
|
static int merge(p1,p2) struct adm *p1,*p2; {
|
||
|
struct adm *p;
|
||
|
|
||
|
p = (struct adm *)((char *)p1 + p1->size);
|
||
|
if (p > p2)
|
||
|
_trp(EFREE);
|
||
|
if (p != p2)
|
||
|
return(0);
|
||
|
p1->size += p2->size;
|
||
|
p1->next = p2->next;
|
||
|
return(1);
|
||
|
}
|
||
|
|
||
|
_dis(n,pp) int n; struct adm **pp; {
|
||
|
struct adm *p1,*p2;
|
||
|
|
||
|
/*
|
||
|
* NOTE: dispose only objects whose size is a multiple of sizeof(*pp).
|
||
|
* this is always true for objects allocated by _new()
|
||
|
*/
|
||
|
n = ((n+sizeof(*p1)-1) / sizeof(*p1)) * sizeof(*p1);
|
||
|
if (n == 0)
|
||
|
return;
|
||
|
if ((p1= *pp) == (struct adm *) 0)
|
||
|
_trp(EFREE);
|
||
|
p1->size = n;
|
||
|
if ((p2 = _highp) == 0) /*p1 is the only free block*/
|
||
|
p1->next = p1;
|
||
|
else {
|
||
|
if (p2 > p1) {
|
||
|
/*search for the preceding free block*/
|
||
|
if (_lastp < p1) /*reduce search*/
|
||
|
p2 = _lastp;
|
||
|
while (p2->next < p1)
|
||
|
p2 = p2->next;
|
||
|
}
|
||
|
/* if p2 preceeds p1 in the circular list,
|
||
|
* try to merge them */
|
||
|
p1->next = p2->next; p2->next = p1;
|
||
|
if (p2 <= p1 && merge(p2,p1))
|
||
|
p1 = p2;
|
||
|
p2 = p1->next;
|
||
|
/* p1 preceeds p2 in the circular list */
|
||
|
if (p2 > p1) merge(p1,p2);
|
||
|
}
|
||
|
if (p1 >= p1->next)
|
||
|
_highp = p1;
|
||
|
_lastp = p1;
|
||
|
*pp = (struct adm *) 0;
|
||
|
}
|