unit memmgr;
interface
function dGetMem(size: integer): pointer;
function dFreeMem(p: pointer): integer;
function dReallocMem(p: pointer; size: integer): pointer;
implementation
uses Libc;
const hashSize = 32;
var heap, base, bbase, bend, current: pointer;
memSize, heapCount: cardinal;
type
block = ^rblock;
rblock = record
size: cardinal;
ptr: pointer;
prev: block;
next: block;
free: word;
end;
var
table: array[0..hashSize-1] of block;
function hash(p: pointer): byte;
var o: cardinal;
begin
o := cardinal(p) shr 1;
o := (o AND $00FF00 shr 8) + (o AND $FF0000 shr 16) + (o AND $0000FF);
result := o MOD hashSize;
end;
function getBlockSlot(hint: block): pointer;
var found: boolean;
c: block;
begin
result := nil;
found := false;
c := hint;
while found <> true do
begin
if c = bend then
c := bbase;
if c.ptr = nil then
begin
result := c;
found := true;
continue;
end;
//c := pointer(cardinal(c)+sizeof(rblock));
inc(c);
if c = hint then
exit;
end;
end;
function dGetMem(size: integer): pointer;
var c, n: block;
o: cardinal;
found: boolean;
s: pointer;
begin
result := nil;
if size MOD 4 <> 0 then
size := size + (4 - (size mod 4));
// First, find an empty block
c := block(current);
found := false;
while found <> true do
begin
if c = nil then exit;
if c.size >= size then
found := true
else
c := c.next;
end;
{ Find a new block to put the new free infomation }
n := getBlockSlot(c);
n.ptr := pointer(cardinal(c.ptr)+size);
n.size := c.size-size;
n.next := c.next;
if current = c then
current := n;
// Allocate the block
result := c.ptr;
c.free := 1;
c.size := size;
c.prev := nil;
o := hash(c.ptr);
c.next := table[o];
if table[o] <> nil then
table[o].prev := c;
table[o] := c;
end;
function dFreeMem(p: pointer): integer;
var found: boolean;
c: block;
begin
result := 1;
c := table[hash(p)];
{ Find the block pointed to by p }
while (c.ptr <> p) and (c <> nil) do
begin
c := c.next;
end;
if c = nil then
exit;
c.free := 0;
result := 0;
end;
function dReallocMem(p: pointer; size: integer): pointer;
begin
end;
const
dMemMgr: TMemoryManager = (
GetMem: dGetMem;
FreeMem: dFreeMem;
ReallocMem: dReallocMem);
var i: cardinal;
begin
memSize := 8*1024*1024;
heapCount := 1024;
heap := malloc(memSize);
base := heap;
bbase := malloc(sizeof(rblock)*heapCount);
bend := pointer(cardinal(bbase)+sizeof(rblock)*heapCount);
current := bbase;
for i := 0 to hashSize-1 do
table[i] := nil;
with block(current)^ do
begin
size := memSize;
ptr := base;
next := nil;
free := 0;
end;
// SetMemoryManager(dMemMgr);
end.