ack/util/ass/asscm.c

148 lines
3.2 KiB
C
Raw Permalink Normal View History

1984-07-02 15:35:56 +00:00
/*
1987-03-10 01:26:51 +00:00
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
1984-07-02 15:35:56 +00:00
*
*/
/* Core management for the EM assembler.
2019-03-17 14:41:25 +00:00
two routines:
getarea(size)
returns a pointer to a free area of 'size' bytes.
freearea(ptr,size)
free's the area of 'size' bytes pointed to by ptr
1984-07-02 15:35:56 +00:00
2019-03-17 14:41:25 +00:00
Free blocks are linked together and kept sorted.
Adjacent free blocks are collapsed.
Free blocks with a size smaller then the administration cannot
exist.
The algorithm is first fit.
*/
1984-07-02 15:35:56 +00:00
#include "ass00.h"
2019-03-17 14:41:25 +00:00
#include "assex.h"
#include "asscm.h"
1984-11-08 12:08:31 +00:00
1984-07-02 15:35:56 +00:00
#ifdef MEMUSE
2019-03-17 14:41:25 +00:00
static unsigned m_used = 0;
static unsigned m_free = 0;
1984-07-02 15:35:56 +00:00
#endif
2019-03-17 14:41:25 +00:00
struct freeblock
{
struct freeblock *f_next;
unsigned f_size;
};
1984-07-02 15:35:56 +00:00
2019-03-17 14:41:25 +00:00
static struct freeblock freexx[2] =
{
{ freexx, 0 },
{ freexx + 1, 0 } };
1984-07-02 15:35:56 +00:00
#define freehead freexx[1]
#define CHUNK 2048 /* Smallest chunk to be gotten from UNIX */
2019-03-17 14:41:25 +00:00
area_t getarea(unsigned int size)
{
register struct freeblock *c_ptr, *l_ptr;
register char *ptr;
unsigned rqsize;
1984-07-02 15:35:56 +00:00
1988-04-25 10:41:33 +00:00
size = ((size + (sizeof(int) - 1)) / sizeof(int)) * sizeof(int);
1984-07-02 15:35:56 +00:00
#ifdef MEMUSE
2019-03-17 14:41:25 +00:00
m_used += size;
m_free -= size;
1984-07-02 15:35:56 +00:00
#endif
2019-03-17 14:41:25 +00:00
for (;;)
{
for (l_ptr = &freehead, c_ptr= freehead.f_next;
c_ptr!= &freehead; c_ptr = c_ptr->f_next )
{
if ( size==c_ptr->f_size )
{
l_ptr->f_next= c_ptr->f_next;
return (area_t) c_ptr;
1984-07-02 15:35:56 +00:00
}
2019-03-17 14:41:25 +00:00
if ( size+sizeof freehead <= c_ptr->f_size )
{
c_ptr->f_size -= size;
return (area_t) ((char *) c_ptr + c_ptr->f_size);
1984-07-02 15:35:56 +00:00
}
2019-03-17 14:41:25 +00:00
l_ptr = c_ptr;
1984-07-02 15:35:56 +00:00
}
2019-03-17 14:41:25 +00:00
rqsize = size<CHUNK ? CHUNK : size;
for(;;)
{
ptr = malloc( rqsize );
if ( ptr ) break; /* request succesfull */
rqsize /= 2;
rqsize -= rqsize%sizeof (int);
if ( rqsize < sizeof freehead )
{
fatal("Out of memory");
1984-07-02 15:35:56 +00:00
}
}
2019-03-17 14:41:25 +00:00
freearea((area_t)ptr,rqsize);
1984-07-02 15:35:56 +00:00
#ifdef MEMUSE
2019-03-17 14:41:25 +00:00
m_used += rqsize;
1984-07-02 15:35:56 +00:00
#endif
}
/* NOTREACHED */
}
2019-03-17 14:41:25 +00:00
void freearea(register area_t ptr, unsigned int size)
{
register struct freeblock *c_ptr, *l_ptr;
1984-07-02 15:35:56 +00:00
1988-04-25 10:41:33 +00:00
size = ((size + (sizeof(int) - 1)) / sizeof(int)) * sizeof(int);
1984-07-02 15:35:56 +00:00
#ifdef MEMUSE
2019-03-17 14:41:25 +00:00
m_free += size;
m_used -= size;
1984-07-02 15:35:56 +00:00
#endif
2019-03-17 14:41:25 +00:00
for (l_ptr = &freehead, c_ptr=freehead.f_next;
c_ptr!= &freehead; c_ptr= c_ptr->f_next )
{
if ( (area_t)c_ptr>ptr ) break;
l_ptr= c_ptr;
1984-07-02 15:35:56 +00:00
}
/* now insert between l_ptr and c_ptr */
/* Beware they may both point to freehead */
#ifdef MEMUSE
2019-03-17 14:41:25 +00:00
if (((char *) l_ptr) + l_ptr->f_size > (char *) ptr
&& (char *) l_ptr <= (char *) ptr)
fatal("Double freed");
if (((char *) ptr) + size > (char *) c_ptr
&& (char *) ptr <= (char *) c_ptr)
fatal("Frreed double");
1984-07-02 15:35:56 +00:00
#endif
/* Is the block before this one adjacent ? */
2019-03-17 14:41:25 +00:00
if (((char *) l_ptr) + l_ptr->f_size == (char *) ptr)
{
l_ptr->f_size += size;
/* yes */
}
else
{
1984-07-02 15:35:56 +00:00
/* No, create an entry */
2019-03-17 14:41:25 +00:00
((struct freeblock *) ptr)->f_next = c_ptr;
((struct freeblock *) ptr)->f_size = size;
l_ptr->f_next = (struct freeblock *) ptr;
l_ptr = (struct freeblock *) ptr;
1984-07-02 15:35:56 +00:00
}
/* Are the two entries adjacent ? */
2019-03-17 14:41:25 +00:00
if ((char *) l_ptr + l_ptr->f_size == (char *) c_ptr)
{
1984-07-02 15:35:56 +00:00
/* the two entries are adjacent */
2019-03-17 14:41:25 +00:00
l_ptr->f_next = c_ptr->f_next;
l_ptr->f_size += c_ptr->f_size;
1984-07-02 15:35:56 +00:00
}
}
#ifdef MEMUSE
2019-03-17 14:41:25 +00:00
void memuse(void)
{
printf("Free %7u, Used %7u, Total %7u\n", m_free, m_used, m_free + m_used);
1984-07-02 15:35:56 +00:00
}
#endif