<> <> <> <> DIRECTORY FileStreamPrivate USING [ BufferNodeHandle, BufferNode, FileDataHandle, FileData, NodeStatus, ProcessNode ], FS, IO, Process, Rope; FileStreamProcessCacheImpl: CEDAR MONITOR IMPORTS FileStreamPrivate, Process EXPORTS FileStreamPrivate = BEGIN ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; FileData: TYPE = FileStreamPrivate.FileData; BufferNode: TYPE = FileStreamPrivate.BufferNode; FileDataHandle: TYPE = FileStreamPrivate.FileDataHandle; BufferNodeHandle: TYPE = FileStreamPrivate.BufferNodeHandle; NumberOfProcesses: INT = 2 ; ModuleCondition: CONDITION; QueueRecord: TYPE = RECORD [ fileData: FileDataHandle, node: BufferNodeHandle <<,nodeStatus: FileStreamPrivate.NodeStatus>> <<,nodeFirstFileByteInBuffer: INT>> ]; QUEUESIZE: INT = 20 ; QueueRec: TYPE = RECORD [ queue: ARRAY [0..QUEUESIZE) OF QueueRecord, putQueue: INT _ 0, getQueue: INT _ 0, noEntries: INT _ 0 ]; Queue: REF QueueRec _ NIL; <> StartRequest: PUBLIC ENTRY PROC [ fileData: FileDataHandle, node: BufferNodeHandle ] = { tempCount: INT _ Queue.noEntries ; ptr: INT _ Queue.getQueue ; IF node.status # needsParallelRead AND node.status # needsParallelWrite THEN ERROR ; WHILE tempCount > 0 DO IF Queue.queue[ptr].node = node THEN ERROR ; ptr _ IF ptr = QUEUESIZE-1 THEN 0 ELSE ptr+1 ; tempCount _ tempCount - 1 ; ENDLOOP; WHILE Queue.noEntries >= QUEUESIZE - 1 DO WAIT ModuleCondition ; ENDLOOP; Queue.queue[Queue.putQueue] _ [fileData, node --, node.status, node.firstFileByteInBuffer--]; Queue.putQueue _ IF Queue.putQueue = QUEUESIZE-1 THEN 0 ELSE Queue.putQueue+1 ; Queue.noEntries _ Queue.noEntries + 1; BROADCAST ModuleCondition ; }; <> FindSomethingToDo: ENTRY PROC [] RETURNS [fileData: FileDataHandle, node: BufferNodeHandle ] = { WHILE Queue.noEntries = 0 DO WAIT ModuleCondition ; ENDLOOP; [fileData, node ] _ Queue.queue[Queue.getQueue] ; Queue.queue[Queue.getQueue] _ [NIL,NIL]; Queue.getQueue _ IF Queue.getQueue = QUEUESIZE-1 THEN 0 ELSE Queue.getQueue+1 ; Queue.noEntries _ Queue.noEntries - 1; BROADCAST ModuleCondition ; }; <> FileStreamForegroundProcess: PROC [] = { DO fileData: FileDataHandle ; node: BufferNodeHandle; [fileData, node] _ FindSomethingToDo []; FileStreamPrivate.ProcessNode[fileData, node] ; ENDLOOP; }; <> Init: PROC [] = { myPriority: Process.Priority ; myPriority _ Process.GetPriority[]; Process.SetPriority[Process.priorityForeground]; Queue _ NEW[QueueRec]; FOR I:INT IN [1..NumberOfProcesses] DO process: PROCESS; process _ FORK FileStreamForegroundProcess[]; TRUSTED {Process.Detach[process]; }; ENDLOOP; Process.SetPriority[myPriority]; }; Init[]; END. CHANGE LOG Created by Hagmann on December 6, 1983 3:02 pm <> Modified by Hagmann on December 19, 1984 9:49:48 am PST <>