2 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 * See the copyright notice in the ACK home directory, in the file "Copyright".
7 /* Core management for the EM assembler.
10 returns a pointer to a free area of 'size' bytes.
12 free's the area of 'size' bytes pointed to by ptr
14 Free blocks are linked together and kept sorted.
15 Adjacent free blocks are collapsed.
16 Free blocks with a size smaller then the administration cannot
18 The algorithm is first fit.
24 static char rcs_id[] = "$Id: asscm.c,v 2.6 1994/06/24 10:15:30 ceriel Exp $" ;
28 static unsigned m_used = 0 ;
29 static unsigned m_free = 0 ;
33 struct freeblock *f_next ;
37 static struct freeblock freexx[2] = {
42 #define freehead freexx[1]
44 #define CHUNK 2048 /* Smallest chunk to be gotten from UNIX */
46 area_t getarea(size) unsigned size ; {
47 register struct freeblock *c_ptr,*l_ptr ;
52 size = ((size + (sizeof(int) - 1)) / sizeof(int)) * sizeof(int);
58 for ( l_ptr= &freehead, c_ptr= freehead.f_next ;
59 c_ptr!= &freehead ; c_ptr = c_ptr->f_next ) {
60 if ( size==c_ptr->f_size ) {
61 l_ptr->f_next= c_ptr->f_next ;
62 return (area_t) c_ptr ;
64 if ( size+sizeof freehead <= c_ptr->f_size ) {
65 c_ptr->f_size -= size ;
66 return (area_t) ((char *) c_ptr + c_ptr->f_size) ;
70 rqsize = size<CHUNK ? CHUNK : size ;
72 ptr = malloc( rqsize ) ;
73 if ( ptr ) break ; /* request succesfull */
75 rqsize -= rqsize%sizeof (int) ;
76 if ( rqsize < sizeof freehead ) {
77 fatal("Out of memory") ;
80 freearea((area_t)ptr,rqsize) ;
88 freearea(ptr,size) register area_t ptr ; unsigned size ; {
89 register struct freeblock *c_ptr, *l_ptr ;
91 size = ((size + (sizeof(int) - 1)) / sizeof(int)) * sizeof(int);
96 for ( l_ptr= &freehead, c_ptr=freehead.f_next ;
97 c_ptr!= &freehead ; c_ptr= c_ptr->f_next ) {
98 if ( (area_t)c_ptr>ptr ) break ;
101 /* now insert between l_ptr and c_ptr */
102 /* Beware they may both point to freehead */
105 if ( ((char *)l_ptr)+l_ptr->f_size> (char *)ptr && (char *)l_ptr<=(char *)ptr )
106 fatal("Double freed") ;
107 if ( ((char *)ptr)+size > (char *)c_ptr && (char *)ptr<=(char *)c_ptr )
108 fatal("Frreed double") ;
110 /* Is the block before this one adjacent ? */
111 if ( ((char *)l_ptr) + l_ptr->f_size == (char *) ptr ) {
112 l_ptr->f_size += size ; /* yes */
114 /* No, create an entry */
115 ((struct freeblock *)ptr)->f_next = c_ptr ;
116 ((struct freeblock *)ptr)->f_size = size ;
117 l_ptr->f_next = (struct freeblock *)ptr ;
118 l_ptr = (struct freeblock *)ptr ;
120 /* Are the two entries adjacent ? */
121 if ( (char *)l_ptr + l_ptr->f_size == (char *) c_ptr ) {
122 /* the two entries are adjacent */
123 l_ptr->f_next = c_ptr->f_next ;
124 l_ptr->f_size += c_ptr->f_size ;
130 printf("Free %7u, Used %7u, Total %7u\n",m_free,m_used,m_free+m_used);