MODULE Lingots; IMPORT SIM, EVENT, STAT, PROCS, LIST, RES, CONT; FROM SYSTEM IMPORT ADDRESS; FROM Storage IMPORT ALLOCATE, DEALLOCATE; FROM RAND1 IMPORT Normal, Expon; FROM EVENT IMPORT EventType, EventNotice, NoticeAttrib; FROM CONT IMPORT VarCont, Value, VarAttrib, CurrentVar, SelectMethod, Method, StartInteg, Delete; FROM PROCS IMPORT ProcessType, ProcessInstance, Delay, Suspend, Resume, InstanceAttrib, CurrentProcess, Terminate; FROM LIST IMPORT List, View, OutPosition; FROM RES IMPORT Resource, Request, Release, ServList, User, UserDossier, Avail, ServicePolicy, Report; TYPE Lingot = POINTER TO RECORD (* Un lingot. *) Proc : ProcessInstance; (* Le processus associe a ce lingot. *) Tj : VarCont; (* La temperature du lingot. *) hj : LONGREAL (* Coefficient de rechauffement. *) END; VAR PlaceDansFour : Resource; (* Les places dans le four. *) UnLingot : ProcessType; (* Decrit le comportement d'un lingot. *) GenArrivees : ProcessType; (* Genere les arrivees des lingots. *) FinSim : EventType; (* Fin de la simulation. *) TestS : EventType; (* Verifie la temperature d'un lingot. *) TemperFour : VarCont; (* La temperature du four. *) PROCEDURE ProcLingot; VAR L : Lingot; BEGIN L := PROCS.Attrib (); WITH L^ DO IF Avail (PlaceDansFour) = 0 THEN CONT.Init (Tj, 200.0) END; Request (1, PlaceDansFour); StartInteg (Tj, TestS, L); Suspend; (* Le lingot vient maintenant d'atteindre la temperature S. *) Release (1, PlaceDansFour); Delete (Tj); DISPOSE (L); Terminate END END ProcLingot; PROCEDURE ProcTestS; VAR L : Lingot; BEGIN L := EVENT.Attrib (); IF Value (L^.Tj) >= 1200.0 THEN Resume (L^.Proc) END END ProcTestS; PROCEDURE DerivLingot (t : LONGREAL) : LONGREAL; VAR L : Lingot; BEGIN L := VarAttrib (CurrentVar ()); RETURN L^.hj * (Value (TemperFour) - Value (CurrentVar ())) END DerivLingot; PROCEDURE DerivFour (t : LONGREAL) : LONGREAL; VAR L : Lingot; Sum : LONGREAL; U : ADDRESS; Serv : List; BEGIN Serv := ServList (PlaceDansFour); Sum := 0.2 * (1425.0 - Value (TemperFour)); View (U, First, Serv); WHILE U # NIL DO L := InstanceAttrib (User (UserDossier (U))); Sum := Sum - 0.5 * L^.hj * (Value (TemperFour) - Value (L^.Tj)); View (U, Next, Serv) END; RETURN Sum END DerivFour; PROCEDURE ProcFinSim; BEGIN Report (PlaceDansFour); SIM.Stop END ProcFinSim; PROCEDURE ProcGenArrivees; VAR L : Lingot; BEGIN WHILE TRUE DO Delay (Expon (15.0, 1)); NEW (L); WITH L^ DO hj := Normal (0.15, 0.01, 3); CONT.Create (Tj, Normal (230.0, 12.0, 2), DerivLingot, L); PROCS.ScheduleNamedNext (UnLingot, L, Proc) END END END ProcGenArrivees; BEGIN RES.Create (PlaceDansFour, Fifo, 5, "Places dans le four"); RES.CollectStat (PlaceDansFour); PROCS.Create (GenArrivees, ProcGenArrivees, 2048, "Generateur d'arrivees"); PROCS.Create (UnLingot, ProcLingot, 2048, "Un lingot"); EVENT.Create (FinSim, ProcFinSim, "Fin de la simulation"); EVENT.Create (TestS, ProcTestS, "Test si temper. >= S"); CONT.Create (TemperFour, 600.0, DerivFour, NIL); EVENT.Schedule (FinSim, 1000.0, NIL); PROCS.Schedule (GenArrivees, 0.0, NIL); SelectMethod (RungeKutta2, 0.01); StartInteg (TemperFour, EventType (NIL), NIL); SIM.Start END Lingots.