/* 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) $)