home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 1
/
crawlyvol1.bin
/
tt
/
vmem11
/
vmem_prg
/
vm_alloc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-09-27
|
5KB
|
244 lines
#include "vmem.h"
/************************/
/* Speicheranforderung: */
/************************/
V_ADR vm_alloc (size)
long size;
{
VPAGE vmempage;
WORD count;
MD entry;
int before, pointer;
if (size < 0) /* freien Speicher ermitteln */
{
count = 0;
pointer = free_list;
while (pointer != NIL)
{
if (MD_COUNT (pointer) > count)
count = MD_COUNT (pointer);
pointer = MD_NEXT (pointer);
}
return (PAGE_TO_ADDR (count));
}
count = GET_COUNT (size);
if ((count == 0) || (info.free_blocks == 0))
return (_NULL);
before = NIL;
pointer = free_list;
while (pointer != NIL)
{
if (MD_COUNT (pointer) >= count)
{
vmempage = MD_START (pointer);
if (init_pages (vmempage, count) != OK)
return (_NULL);
MD_START (pointer) += count;
if ((MD_COUNT (pointer) -= count) == 0)
md_delete (before, pointer);
/* Suchen des Nachfolgers in der Belegtliste: */
before = NIL;
pointer = used_list;
while ((pointer != NIL) && (MD_START (pointer) < vmempage))
{
before = pointer;
pointer = MD_NEXT (pointer);
}
/* Einhängen des neuen MD in die Belegtliste: */
entry = get_free_md ();
INSERT_MD (entry, vmempage, count, pointer);
if (before == NIL)
used_list = entry;
else
MD_NEXT (before) = entry;
/* Initialisierung der Seiten: */
entry = vmempage;
do
flags [entry++] = (NEW | FILE | USED);
while (--count > 0);
info.free_blocks--;
return (PAGE_TO_ADDR (vmempage));
}
before = pointer;
pointer = MD_NEXT (pointer);
}
return (_NULL);
}
/*********************/
/* Speicherfreigabe: */
/*********************/
int vm_free (address)
V_ADR address;
{
VPAGE vmempage, lastpage;
WORD count;
MD entry;
int before, pointer, before2, pointer2;
vmempage = GET_PAGE (address);
count = GET_OFFSET (address);
lastpage = vmempage + count - 1;
if (count != 0)
return (NOT_OK);
before = NIL;
pointer = used_list;
while (pointer != NIL)
{
if (MD_START (pointer) == vmempage)
{
/* MD aus der Belegtliste ausketten: */
if (sector_flag)
free_sector (vmempage, MD_COUNT (pointer));
if (before == NIL)
used_list = MD_NEXT (pointer);
else
MD_NEXT (before) = MD_NEXT (pointer);
/* Platz des MDs in der Freiliste suchen: */
before2 = NIL;
pointer2 = free_list;
while ((pointer2 != NIL) && (MD_START (pointer2) < vmempage))
{
before2 = pointer2;
pointer2 = MD_NEXT (pointer2);
}
/* MD in die Freiliste einketten: */
if (before2 == NIL)
free_list = pointer;
else
MD_NEXT (before2) = pointer;
/* Nachfolger des MD ist nun in der Freiliste: */
MD_NEXT (pointer) = pointer2;
/* Speicherkompression: */
md_merge (before2, pointer, pointer2);
/* Freigabe der sich im CACHE befindenden Seiten: */
for (entry = 0; entry < info.cache_count; entry++)
{
if (cache_flags [entry] != CACHE_FREE)
{
if (INSIDE (cache_page [entry], vmempage, lastpage))
FREE_CACHE (entry);
}
}
/* Seiten initialisieren: */
do
flags [vmempage++] = FREE;
while (--count > 0);
info.free_blocks++;
if (info.free_blocks == MAX_BLOCKS)
{
for (entry=0; entry < (age_count + 4); entry++)
{
FREE_CACHE (entry);
cache_age [entry] = 0;
}
}
return (OK);
}
before = pointer;
pointer = MD_NEXT (pointer);
}
return (NOT_OK);
}
/********************************************/
/* Ausketten und Löschen einer MD-Struktur: */
/********************************************/
void md_delete (before, pointer)
MD before, pointer;
{
if (before == NIL)
free_list = MD_NEXT (pointer);
else
MD_NEXT (before) = MD_NEXT (pointer);
DELETE_MD (pointer);
}
/****************************/
/* Verketten freier Blöcke: */
/****************************/
void md_merge (before, current, next)
MD before, current, next;
{
if (before != NIL)
{
if ((MD_START (before) + MD_COUNT (before)) == MD_START (current))
{
MD_COUNT (before) += MD_COUNT (current);
md_delete (before, current);
current = before;
}
}
if (next != NIL)
{
if ((MD_START (current) + MD_COUNT (current)) == MD_START (next))
{
MD_COUNT (current) += MD_COUNT (next);
md_delete (current, next);
}
}
}
/******************************************/
/* Suchen eines Eintrags der Belegtliste: */
/******************************************/
MD md_find (vmempage)
VPAGE vmempage;
{
MD before, pointer;
before = used_list;
pointer = MD_NEXT (before);
while ((pointer != NIL) && (MD_START (pointer) < vmempage))
{
before = pointer;
pointer = MD_NEXT (pointer);
}
return (before);
}