CacheModelImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Written By: Pradeep Sindhu, September 20, 1986 12:46:24 pm PDT
Pradeep Sindhu, September 26, 1986 11:18:18 pm PDT
Last Edited by: Louis Monier September 24, 1986 5:48:34 pm PDT
Russ Atkinson (RRA) September 25, 1986 7:18:52 pm PDT
DIRECTORY
CacheModel, DynaSeer, EditedStream, IO, Random, Real;
CacheModelImpl: CEDAR PROGRAM
IMPORTS DynaSeer, EditedStream, Random, Real
EXPORTS CacheModel
~ BEGIN OPEN CacheModel;
CacheState: TYPE = REF CacheStateRec;
CacheStateRec: TYPE = RECORD [
requestStatus: {notRequesting, requesting, waitingForReply},
rs: Random.RandomStream,
incomingPacket: ARRAY [0..4] OF Cycle ← ALL[NIL],
cacheRBRand, cacheWBRand, cacheWSRand: INT
];
maxRand: INT = 1000000;
defaultPrRBRqst: REAL ← 0.023*(DynaSeer.busCycle/DynaSeer.procCycle);
defaultPrWBRqst: REAL ← defaultPrRBRqst/3.0;
defaultPrWSRqst: REAL ← 0.0;
prRBRqst, prWBRqst, prWSRqst: REAL;
Exported Procedures
Init: PUBLIC PROC [handle: Handle] = {
DO
ENABLE EditedStream.Rubout => LOOP;
prRBRqst ← DynaSeer.GetRealParm[handle.in, handle.out,
"\nCache Pr{RBRqst}: ", defaultPrRBRqst];
prWBRqst ← DynaSeer.GetRealParm[handle.in, handle.out,
"Cache Pr{WBRqst}: ", defaultPrWBRqst];
prWSRqst ← DynaSeer.GetRealParm[handle.in, handle.out,
"Cache Pr{WSRqst}: ", defaultPrWSRqst];
EXIT;
ENDLOOP;
};
CreateCache: PUBLIC PROC [deviceId: DeviceId] RETURNS [device: Device] = {
device ← DynaSeer.CreateDevice[];
device.deviceId ← deviceId;
device.state ← NEW [CacheStateRec];
device.init ← InitCache;
device.cycle ← CycleCache;
};
InitCache: PUBLIC DynaSeer.InitProc = {
cs: CacheState ← NARROW[device.state];
cs.requestStatus ← notRequesting;
cs.rs ← Random.Create[maxRand, device.deviceId];
cs.cacheRBRand ← Real.Fix[prRBRqst*maxRand];
cs.cacheWBRand ← Real.Fix[(prRBRqst+prWBRqst)*maxRand];
cs.cacheWSRand ← Real.Fix[(prRBRqst+prWBRqst+prWSRqst)*maxRand];
};
CycleCache: PUBLIC DynaSeer.CycleProc = {
myState: CacheState ← NARROW[device.state];
myId: DeviceId ← device.deviceId;
GenerateCacheLPRequest: PROC [] RETURNS [Request] = {
rbRqstCycle: Cycle ← DynaSeer.MakeCycle[RBRqst, myId, myId, Random.NextInt[myState.rs]];
wbRqstCycle: Cycle ← DynaSeer.MakeCycle[WBRqst, myId, myId, Random.NextInt[myState.rs]];
wsRqstCycle: Cycle ← DynaSeer.MakeCycle[WSRqst, myId, myId, Random.NextInt[myState.rs]];
rand: INT ← Random.NextInt[myState.rs];
IF rand <= myState.cacheRBRand THEN RETURN [DynaSeer.MakeRequest[Two, rbRqstCycle, Low]];
IF rand <= myState.cacheWBRand THEN RETURN [DynaSeer.MakeRequest[Five, wbRqstCycle, High]];
IF rand <= myState.cacheWSRand THEN RETURN [DynaSeer.MakeRequest[Two, wsRqstCycle, Low]];
RETURN [NIL];
};
TreatBusCycle: PROC [cycle: Cycle] = {
SELECT cycle.cmd FROM
RBRply, WBRply, WSRply => IF cycle.deviceId=myId THEN myState.requestStatus ← notRequesting;
ENDCASE;
};
TreatBusCycle[cycle];
SELECT myState.requestStatus FROM
notRequesting => {
request: Request ← GenerateCacheLPRequest[];
IF request#NIL THEN {
myState.requestStatus ← requesting;
IF request.priority=Low
THEN handle.cacheLPRequests[myId] ← request
ELSE handle.cacheHPRequests[myId] ← request;
};
};
requesting => {
hpRequest: Request ← handle.cacheHPRequests[myId];
lpRequest: Request ← handle.cacheLPRequests[myId];
IF lpRequest=NIL AND hpRequest=NIL
THEN myState.requestStatus ← waitingForReply
ELSE {
IF lpRequest#NIL THEN lpRequest.cycles.first.grantLatency ← lpRequest.cycles.first.grantLatency+1;
IF hpRequest#NIL THEN hpRequest.cycles.first.grantLatency ← hpRequest.cycles.first.grantLatency+1;
};
};
ENDCASE;
};
END.