[9] | 1 | /* $Header: /cvsup/minix/src/lib/ack/libp/dis.c,v 1.1 2005/10/10 15:27:46 beng Exp $ */
|
---|
| 2 | /*
|
---|
| 3 | * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
---|
| 4 | *
|
---|
| 5 | * This product is part of the Amsterdam Compiler Kit.
|
---|
| 6 | *
|
---|
| 7 | * Permission to use, sell, duplicate or disclose this software must be
|
---|
| 8 | * obtained in writing. Requests for such permissions may be sent to
|
---|
| 9 | *
|
---|
| 10 | * Dr. Andrew S. Tanenbaum
|
---|
| 11 | * Wiskundig Seminarium
|
---|
| 12 | * Vrije Universiteit
|
---|
| 13 | * Postbox 7161
|
---|
| 14 | * 1007 MC Amsterdam
|
---|
| 15 | * The Netherlands
|
---|
| 16 | *
|
---|
| 17 | */
|
---|
| 18 |
|
---|
| 19 | /* Author: J.W. Stevenson */
|
---|
| 20 |
|
---|
| 21 | #include <pc_err.h>
|
---|
| 22 |
|
---|
| 23 | #define assert() /* nothing */
|
---|
| 24 |
|
---|
| 25 | /*
|
---|
| 26 | * use circular list of free blocks from low to high addresses
|
---|
| 27 | * _highp points to free block with highest address
|
---|
| 28 | */
|
---|
| 29 | struct adm {
|
---|
| 30 | struct adm *next;
|
---|
| 31 | int size;
|
---|
| 32 | };
|
---|
| 33 |
|
---|
| 34 | extern struct adm *_lastp;
|
---|
| 35 | extern struct adm *_highp;
|
---|
| 36 | extern _trp();
|
---|
| 37 |
|
---|
| 38 | static int merge(p1,p2) struct adm *p1,*p2; {
|
---|
| 39 | struct adm *p;
|
---|
| 40 |
|
---|
| 41 | p = (struct adm *)((char *)p1 + p1->size);
|
---|
| 42 | if (p > p2)
|
---|
| 43 | _trp(EFREE);
|
---|
| 44 | if (p != p2)
|
---|
| 45 | return(0);
|
---|
| 46 | p1->size += p2->size;
|
---|
| 47 | p1->next = p2->next;
|
---|
| 48 | return(1);
|
---|
| 49 | }
|
---|
| 50 |
|
---|
| 51 | _dis(n,pp) int n; struct adm **pp; {
|
---|
| 52 | struct adm *p1,*p2;
|
---|
| 53 |
|
---|
| 54 | /*
|
---|
| 55 | * NOTE: dispose only objects whose size is a multiple of sizeof(*pp).
|
---|
| 56 | * this is always true for objects allocated by _new()
|
---|
| 57 | */
|
---|
| 58 | n = ((n+sizeof(*p1)-1) / sizeof(*p1)) * sizeof(*p1);
|
---|
| 59 | if (n == 0)
|
---|
| 60 | return;
|
---|
| 61 | if ((p1= *pp) == (struct adm *) 0)
|
---|
| 62 | _trp(EFREE);
|
---|
| 63 | p1->size = n;
|
---|
| 64 | if ((p2 = _highp) == 0) /*p1 is the only free block*/
|
---|
| 65 | p1->next = p1;
|
---|
| 66 | else {
|
---|
| 67 | if (p2 > p1) {
|
---|
| 68 | /*search for the preceding free block*/
|
---|
| 69 | if (_lastp < p1) /*reduce search*/
|
---|
| 70 | p2 = _lastp;
|
---|
| 71 | while (p2->next < p1)
|
---|
| 72 | p2 = p2->next;
|
---|
| 73 | }
|
---|
| 74 | /* if p2 preceeds p1 in the circular list,
|
---|
| 75 | * try to merge them */
|
---|
| 76 | p1->next = p2->next; p2->next = p1;
|
---|
| 77 | if (p2 <= p1 && merge(p2,p1))
|
---|
| 78 | p1 = p2;
|
---|
| 79 | p2 = p1->next;
|
---|
| 80 | /* p1 preceeds p2 in the circular list */
|
---|
| 81 | if (p2 > p1) merge(p1,p2);
|
---|
| 82 | }
|
---|
| 83 | if (p1 >= p1->next)
|
---|
| 84 | _highp = p1;
|
---|
| 85 | _lastp = p1;
|
---|
| 86 | *pp = (struct adm *) 0;
|
---|
| 87 | }
|
---|