made to work on small machines.
This commit is contained in:
parent
abc2ba9a3c
commit
3e4629b077
1 changed files with 61 additions and 19 deletions
|
@ -7,6 +7,14 @@ static char rcsid[] = "$Header$";
|
||||||
* for each piece telling where it is, how many bytes are used, and how may
|
* for each piece telling where it is, how many bytes are used, and how may
|
||||||
* are left. If a request for core doesn't fit in the left bytes, an sbrk()
|
* are left. If a request for core doesn't fit in the left bytes, an sbrk()
|
||||||
* is done and pieces after the one that requested the growth are moved up.
|
* is done and pieces after the one that requested the growth are moved up.
|
||||||
|
*
|
||||||
|
* Unfortunately, we cannot use sbrk to request more memory, because its
|
||||||
|
* result cannot be trusted. More specifically, it does not work properly
|
||||||
|
* on 2.9 BSD, and probably does not work properly on 2.8 BSD and V7 either.
|
||||||
|
* The problem is that "sbrk" adds the increment to the current "break"
|
||||||
|
* WITHOUT testing the carry bit. So, if your break is at 40000, and
|
||||||
|
* you "sbrk(30000)", it will succeed, but your break will be at 4464
|
||||||
|
* (70000 - 65536).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <out.h>
|
#include <out.h>
|
||||||
|
@ -26,7 +34,32 @@ struct memory mems[NMEMS];
|
||||||
bool incore = TRUE; /* TRUE while everything can be kept in core. */
|
bool incore = TRUE; /* TRUE while everything can be kept in core. */
|
||||||
ind_t core_position = (ind_t)0; /* Index of current module. */
|
ind_t core_position = (ind_t)0; /* Index of current module. */
|
||||||
|
|
||||||
#define AT_LEAST 2 /* See comment about string areas. */
|
#define AT_LEAST (ind_t)2 /* See comment about string areas. */
|
||||||
|
#define GRANULE 64 /* power of 2 */
|
||||||
|
|
||||||
|
static char *BASE;
|
||||||
|
static ind_t refused;
|
||||||
|
|
||||||
|
sbreak(incr)
|
||||||
|
ind_t incr;
|
||||||
|
{
|
||||||
|
extern char *sbrk();
|
||||||
|
extern char *brk();
|
||||||
|
unsigned int inc;
|
||||||
|
|
||||||
|
incr = (incr + (GRANULE - 1)) & ~(GRANULE - 1);
|
||||||
|
|
||||||
|
inc = incr;
|
||||||
|
if ((refused && refused < incr) ||
|
||||||
|
inc != incr ||
|
||||||
|
BASE + inc < BASE ||
|
||||||
|
(int) brk(BASE + inc) == -1) {
|
||||||
|
refused = refused && refused > incr ? incr : refused;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
BASE = sbrk(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize some pieces of core. We hope that this will be our last
|
* Initialize some pieces of core. We hope that this will be our last
|
||||||
|
@ -37,9 +70,8 @@ init_core()
|
||||||
register char *base;
|
register char *base;
|
||||||
register ind_t total_size;
|
register ind_t total_size;
|
||||||
register struct memory *mem;
|
register struct memory *mem;
|
||||||
extern char *sbrk();
|
|
||||||
extern char *brk();
|
extern char *brk();
|
||||||
char *BASE;
|
extern char *sbrk();
|
||||||
|
|
||||||
#include "mach.c"
|
#include "mach.c"
|
||||||
|
|
||||||
|
@ -64,14 +96,22 @@ char *BASE;
|
||||||
total_size += 1;
|
total_size += 1;
|
||||||
else
|
else
|
||||||
mems[ALLOGCHR].mem_left -= 1;
|
mems[ALLOGCHR].mem_left -= 1;
|
||||||
|
|
||||||
|
if (sbreak(total_size) == -1) {
|
||||||
|
incore = FALSE; /* In core strategy failed. */
|
||||||
|
if (sbreak(AT_LEAST) == -1)
|
||||||
|
fatal("no core at all");
|
||||||
|
|
||||||
|
base = BASE;
|
||||||
|
for (mem = mems; mem < &mems[NMEMS]; mem++) {
|
||||||
|
mem->mem_base = base;
|
||||||
|
mem->mem_full = (ind_t)0;
|
||||||
|
mem->mem_left = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mems[ALLOLCHR].mem_full = 1;
|
mems[ALLOLCHR].mem_full = 1;
|
||||||
mems[ALLOGCHR].mem_full = 1;
|
mems[ALLOGCHR].mem_full = 1;
|
||||||
|
|
||||||
if (brk(BASE + total_size) == (char *) -1) {
|
|
||||||
incore = FALSE; /* In core strategy failed. */
|
|
||||||
if ((int)sbrk(AT_LEAST) == -1)
|
|
||||||
fatal("no core at all");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -85,10 +125,9 @@ move_up(piece, incr)
|
||||||
register ind_t incr;
|
register ind_t incr;
|
||||||
{
|
{
|
||||||
register struct memory *mem;
|
register struct memory *mem;
|
||||||
extern char *sbrk();
|
|
||||||
|
|
||||||
debug("move_up(%d, %d)\n", piece, (int)incr, 0, 0);
|
debug("move_up(%d, %d)\n", piece, (int)incr, 0, 0);
|
||||||
if (incr != (int)incr || sbrk((int)incr) == (char *) -1)
|
if (sbreak(incr) == -1)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
for (mem = &mems[NMEMS - 1]; mem > &mems[piece]; mem--)
|
for (mem = &mems[NMEMS - 1]; mem > &mems[piece]; mem--)
|
||||||
|
@ -114,16 +153,17 @@ compact(piece, incr)
|
||||||
{
|
{
|
||||||
register ind_t gain;
|
register ind_t gain;
|
||||||
register struct memory *mem;
|
register struct memory *mem;
|
||||||
|
#define ALIGN 8
|
||||||
|
|
||||||
debug("compact(%d, %d)\n", piece, (int)incr, 0, 0);
|
debug("compact(%d, %d)\n", piece, (int)incr, 0, 0);
|
||||||
gain = mems[0].mem_left;
|
gain = mems[0].mem_left & ~(ALIGN - 1);
|
||||||
mems[0].mem_left = (ind_t)0;
|
mems[0].mem_left &= (ALIGN - 1);
|
||||||
for (mem = &mems[1]; mem <= &mems[piece]; mem++) {
|
for (mem = &mems[1]; mem <= &mems[piece]; mem++) {
|
||||||
/* Here memory is inserted before a piece. */
|
/* Here memory is inserted before a piece. */
|
||||||
assert(passnumber == FIRST || gain == (ind_t)0);
|
assert(passnumber == FIRST || gain == (ind_t)0);
|
||||||
copy_down(mem, gain);
|
copy_down(mem, gain);
|
||||||
gain += mem->mem_left;
|
gain += mem->mem_left & ~(ALIGN - 1);
|
||||||
mem->mem_left = (ind_t)0;
|
mem->mem_left &= (ALIGN - 1);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Note that we already added the left bytes of the piece we want to
|
* Note that we already added the left bytes of the piece we want to
|
||||||
|
@ -134,13 +174,13 @@ compact(piece, incr)
|
||||||
|
|
||||||
for (mem = &mems[NMEMS - 1]; mem > &mems[piece]; mem--) {
|
for (mem = &mems[NMEMS - 1]; mem > &mems[piece]; mem--) {
|
||||||
/* Here memory is appended after a piece. */
|
/* Here memory is appended after a piece. */
|
||||||
up += mem->mem_left;
|
up += mem->mem_left & ~(ALIGN - 1);
|
||||||
copy_up(mem, up);
|
copy_up(mem, up);
|
||||||
mem->mem_left = (ind_t)0;
|
mem->mem_left &= (ALIGN - 1);
|
||||||
}
|
}
|
||||||
gain += up;
|
gain += up;
|
||||||
}
|
}
|
||||||
mems[piece].mem_left = gain;
|
mems[piece].mem_left += gain;
|
||||||
return gain >= incr;
|
return gain >= incr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,6 +199,7 @@ copy_down(mem, dist)
|
||||||
register char *new;
|
register char *new;
|
||||||
register ind_t size;
|
register ind_t size;
|
||||||
|
|
||||||
|
if (!dist) return;
|
||||||
size = mem->mem_full;
|
size = mem->mem_full;
|
||||||
old = mem->mem_base;
|
old = mem->mem_base;
|
||||||
new = old - dist;
|
new = old - dist;
|
||||||
|
@ -182,6 +223,7 @@ copy_up(mem, dist)
|
||||||
register char *new;
|
register char *new;
|
||||||
register ind_t size;
|
register ind_t size;
|
||||||
|
|
||||||
|
if (!dist) return;
|
||||||
size = mem->mem_full;
|
size = mem->mem_full;
|
||||||
old = mem->mem_base + size;
|
old = mem->mem_base + size;
|
||||||
new = old + dist;
|
new = old + dist;
|
||||||
|
@ -215,7 +257,7 @@ alloc(piece, size)
|
||||||
while (left + incr < size)
|
while (left + incr < size)
|
||||||
incr += INCRSIZE;
|
incr += INCRSIZE;
|
||||||
|
|
||||||
if (incr == 0 || move_up(piece, incr) || compact(piece, incr)) {
|
if (incr == 0 || move_up(piece, incr) || compact(piece, size)) {
|
||||||
mems[piece].mem_full += size;
|
mems[piece].mem_full += size;
|
||||||
mems[piece].mem_left -= size;
|
mems[piece].mem_left -= size;
|
||||||
return full;
|
return full;
|
||||||
|
|
Loading…
Add table
Reference in a new issue