[go: up one dir, main page]

Menu

[4700cd]: / scrap / memmgr.pas  Maximize  Restore  History

Download this file

151 lines (133 with data), 2.8 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
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.