SysIII/usr/src/uts/vax/os/malloc.c
#include "sys/param.h"
#include "sys/systm.h"
#include "sys/map.h"
#include "sys/page.h"
#include "sys/mem.h"
/*
* Allocate 'size' units from the given map.
* Return the base of the allocated space.
* In a map, the addresses are increasing and the
* list is terminated by a 0 size.
* The swap map unit is 512 bytes.
* Algorithm is first-fit.
*/
malloc(mp, size)
struct map *mp;
{
register unsigned int a;
register struct map *bp;
for (bp=mp; bp->m_size; bp++) {
if (bp->m_size >= size) {
a = bp->m_addr;
bp->m_addr += size;
if ((bp->m_size -= size) == 0) {
do {
bp++;
(bp-1)->m_addr = bp->m_addr;
} while ((bp-1)->m_size = bp->m_size);
}
return(a);
}
}
return(0);
}
/*
* Free the previously allocated space aa
* of size units into the specified map.
* Sort aa into map and combine on
* one or both ends if possible.
*/
mfree(mp, size, a)
struct map *mp;
register unsigned int a;
{
register struct map *bp;
register unsigned int t;
bp = mp;
for (; bp->m_addr<=a && bp->m_size!=0; bp++);
if (bp>mp && (bp-1)->m_addr+(bp-1)->m_size == a) {
(bp-1)->m_size += size;
if (a+size == bp->m_addr) {
(bp-1)->m_size += bp->m_size;
while (bp->m_size) {
bp++;
(bp-1)->m_addr = bp->m_addr;
(bp-1)->m_size = bp->m_size;
}
}
} else {
if (a+size == bp->m_addr && bp->m_size) {
bp->m_addr -= size;
bp->m_size += size;
} else if (size) {
do {
t = bp->m_addr;
bp->m_addr = a;
a = t;
t = bp->m_size;
bp->m_size = size;
bp++;
} while (size = t);
}
}
}
/*
* allocate memory
* Note: the memory map is stored in the array
* `memmap', one bit per page frame. If the
* i'th bit of memmap is 0, then page frame i
* is free (available), if 1, then it is allocated.
* Up to NICMEM free page frame numbers are
* stored in the array mem.m_pnum.
*/
int memmap[];
int freemem;
memall(base, size)
register int *base;
{
register int i, pos, ndx, mask;
if (size <= 0 || size > freemem)
return(0);
if (mem.m_free < 0)
panic("bad mem free-list");
for(i=size; --i>=0; ) {
if (mem.m_free == 0) {
pos = lastpos + 1;
if (pos >= maxfree)
pos = firstfree;
while(mem.m_free<NICMEM) {
if ((memmap[pos>>5]&masktab[pos&0x1f])==0)
mem.m_pnum[mem.m_free++] = pos;
if (pos == lastpos)
break;
if (++pos >= maxfree)
pos = firstfree;
}
if (mem.m_free <= 0)
panic("lost mem");
lastpos = pos;
}
pos = mem.m_pnum[--mem.m_free];
mask = masktab[pos&0x1f];
ndx = pos >> 5;
if (memmap[ndx]&mask)
panic("dup alloc");
memmap[ndx] |= mask;
*base++ = pos;
freemem--;
}
return(size);
}
/*
* Free memory
*/
memfree(base, size)
register int *base, size;
{
register int pos, ndx, mask;
while(--size>=0) {
pos = *base++ &= PG_PFNUM;
if (pos<firstfree || pos>=maxfree)
panic("bad mem free");
ndx = pos >> 5;
mask = masktab[pos & 0x1f];
if ((memmap[ndx]&mask)==0)
panic("dup free");
memmap[ndx] &= ~mask;
if (mem.m_free < NICMEM && mem.m_free >= 0)
mem.m_pnum[mem.m_free++] = pos;
freemem++;
}
}
/*
* Initialize memory map
*/
meminit(first, last)
{
firstfree = first;
maxfree = lastpos = last;
freemem = last - first;
mem.m_free = 0;
}