|
@@ -37,8 +37,9 @@ const
|
|
maxblock = maxblocksize div blocksize;
|
|
maxblock = maxblocksize div blocksize;
|
|
maxreusebigger = 8; { max reuse bigger tries }
|
|
maxreusebigger = 8; { max reuse bigger tries }
|
|
|
|
|
|
- usedmask = $80000000;
|
|
|
|
- sizemask = not usedmask;
|
|
|
|
|
|
+ usedmask = 1; { flag if the block is used or not }
|
|
|
|
+ beforeheapendmask = 2; { flag if the block is just before a heapptr }
|
|
|
|
+ sizemask = not(blocksize-1);
|
|
|
|
|
|
{****************************************************************************}
|
|
{****************************************************************************}
|
|
|
|
|
|
@@ -302,7 +303,10 @@ begin
|
|
if heapend-heapptr>size then
|
|
if heapend-heapptr>size then
|
|
begin
|
|
begin
|
|
sysgetmem:=heapptr;
|
|
sysgetmem:=heapptr;
|
|
- pheaprecord(sysgetmem)^.size:=size or usedmask;
|
|
|
|
|
|
+ if (heapptr+size=heapend) then
|
|
|
|
+ pheaprecord(sysgetmem)^.size:=size or (usedmask or beforeheapendmask)
|
|
|
|
+ else
|
|
|
|
+ pheaprecord(sysgetmem)^.size:=size or usedmask;
|
|
inc(sysgetmem,sizeof(theaprecord));
|
|
inc(sysgetmem,sizeof(theaprecord));
|
|
inc(heapptr,size);
|
|
inc(heapptr,size);
|
|
exit;
|
|
exit;
|
|
@@ -378,7 +382,8 @@ begin
|
|
if sizeleft>sizeof(tfreerecord) then
|
|
if sizeleft>sizeof(tfreerecord) then
|
|
begin
|
|
begin
|
|
pcurr:=pfreerecord(pointer(pcurr)+size);
|
|
pcurr:=pfreerecord(pointer(pcurr)+size);
|
|
- pcurr^.size:=sizeleft;
|
|
|
|
|
|
+ { inherit the beforeheapendmask }
|
|
|
|
+ pcurr^.size:=sizeleft or (pheaprecord(sysgetmem)^.size and beforeheapendmask);
|
|
{ insert the block in the freelist }
|
|
{ insert the block in the freelist }
|
|
pcurr^.prev:=nil;
|
|
pcurr^.prev:=nil;
|
|
s1:=sizeleft shr blockshr;
|
|
s1:=sizeleft shr blockshr;
|
|
@@ -388,9 +393,15 @@ begin
|
|
if assigned(freelists[s1]) then
|
|
if assigned(freelists[s1]) then
|
|
freelists[s1]^.prev:=pcurr;
|
|
freelists[s1]^.prev:=pcurr;
|
|
freelists[s1]:=pcurr;
|
|
freelists[s1]:=pcurr;
|
|
|
|
+ { create the block we need to return }
|
|
|
|
+ pheaprecord(sysgetmem)^.size:=size or usedmask;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ { create the block we need to return }
|
|
|
|
+ pheaprecord(sysgetmem)^.size:=size or usedmask or (pheaprecord(sysgetmem)^.size and beforeheapendmask);
|
|
end;
|
|
end;
|
|
- { create the block we need to return }
|
|
|
|
- pheaprecord(sysgetmem)^.size:=size or usedmask;
|
|
|
|
|
|
+
|
|
inc(sysgetmem,sizeof(theaprecord));
|
|
inc(sysgetmem,sizeof(theaprecord));
|
|
exit;
|
|
exit;
|
|
end;
|
|
end;
|
|
@@ -401,7 +412,10 @@ begin
|
|
if heapend-heapptr>size then
|
|
if heapend-heapptr>size then
|
|
begin
|
|
begin
|
|
sysgetmem:=heapptr;
|
|
sysgetmem:=heapptr;
|
|
- pheaprecord(sysgetmem)^.size:=size or usedmask;
|
|
|
|
|
|
+ if (heapptr+size=heapend) then
|
|
|
|
+ pheaprecord(sysgetmem)^.size:=size or (usedmask or beforeheapendmask)
|
|
|
|
+ else
|
|
|
|
+ pheaprecord(sysgetmem)^.size:=size or usedmask;
|
|
inc(sysgetmem,sizeof(theaprecord));
|
|
inc(sysgetmem,sizeof(theaprecord));
|
|
inc(heapptr,size);
|
|
inc(heapptr,size);
|
|
exit;
|
|
exit;
|
|
@@ -428,18 +442,19 @@ end;
|
|
|
|
|
|
Function SysFreeMem(var p : pointer):Longint;
|
|
Function SysFreeMem(var p : pointer):Longint;
|
|
var
|
|
var
|
|
- s : longint;
|
|
|
|
|
|
+ pcurrsize,s : longint;
|
|
pcurr : pfreerecord;
|
|
pcurr : pfreerecord;
|
|
begin
|
|
begin
|
|
if p=nil then
|
|
if p=nil then
|
|
HandleError(204);
|
|
HandleError(204);
|
|
{ fix p to point to the heaprecord }
|
|
{ fix p to point to the heaprecord }
|
|
pcurr:=pfreerecord(pointer(p)-sizeof(theaprecord));
|
|
pcurr:=pfreerecord(pointer(p)-sizeof(theaprecord));
|
|
- pcurr^.size:=pcurr^.size and sizemask;
|
|
|
|
- inc(internal_memavail,pcurr^.size);
|
|
|
|
|
|
+ pcurrsize:=pcurr^.size and sizemask;
|
|
|
|
+ inc(internal_memavail,pcurrsize);
|
|
{ insert the block in it's freelist }
|
|
{ insert the block in it's freelist }
|
|
|
|
+ pcurr^.size:=pcurr^.size and (not usedmask);
|
|
pcurr^.prev:=nil;
|
|
pcurr^.prev:=nil;
|
|
- s:=pcurr^.size shr blockshr;
|
|
|
|
|
|
+ s:=pcurrsize shr blockshr;
|
|
if s>maxblock then
|
|
if s>maxblock then
|
|
s:=0;
|
|
s:=0;
|
|
pcurr^.next:=freelists[s];
|
|
pcurr^.next:=freelists[s];
|
|
@@ -447,7 +462,7 @@ begin
|
|
pcurr^.next^.prev:=pcurr;
|
|
pcurr^.next^.prev:=pcurr;
|
|
freelists[s]:=pcurr;
|
|
freelists[s]:=pcurr;
|
|
p:=nil;
|
|
p:=nil;
|
|
- SysFreeMem:=pcurr^.size;
|
|
|
|
|
|
+ SysFreeMem:=pcurrsize;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -457,7 +472,7 @@ end;
|
|
|
|
|
|
Function SysFreeMemSize(var p : pointer;size : longint):longint;
|
|
Function SysFreeMemSize(var p : pointer;size : longint):longint;
|
|
var
|
|
var
|
|
- s : longint;
|
|
|
|
|
|
+ pcurrsize,s : longint;
|
|
pcurr : pfreerecord;
|
|
pcurr : pfreerecord;
|
|
begin
|
|
begin
|
|
SysFreeMemSize:=0;
|
|
SysFreeMemSize:=0;
|
|
@@ -472,15 +487,16 @@ begin
|
|
HandleError(204);
|
|
HandleError(204);
|
|
{ fix p to point to the heaprecord }
|
|
{ fix p to point to the heaprecord }
|
|
pcurr:=pfreerecord(pointer(p)-sizeof(theaprecord));
|
|
pcurr:=pfreerecord(pointer(p)-sizeof(theaprecord));
|
|
- pcurr^.size:=pcurr^.size and sizemask;
|
|
|
|
- inc(internal_memavail,pcurr^.size);
|
|
|
|
|
|
+ pcurrsize:=pcurr^.size and sizemask;
|
|
|
|
+ inc(internal_memavail,pcurrsize);
|
|
{ size check }
|
|
{ size check }
|
|
size:=(size+sizeof(theaprecord)+(blocksize-1)) and (not (blocksize-1));
|
|
size:=(size+sizeof(theaprecord)+(blocksize-1)) and (not (blocksize-1));
|
|
- if size<>pcurr^.size then
|
|
|
|
|
|
+ if size<>pcurrsize then
|
|
HandleError(204);
|
|
HandleError(204);
|
|
{ insert the block in it's freelist }
|
|
{ insert the block in it's freelist }
|
|
|
|
+ pcurr^.size:=pcurr^.size and (not usedmask);
|
|
pcurr^.prev:=nil;
|
|
pcurr^.prev:=nil;
|
|
- s:=pcurr^.size shr blockshr;
|
|
|
|
|
|
+ s:=pcurrsize shr blockshr;
|
|
if s>maxblock then
|
|
if s>maxblock then
|
|
s:=0;
|
|
s:=0;
|
|
pcurr^.next:=freelists[s];
|
|
pcurr^.next:=freelists[s];
|
|
@@ -488,7 +504,7 @@ begin
|
|
pcurr^.next^.prev:=pcurr;
|
|
pcurr^.next^.prev:=pcurr;
|
|
freelists[s]:=pcurr;
|
|
freelists[s]:=pcurr;
|
|
p:=nil;
|
|
p:=nil;
|
|
- SysFreeMemSize:=pcurr^.size;
|
|
|
|
|
|
+ SysFreeMemSize:=pcurrsize;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -524,6 +540,7 @@ var
|
|
foundsize,
|
|
foundsize,
|
|
sizeleft,
|
|
sizeleft,
|
|
s : longint;
|
|
s : longint;
|
|
|
|
+ wasbeforeheapend : boolean;
|
|
p2 : pointer;
|
|
p2 : pointer;
|
|
hp,
|
|
hp,
|
|
pnew,
|
|
pnew,
|
|
@@ -541,6 +558,7 @@ begin
|
|
{ fix p to point to the heaprecord }
|
|
{ fix p to point to the heaprecord }
|
|
pcurr:=pfreerecord(pointer(p)-sizeof(theaprecord));
|
|
pcurr:=pfreerecord(pointer(p)-sizeof(theaprecord));
|
|
currsize:=pcurr^.size and sizemask;
|
|
currsize:=pcurr^.size and sizemask;
|
|
|
|
+ wasbeforeheapend:=(pcurr^.size and beforeheapendmask)<>0;
|
|
{ is the allocated block still correct? }
|
|
{ is the allocated block still correct? }
|
|
if currsize=size then
|
|
if currsize=size then
|
|
begin
|
|
begin
|
|
@@ -553,9 +571,16 @@ begin
|
|
{ the size is bigger than the previous size, we need to allocated more mem.
|
|
{ the size is bigger than the previous size, we need to allocated more mem.
|
|
We first check if the blocks after the current block are free. If not we
|
|
We first check if the blocks after the current block are free. If not we
|
|
simply call getmem/freemem to get the new block }
|
|
simply call getmem/freemem to get the new block }
|
|
- foundsize:=pcurr^.size and sizemask;
|
|
|
|
|
|
+ foundsize:=0;
|
|
hp:=pcurr;
|
|
hp:=pcurr;
|
|
repeat
|
|
repeat
|
|
|
|
+ inc(foundsize,hp^.size and sizemask);
|
|
|
|
+ { block used or before a heapptr ? }
|
|
|
|
+ if (hp^.size and beforeheapendmask)<>0 then
|
|
|
|
+ begin
|
|
|
|
+ wasbeforeheapend:=true;
|
|
|
|
+ break;
|
|
|
|
+ end;
|
|
{ get next block }
|
|
{ get next block }
|
|
hp:=pfreerecord(pointer(hp)+(hp^.size and sizemask));
|
|
hp:=pfreerecord(pointer(hp)+(hp^.size and sizemask));
|
|
{ when we're at heapptr then we can stop }
|
|
{ when we're at heapptr then we can stop }
|
|
@@ -564,10 +589,8 @@ begin
|
|
inc(foundsize,heapend-heapptr);
|
|
inc(foundsize,heapend-heapptr);
|
|
break;
|
|
break;
|
|
end;
|
|
end;
|
|
- { block used? }
|
|
|
|
if (hp^.size and usedmask)<>0 then
|
|
if (hp^.size and usedmask)<>0 then
|
|
break;
|
|
break;
|
|
- inc(foundsize,hp^.size and sizemask);
|
|
|
|
until (foundsize>=size);
|
|
until (foundsize>=size);
|
|
{ found enough free blocks? }
|
|
{ found enough free blocks? }
|
|
if foundsize>=size then
|
|
if foundsize>=size then
|
|
@@ -588,10 +611,10 @@ begin
|
|
end;
|
|
end;
|
|
s:=hp^.size and sizemask;
|
|
s:=hp^.size and sizemask;
|
|
inc(foundsize,s);
|
|
inc(foundsize,s);
|
|
|
|
+ { remove block from freelist }
|
|
s:=s shr blockshr;
|
|
s:=s shr blockshr;
|
|
if s>maxblock then
|
|
if s>maxblock then
|
|
s:=0;
|
|
s:=0;
|
|
- { remove block from freelist }
|
|
|
|
if assigned(hp^.next) then
|
|
if assigned(hp^.next) then
|
|
hp^.next^.prev:=hp^.prev;
|
|
hp^.next^.prev:=hp^.prev;
|
|
if assigned(hp^.prev) then
|
|
if assigned(hp^.prev) then
|
|
@@ -599,7 +622,10 @@ begin
|
|
else
|
|
else
|
|
freelists[s]:=hp^.next;
|
|
freelists[s]:=hp^.next;
|
|
until (foundsize>=size);
|
|
until (foundsize>=size);
|
|
- pcurr^.size:=foundsize or usedmask;
|
|
|
|
|
|
+ if wasbeforeheapend then
|
|
|
|
+ pcurr^.size:=foundsize or usedmask or beforeheapendmask
|
|
|
|
+ else
|
|
|
|
+ pcurr^.size:=foundsize or usedmask;
|
|
end
|
|
end
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
@@ -623,7 +649,7 @@ begin
|
|
if sizeleft>sizeof(tfreerecord) then
|
|
if sizeleft>sizeof(tfreerecord) then
|
|
begin
|
|
begin
|
|
pnew:=pfreerecord(pointer(pcurr)+size);
|
|
pnew:=pfreerecord(pointer(pcurr)+size);
|
|
- pnew^.size:=sizeleft;
|
|
|
|
|
|
+ pnew^.size:=sizeleft or (pcurr^.size and beforeheapendmask);
|
|
{ insert the block in the freelist }
|
|
{ insert the block in the freelist }
|
|
pnew^.prev:=nil;
|
|
pnew^.prev:=nil;
|
|
s:=sizeleft shr blockshr;
|
|
s:=sizeleft shr blockshr;
|
|
@@ -633,9 +659,14 @@ begin
|
|
if assigned(freelists[s]) then
|
|
if assigned(freelists[s]) then
|
|
freelists[s]^.prev:=pnew;
|
|
freelists[s]^.prev:=pnew;
|
|
freelists[s]:=pnew;
|
|
freelists[s]:=pnew;
|
|
|
|
+ { fix the size of the current block and leave }
|
|
|
|
+ pcurr^.size:=size or usedmask;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ { fix the size of the current block and leave }
|
|
|
|
+ pcurr^.size:=size or usedmask or (pcurr^.size and beforeheapendmask);
|
|
end;
|
|
end;
|
|
- { fix the size of the current block and leave }
|
|
|
|
- pcurr^.size:=size or usedmask;
|
|
|
|
end;
|
|
end;
|
|
SysReAllocMem:=p;
|
|
SysReAllocMem:=p;
|
|
end;
|
|
end;
|
|
@@ -713,7 +744,7 @@ begin
|
|
if sizeleft>sizeof(tfreerecord) then
|
|
if sizeleft>sizeof(tfreerecord) then
|
|
begin
|
|
begin
|
|
pcurr:=pfreerecord(heapptr);
|
|
pcurr:=pfreerecord(heapptr);
|
|
- pcurr^.size:=sizeleft;
|
|
|
|
|
|
+ pcurr^.size:=sizeleft or beforeheapendmask;
|
|
{ insert the block in the freelist }
|
|
{ insert the block in the freelist }
|
|
pcurr^.next:=freelists[0];
|
|
pcurr^.next:=freelists[0];
|
|
pcurr^.prev:=nil;
|
|
pcurr^.prev:=nil;
|
|
@@ -752,7 +783,13 @@ end;
|
|
|
|
|
|
{
|
|
{
|
|
$Log$
|
|
$Log$
|
|
- Revision 1.23 1999-11-10 22:29:51 michael
|
|
|
|
|
|
+ Revision 1.24 1999-11-14 21:34:21 peter
|
|
|
|
+ * fixed reallocmem with a block at the end of an allocated memoryblock,
|
|
|
|
+ had to introduce a flag for such blocks.
|
|
|
|
+ * flags are now stored in the first 4 bits instead of the highest bit,
|
|
|
|
+ this could be done because the sizes of block are always >= 16
|
|
|
|
+
|
|
|
|
+ Revision 1.23 1999/11/10 22:29:51 michael
|
|
+ Fixed sysreallocmem
|
|
+ Fixed sysreallocmem
|
|
|
|
|
|
Revision 1.22 1999/11/01 13:56:50 peter
|
|
Revision 1.22 1999/11/01 13:56:50 peter
|