perm filename IFLUSH.2[EAL,HE] blob
sn#701200 filedate 1983-03-24 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00003 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 {$NOMAIN EDIT-called routines to flush things }
C00004 00003 (* Aux routines: flushLevel, flushAll, unwind, flushPdb, flushKids *)
C00013 ENDMK
C⊗;
{$NOMAIN EDIT-called routines to flush things }
%include ialhdr.pas;
{ Externally defined routines: }
(* From ALLOC *)
procedure relCmoncb(n: cmoncbp); external;
procedure relPdb(n: pdbp); external;
(* From IAUX1A *)
function getPdb: pdbp; external;
function getELev(hdr: envheaderp): integer; external;
function getVar (level, offset: byte): enventryp; external;
procedure freePdb(p: pdbp); external;
procedure freeEvent(e: eventp); external;
procedure killStack; external;
(* From IAUX1B *)
procedure deClkQueue(po: pdbp); external;
(* From IAUX2A *)
procedure killEnv; external;
(* Aux routines: flushLevel, flushAll, unwind, flushPdb, flushKids *)
procedure flushLevel(dLev: integer); external; (* to clean up from debugger *)
procedure flushLevel;
var b: boolean; pri: integer; e: eventp; pp,po: pdbp; ee: enventryp;
begin
pri := dLev * 10;
if curInt <> nil then
if curInt↑.priority >= pri then curInt := nil;
b := true;
while b and (activeInts <> nil) do (* flush run queue *)
if activeInts↑.priority >= pri then activeInts := activeInts↑.next
else b := false;
b := true;
while b and (readQueue <> nil) do (* flush read queue *)
if readQueue↑.priority >= pri then readQueue := readQueue↑.next
else b := false;
e := allEvents;
while e <> nil do
with e↑ do
begin
b := true;
while b and (waitlist <> nil) do (* clean up event's waitlist *)
if waitlist↑.priority >= pri then
begin
waitlist := waitlist↑.next;
count := count + 1;
end
else b := false;
e := next;
end;
po := curInt;
pp := allPdbs;
while pp <> nil do
begin
curInt := pp;
pp := pp↑.nextPdb;
with curInt↑ do
if priority >= pri then (* may need to flush this one *)
begin
killStack;
while level < getELev(env) do killEnv; (* flush envs process created *)
if status = sleepqueue then deClkQueue(curInt);
if cm <> nil then
with cm↑ do
if oldcmon <> nil then
begin
with cmon↑.cdef↑ do ee := getVar(level,offset);
ee↑.c := oldcmon;
freePdb(pdb); (* done with this incarnation of cmon *)
if cmon↑.oncond↑.ntype = forcenode then freeEvent(evt);
relCmoncb(cm);
end
else
begin (* set us up for later *)
priority := (priority mod 10) + 1; (* base level priority again *)
spc := cm↑.cmon;
mode := 0;
status := nullqueue;
running := false;
enabled := false;
end
else
begin
if (not procp) and (evt <> nil) then freeEvent(evt);
freePdb(curInt);
end;
end;
end;
curInt := po;
end;
procedure flushAll(p: pdbp; dLev: integer); external; (* for use by EDIT *)
procedure flushAll;
var b: boolean; i: integer; e: eventp; pp,po: pdbp;
begin
flushLevel(dLev);
if p <> nil then
begin (* flush process *)
po := curInt;
curInt := p;
with curInt↑ do
begin
killStack;
while level < getELev(env) do killEnv; (* flush envs process created *)
if status = sleepqueue then deClkQueue(curInt);
if cm = nil then relPdb(curInt);
end;
curInt := po;
end;
if dLev = 0 then
begin
etime := 0;
stime := 0;
curtime := 0;
curInt := nil;
activeInts := nil;
readQueue := nil;
resched := false;
(* *** would like to flush any leftover events, unless we saved outermost *** *)
(* *** environment - if we are then we can't.... *** *)
(* while allEvents <> nil do freeEvent(allEvents); (* flush any old events *)
e := allEvents; (* at least we can reset them though *)
while e <> nil do
with e↑ do
begin e↑.waitlist := nil; count := 0; e := next end;
curInt := getPdb;
speedfactor↑.s := 2.0; (* re-initialize speed_factor *)
iSingleThreadMode := false; (* reset no wait mode *)
(* ??? any other system defined variables need to be reset/reinitialized? ??? *)
end;
end;
procedure unwind(p: pdbp; eLev: integer); external; (* for use by EDIT *)
procedure unwind;
var po: pdbp;
begin
po := curInt;
curInt := p;
while eLev < getELev(curInt↑.env) do killEnv; (* unwind inner environments *)
curInt := po;
end;
procedure flushPdb(p: pdbp); external; (* for use by EDIT *)
procedure flushPdb;
var po: pdbp;
begin
if p↑.status = runqueue then
if activeInts = p then activeInts := p↑.next
else
begin
po := activeInts;
while (po↑.next <> nil) and (po↑.next <> p) do po := po↑.next;
if po <> nil then po↑.next := p↑.next;
end
else if p↑.status = inputqueue then
if readQueue = p then readQueue := p↑.next
else
begin
po := readQueue;
while (po↑.next <> nil) and (po↑.next <> p) do po := po↑.next;
if po <> nil then po↑.next := p↑.next;
end;
p↑.priority := 255; (* so we can free just this process using flushLevel *)
flushLevel(25);
end;
procedure flushKids(p: pdbp; zapit: boolean); external;
procedure flushKids;
var pp: pdbp; b: boolean;
begin
if p↑.status = joinwait then
begin
b := false;
repeat
pp := allPdbs;
repeat (* find one of the threads *)
with pp↑ do
if (not procp) and (cm = nil) and (evt <> nil) then
if evt↑.waitlist = p then
begin flushKids(pp,true); pp := nil end; (* flush it *)
if pp <> nil then (* move on to next *)
begin pp := pp↑.nextPdb; b := pp = nil end;
until pp = nil;
until b; (* repeat til we find all of them *)
end
else if p↑.status = proccall then
begin
pp := allPdbs;
repeat
if pp↑.procp and (pp↑.opdb = p) then
begin flushKids(pp,true); pp := nil end (* flush it *)
else pp := pp↑.nextPdb;
until pp = nil;
end;
if zapit then flushPdb(p);
end;