dis.c

Go to the documentation of this file.
00001 /* $Header: /opt/proj/minix/cvsroot/src/lib/ack/libp/dis.c,v 1.1 2005/10/10 15:27:46 beng Exp $ */
00002 /*
00003  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
00004  *
00005  *          This product is part of the Amsterdam Compiler Kit.
00006  *
00007  * Permission to use, sell, duplicate or disclose this software must be
00008  * obtained in writing. Requests for such permissions may be sent to
00009  *
00010  *      Dr. Andrew S. Tanenbaum
00011  *      Wiskundig Seminarium
00012  *      Vrije Universiteit
00013  *      Postbox 7161
00014  *      1007 MC Amsterdam
00015  *      The Netherlands
00016  *
00017  */
00018 
00019 /* Author: J.W. Stevenson */
00020 
00021 #include        <pc_err.h>
00022 
00023 #define assert()        /* nothing */
00024 
00025 /*
00026  * use circular list of free blocks from low to high addresses
00027  * _highp points to free block with highest address
00028  */
00029 struct adm {
00030         struct adm      *next;
00031         int             size;
00032 };
00033 
00034 extern struct adm       *_lastp;
00035 extern struct adm       *_highp;
00036 extern                  _trp();
00037 
00038 static int merge(p1,p2) struct adm *p1,*p2; {
00039         struct adm *p;
00040 
00041         p = (struct adm *)((char *)p1 + p1->size);
00042         if (p > p2)
00043                 _trp(EFREE);
00044         if (p != p2)
00045                 return(0);
00046         p1->size += p2->size;
00047         p1->next = p2->next;
00048         return(1);
00049 }
00050 
00051 _dis(n,pp) int n; struct adm **pp; {
00052         struct adm *p1,*p2;
00053 
00054         /*
00055          * NOTE: dispose only objects whose size is a multiple of sizeof(*pp).
00056          *       this is always true for objects allocated by _new()
00057          */
00058         n = ((n+sizeof(*p1)-1) / sizeof(*p1)) * sizeof(*p1);
00059         if (n == 0)
00060                 return;
00061         if ((p1= *pp) == (struct adm *) 0)
00062                 _trp(EFREE);
00063         p1->size = n;
00064         if ((p2 = _highp) == 0)  /*p1 is the only free block*/
00065                 p1->next = p1;
00066         else {
00067                 if (p2 > p1) {
00068                         /*search for the preceding free block*/
00069                         if (_lastp < p1)  /*reduce search*/
00070                                 p2 = _lastp;
00071                         while (p2->next < p1)
00072                                 p2 = p2->next;
00073                 }
00074                 /* if p2 preceeds p1 in the circular list,
00075                  * try to merge them                    */
00076                 p1->next = p2->next; p2->next = p1;
00077                 if (p2 <= p1 && merge(p2,p1))
00078                         p1 = p2;
00079                 p2 = p1->next;
00080                 /* p1 preceeds p2 in the circular list */
00081                 if (p2 > p1) merge(p1,p2);
00082         }
00083         if (p1 >= p1->next)
00084                 _highp = p1;
00085         _lastp = p1;
00086         *pp = (struct adm *) 0;
00087 }

Generated on Fri Apr 14 22:57:25 2006 for minix by  doxygen 1.4.6