Bucket =
RECORD
CASE : BOOLEAN OF
- FALSE: BSIZE: INTEGER; (* size of user part in UNITs *)
+ FALSE: BSIZE: CARDINAL; (* size of user part in UNITs *)
BNEXT: BucketPtr; | (* next free Bucket *)
TRUE: BXX: ALIGNTYPE
END;
USED: ADDRESS;
PROCEDURE MyAllocate(size: CARDINAL) : ADDRESS;
- VAR nu : INTEGER;
- b : INTEGER;
+ VAR nu : CARDINAL;
+ b : CARDINAL;
p, q: BucketPtr;
brk : ADDRESS;
BEGIN
IF FreeLists[b] # NIL THEN
q := FreeLists[b];
FreeLists[b] := q^.BNEXT;
- p := ADDRESS(q) + CARDINAL((nu+1)*UNIT);
+ p := ADDRESS(q) + (nu+1)*UNIT;
(* p indicates the block that must be given
back
*)
(* split block,
tail goes to FreeLists area
*)
- q := ADDRESS(p) + CARDINAL((nu+1)*UNIT);
+ q := ADDRESS(p) + (nu+1)*UNIT;
q^.BSIZE := p^.BSIZE -nu -1;
q^.BNEXT := FreeLists[q^.BSIZE];
FreeLists[q^.BSIZE] := q;
(* Give part of tail of original block.
Block stays in this list.
*)
- q := ADDRESS(p) + CARDINAL((p^.BSIZE-nu)*UNIT);
+ q := ADDRESS(p) + (p^.BSIZE-nu)*UNIT;
q^.BSIZE := nu;
p^.BSIZE := p^.BSIZE - nu - 1;
q^.BNEXT := USED;
PROCEDURE ReOrganize();
VAR lastblock: BucketPtr;
b, be: BucketPtr;
- i: INTEGER;
+ i: CARDINAL;
BEGIN
+ lastblock := NIL;
FOR i := 1 TO NLISTS DO
b := FreeLists[i];
WHILE b # NIL DO
b := FirstBlock;
WHILE ADDRESS(b) < ADDRESS(lastblock) DO
LOOP
- be := ADDRESS(b)+CARDINAL((b^.BSIZE+1)*UNIT);
+ be := ADDRESS(b)+(b^.BSIZE+1)*UNIT;
IF b^.BNEXT # NIL THEN
(* this block is not free *)
EXIT;
EXIT;
END;
(* this block and the next one are free,
- so merge them
+ so merge them, but only if it is not too big
*)
- b^.BSIZE := b^.BSIZE + be^.BSIZE + 1;
+ IF MAX(CARDINAL) - b^.BSIZE > be^.BSIZE THEN
+ b^.BSIZE := b^.BSIZE + be^.BSIZE + 1;
+ ELSE
+ EXIT;
+ END;
END;
b := be;
END;
END;
END;
END;
- b := ADDRESS(b) + CARDINAL((b^.BSIZE+1) * UNIT);
+ b := ADDRESS(b) + (b^.BSIZE+1) * UNIT;
END;
END ReOrganize;
PROCEDURE InitStorage();
- VAR i: INTEGER;
+ VAR i: CARDINAL;
brk: ADDRESS;
BEGIN
FOR i := 1 TO NLISTS DO