externalroutine tidyijob(string (255) s)
! This routine examines file T#SPIJOB, which it first creates as a copy
! of JJ#SPIJOB. It first sets the _user sub-field of each cell in
! the freelist to "<FREE>", and prints out the number of freelist cells.
! It then goes through each of the 128 lists in turn: if any contains a cell
! so marked then the list is terminated before it, since clearly it should
! not be pointing at part of the freelist.
! If the structure gets into a twist it is probably best to destroy
! JSPIJOB and start again. However, such a corruption should be
! investigated.
recordformat rf(integer conad, filetype, datastart, dataend)
record (rf) r
externalroutinespec copy(string (255) s)
systemroutinespec connect(string (31) file, integer mode, hole,
project, record (rf)name r, integername flag)
recordformat ijob head f( c
integer end, start, size, filetype,
checksum, date time, format, sp0,
maxcells, freep, freen, sp1,
halfintegerarray list head(0:127))
record (ijob head f)name ijob head
recordformat cell f(string (6) user, string (16) device, integer size,
halfinteger last, next, integer time q, time unq, string (6) jname)
! This requires 48 bytes.
record (cell f)arrayname cell
record (cell f)arrayformat caf(1:50000)
integer i, flag, j, k, l, maxcells
longinteger li
integerfn s to i(string (255) s)
integer j, z
z = 0
z = 10*z + charno(s,j)-'0' for j=1,1,length(s)
result = z
end
integerfn getcell {from freelist}
integer i
i = ijob head_freep
ijob head_freep = cell(ijob head_freep)_next
cell(ijob head_freep)_last = 0 unless ijob head_freep=0
ijob head_freen = ijob head_freen-1
cell(i) = 0
result = i
end ; ! Of %integerfn getcell.
copy("JJ#SPIJOB,T#SPIJOB")
connect("T#SPIJOB",3,0,0,r,flag)
monitor and stop if flag#0
ijob head == record(r_conad)
cell == array(r_conad+ijob head_start,caf)
maxcells = ijob head_maxcells
begin
halfintegerarray in list(1:maxcells)
in list(i) = 129 for i=1,1,maxcells; ! Marks all cells as unused.
! First mark all freelist cells.
j = 0
i = ijob head_freep
while i#0 cycle
cell(i)_user = "<FREE>"
in list(i) = 128; ! Code for freelist cell.
j = j+1
i = cell(i)_next
repeat
printstring("No. of freelist cells:
1) by counting the list:"); write(j,3); newline
printstring("2) according to head_freen")
write(ijob head_freen,2); newline
ijob head_freen = j
! Now remove any freelist cells within proper lists.
l = 0; ! To hold total number in all lists.
for i=0,1,127 cycle
j = ijob head_listhead(i)
continue if j=0
if cell(j)_user="<FREE>" start
ijob head_listhead(i) = 0
printstring("List"); write(i,2)
printstring(" faulty: contains freelist cells.")
newline
continue
finish
while j#0 cycle
k = cell(j)_next
if k#0 and cell(k)_user="<FREE>" start
cell(j)_next = 0
printstring("List"); write(i,2)
printstring(" faulty: contains freelist cells.")
newline
exit
finish
in list(j) = i; ! Cell is in list i.
l = l+1
j = k
repeat
repeat
! Now check 'in list' array, to see if the structure is self-consistent.
for i = 0,1,127 cycle
j = ijob head_list head(i)
while j#0 cycle
if in list(j)#i start
printstring("Cell"); write(j,1)
printstring(" is in list no."); write(i,1)
printstring(", but 'in list' value is")
write(in list(j),2); newline
finish
j = cell(j)_next
repeat
repeat
j = 0; ! free list count
k = 0; ! unassigned count
for i = 1,1,maxcells cycle
j = j+1 if in list(i)=128
k = k+1 if in list(i)=129
repeat
printstring("3) according to 'in list' array")
write(j,2); newlines(2)
printstring("Total number of cells"); write(maxcells,2); newline
printstring("Cells in use in (0-127) lists:")
write(l,2); newlines(2)
if k#0 start
newline
printstring("No. of cells unaccounted for (i.e. not in freelist and
not in any of the (0-127) lists:")
write(k,2); newline
finish
while ijob head_freen>300 cycle
! We can reduce file by 3 epages = 256 48-byte cells.
! First move any cells in use within the last 3 epages of the file.
for i=ijob head_maxcells,-1,ijob head_maxcells-255 cycle
continue if cell(i)_user="<FREE>"
j = getcell; ! This cell will not be on the last 3 epages of the file.
ijob head_freen = ijob head_freen+1; ! Reverse getcell's decrement of total.
cell(j) = cell(i)
if cell(j)_last=0 start
li = s to i(cell(j)_jname)
l = ((li<<1!1)¬¬2>>13)&127
ijob head_listhead(l) = j
finishelsestart
cell(cell(j)_last)_next = j
finish
cell(cell(j)_next)_last = j if cell(j)_next#0
repeat
ijob head_freen = ijob head_freen-256
ijob head_maxcells = ijob head_maxcells-256
ijob head_size = ijob head_size-256*48
ijob head_end = ijob head_size
i = ijob head_maxcells
i = i-1 while cell(i)_user#"<FREE>"
! i now gives end of freelist.
cell(i)_next = 0
repeat
end
printstring("Tidied file left in T#SPIJOB."); newline
end
endoffile