pcs/sbigmxp.c

141 lines
4.3 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* =====> SBIGMXP.C */
/* TIPC Scheme '84 Runtime Support - Memory Allocation Routines
(C) Copyright 1984, 1985 by Texas Instruments Incorporated.
All rights reserved.
Author: Terry Caudill
Installation: Texas Instruments Incorporated, Austin, Texas
Division: Data Systems Group
Project: PC Scheme
Comments: This code was lifted from SBIGMEM.C, which was used to
allocate objects greater than on page in size. It was
modified to understand expanded memory and is tied closely
to EXPSMMU.ASM
Date Written: 4 June 86
*/
#include "scheme.h"
/* Turn off assertions in SBIGMXP.C for performance reasons */
#define ASSERT(arg) /* do nothing */
#define ENTER(xyz) /* do nothing */
extern unsigned first_page; /* paragraph address of first physical page */
/************************************************************************/
/* Allocate a Large BLock in Scheme's Memory */
/************************************************************************/
alloc_big_block(reg, type, size)
int reg[2]; /* register to receive pointer to allocated block */
int type; /* type code of block to be allocated */
unsigned size; /* size of block in bytes (including block header) */
{
int number_of_pages; /* number of pages required to satisy request */
int page; /* page number where large block can be allocated */
number_of_pages = ((size + (PAGESIZE - 1)) / PAGESIZE);
if ((page = find_big_block(number_of_pages)) == -1)
{
garbage(); /* Invoke Garbage Collector to reclaim memory */
if ((page = find_big_block(number_of_pages)) == -1)
{
gcsquish(); /* Try compacting memory */
if ((page = find_big_block(number_of_pages)) == -1)
{
out_of_memory(); /* attempt to execute SCHEME-RESET */
/* Note: The above procedure returns control elsewhere */
}
}
}
zero_page(page);
put_ptr(page, 0, type, size);
nextcell[page] = END_LIST;
if (size <= psize[page] - BLK_OVHD)
{
put_ptr(page, size, FREETYPE, psize[page] - size);
nextcell[page] = size;
}
ptype[page] = type + type;
w_attrib[page] = pageattr[type];
pagelink[page] = pagelist[type];
pagelist[type] = page;
reg[C_PAGE] = ADJPAGE(page);
reg[C_DISP] = 0;
} /* end of function: alloc_big_block(reg, type, size) */
find_big_block(number_of_pages)
int number_of_pages; /* number of contiguous pages required */
{
int free_pages[NUMPAGES+1]; /* free page table */
int i,j; /* our old favorite index variables */
int page; /* working page number */
int page_found = -1; /* page number of first page in big block */
int FirstEmmPage; /* First expanded memory page */
ENTER(find_big_block);
FirstEmmPage = exppage();
/* Initialize free_pages table */
for (i = 0; i <= NUMPAGES; i++)
free_pages[i] = -1;
/* Record the number of all free pages */
page = freepage;
while (page != END_LIST)
{
ASSERT(page >= 0 && page < NUMPAGES /* subchk? */);
ASSERT(free_pages[page] == -1 /* infinite loop? */);
free_pages[page] = page;
page = pagelink[page];
}
/* Search for a contiguous group of pages to satisfy request */
for (i = 0; i < NUMPAGES - DEDPAGES - number_of_pages; i++)
{
if (free_pages[i] != -1)
{
j = 1;
while (free_pages[i+j] != -1 &&
(((free_pages[i] < FirstEmmPage) && (free_pages[i+j] < FirstEmmPage)) ||
((free_pages[i] >= FirstEmmPage) && (free_pages[i+j] >= FirstEmmPage))
)
)
{
j++;
if (j >= number_of_pages)
{
/* required number of pages found-- adjust page table */
page_found = free_pages[i];
psize[page_found] = PAGESIZE * number_of_pages;
free_pages[i] = -1;
for (j = 1; j < number_of_pages; j++)
{
page = free_pages[i+j];
psize[page] = 0;
attrib[page].nomemory = 1;
free_pages[i+j] = -1;
}
/* update list of free pages */
freepage = END_LIST;
for (i = NUMPAGES; i > DEDPAGES; i--)
{
if (free_pages[i] != -1)
{
pagelink[(j = free_pages[i])] = freepage;
freepage = j;
}
}
return(page_found);
}
}
i += j;
}
}
return(-1); /* no pages found */
} /* end of function: find_big_block(number_of_pages) */