/* FILE HANDLER INITIALISATION
Allocates and initialises the cache.
Initialises various globals.
*/
SECTION "STARTING"
GET "LIBHDR"
GET "FH2HDR"
GET "MANHDR"
GET "IOHDR"
LET Starting(StartUpPacket) = VALOF
$( LET Succeeded = TRUE
LET RestartTaskId = ?
LET N.CacheSlots, RestartSeg = ?, ?
LET SegList = VEC 3
// Check that PACKET is a start-up packet
UNLESS StartUpPacket!Pkt.Type=0 &
StartUpPacket!Pkt.Arg1=Action.StartUp DO
$( ReturnPkt(StartUpPacket, 0, Error.ActionNotKnown)
CoWait(StackBase)
$)
|| copy console environment
initio()
consoletask := rootnode ! rtn.tasktab ! [startuppacket!pkt.id] !
tcb.gbase ! [@consoletask-@globsize]
// Extract info from the start-up packet
DeviceId := StartUpPacket!Pkt.Arg2
UnitNo := StartUpPacket!Pkt.Arg3
N.CacheSlots := StartUpPacket!Pkt.Arg4
initialise.environment(startuppacket!pkt.arg5)
writeprotect := startuppacket!pkt.arg6
// Check for a valid no. of cache slots
UNLESS 2<=N.CacheSlots<=20 DO N.CacheSlots := 10
// Allocate the cache vector
Cache := GetVec(N.CacheSlots)
IF Cache=0 DO
$( ReturnPkt(StartUpPacket, 0, Result2)
Stop(Result2)
$)
!Cache := N.CacheSlots
// Allocate cache slots
FOR i = 1 TO N.CacheSlots DO
$( Cache!i := GetVec(Size.Block+Size.CachePrefix)+
Size.CachePrefix
IF Cache!i=Size.CachePrefix DO Succeeded := FALSE
$)
// Check allocation of cache slots was successful
UNLESS Succeeded DO
$( FOR i = 1 TO N.CacheSlots DO
FreeVec(Cache!i-Size.CachePrefix)
FreeVec(Cache)
ReturnPkt(StartUpPacket, 0, Error.GetVecFailure)
Stop(Error.GetVecFailure)
$)
/***********************/
// Initialise the cache
FOR i = 1 TO N.CacheSlots DO Set.Vec(Cache!i-3, 3, 0, 0, 0)
// Load the restart segment
RestartTaskId := 5
UNLESS TaskId=Task.FileHandler | writeprotect DO
$( RestartSeg := LoadSeg("SYS:L.FILE-HANDLER-RESTART")
IF RestartSeg=0 DO
Abort(Abort.LoadSegFailure)
SegList!0 := 3 // Seglist length
SegList!1 := RootNode!Rtn.TaskTab!Task.FileHandler!Tcb.SegList!1
SegList!2 := RootNode!Rtn.TaskTab!Task.FileHandler!Tcb.SegList!2
SegList!3 := RestartSeg
FOR Priority = 500 TO 1000 DO
$( RestartTaskId := CreateTask(SegList, 300, Priority)
UNLESS RestartTaskId=0 BREAK
$)
IF RestartTaskId=0 DO
Abort(Abort.CreateTaskFailure)
$)
|| tickle drive
seek(2)
seek(-80)
|| output "mounting" message
device(act.read, rootkey, cache!1)
|| read root
selectoutput(findoutput["**"])
writef("****** Mounting *"%S*" for %S on unit %N*N",
cache!1+b.file.filename,
writeprotect -> "reading", "updating",
unitno)
endwrite()
// conditionally initiate restart
UNLESS writeprotect DO SendPkt(-1, RestartTaskId, ?, ?, ?,
DeviceId, UnitNo, TaskId, ?, startuppacket!pkt.arg5)
// Return the start up packet as all dynamic
// allocation has been done successfully
ReturnPkt(StartUpPacket, TRUE)
/***********************/
// Initialise the cache
|| FOR i = 1 TO N.CacheSlots DO Set.Vec(Cache!i-3, 3, 0, 0, 0)
// Initialise various globals
Packet.Queue := 0
Lock.Queue := 0
Map := 0
bitmap.checked := FALSE
Access.Idle := TRUE
Work.Idle := TRUE
$( LET fh.tcb = rootnode!rtn.tasktab!task.filehandler
LET fh.code = fh.tcb!tcb.seglist!3
LET this.code = tcb!tcb.seglist!3
handler.segment := fh.code=this.code -> 0,
this.code
$)
// Create coroutines:
Main.Co := CreateCo(Main, 100)
Work.Co := CreateCo(Work, 200)
Access.Co := CreateCo(Access, 100)
Access.Action := Action.Nil
// Make SENDPKT multi-event
OldPktWait := PktWait
PktWait := FHPktWait
// Start the MAIN coroutine
result2 := tcb!tcb.seglist!4
ResumeCo(Main.Co, StackBase)
$)