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;
 | |
| }
 | 
