program ManuelsShop ; { the event-oriented version ! } { A single queue, single server queueing model } {Adapted from Wolfgang Kreutzer, System Simulation, programming styles and Languages, 1986, ISBN 0-201-12914-0, p 245 ff.} {the OOP version for turbo Pascal 6.0 and up, Adapted by Lin Jensen, October 1996. New Features: All objects (except TheMonitor) are implemented as objects. Global Reset and Report implemented in SIMOBJ. RunModelForSamples is part of DIS_EV unit, since it is completely general. } {$F+} {Force Far Calls, technical requirement for passing procedures as parameters} USES mcobj, statobj, dis_ev, qnetobj, clock, simobj; const NoDelay = 0.0; AlongNumber = MAXINT; PreSimulationSamples = 500; ExperimentSamples = 1000; type PosIntType = 0..MAXINT; var { Declared and initialized in units: TheClock : anAsynch Clock Type; TheMonitor : anEventSchedulingMonitorType; Reporter : ReportList; } Arrivals, Service : RandomNegExp; Source : aSourceType; Sink : aSinkType; Q : aQueueType; Manuel : aServerType; FlowTime : Histogram; procedure HelloEvent (dummy:aTAptrType; server: Integer); far; forward; {creates incoming customers and puts them in a queue in front of Manuel} procedure StartEvent (dummy:aTAptrType; server: Integer); forward; {starts a service activity if Manuel is idle} procedure FinishEvent (romeo: aTAPtrType; server: Integer); forward; {complete romeo's service activity and check whether other customers} { are waiting for Manuel} procedure ByeEvent (romeo: aTAPtrType; server: Integer); forward; {interviews romeo about queueing delays and gets rid of him} procedure ReadAndInitialize; { initiates the model's entities ! } begin Arrivals.Init ( 12345, 0.8 ); Service.Init ( 67891, 1.0 ); source.Init; sink.Init; Q.init; Manuel.Init ( 1 ); {server capacity = 1} Manuel.SpecificLabel ('Manuel''s performance'); FlowTime.Init ( 0, 25, 10 ); FlowTime.SpecificLabel ('Customers'' Time in Shop') end; (* procedure ResetStatistics; ==== replaced by global reset === *) {all EVENT ROUTINES are called EVENT prefixed by the name of the event} procedure HelloEvent (dummy:aTAptrType; server: Integer); {creates incoming customers and puts them in a queue in front of Manuel} var romeo: aTAPtrType; begin {plan next arrival} ScheduleEvent (TheMonitor, (Arrivals.NegExp), helloEvent, nil, 0); {create a customer} romeo := source.CreateNewTA ; {put him into the Q and schedule a start event} Q.FileintoFIFOq ( romeo); ScheduleEvent (TheMonitor, NoDelay, startEvent, nil, 0); end; {of HelloEvent} procedure StartEvent (dummy:aTAptrType; server: Integer); {starts a service activity if Manuel is idle} var romeo: aTAPtrType; begin IF (Manuel.EnoughServerUnitsAvailableP (1)) and (Q.length > 0) then begin manuel.SeizeServer ( 1); { turn attention to waiting customer} romeo := q.TakeFirstFromQ ; {diagnose degree of lovesickness, mix, and hand over remedy; accept donation } ScheduleEvent (TheMonitor, (Service.NegExp), finishEvent, romeo, 0); end; end; { of StartEvent} procedure FinishEvent (romeo: aTAPtrType; server: Integer); {complete romeo's service activity and check whether other customers} { are waiting for Manuel} begin Manuel.ReleaseServer ( 1); ScheduleEvent (TheMonitor, NoDelay, byeEvent, romeo, 0); ScheduleEvent (TheMonitor, NoDelay, startEvent, nil, 0); end; { of FinishEvent} procedure ByeEvent (romeo: aTAPtrType; server: Integer); {interviews romeo about queueing delays and gets rid of him} begin FlowTime.Update ( FlowTimeQ (romeo)); sink.RemoveTA ( romeo); RecordAnotherSample; {in TheMonitor} end; { of ByeEvent} begin { * * * * * Body of MAIN program * * * * * } ReadAndInitialize; InitEventSchedulingMonitor (TheMonitor, AlongNumber, PreSimulationSamples); ScheduleEvent (TheMonitor, NoDelay, helloEvent, nil, 0); {----- Schedule first Hello event to start simulation ----} { --- the following procedure is part of DIS_EV unit ----- since nothing specific about Manuel's shop! --------} RunModelForSamples (TheMonitor); {---- Presimulation period -} reporter.ResetALL; ResetMonitorStats (TheMonitor, AlongNumber, ExperimentSamples); RunModelForSamples (TheMonitor); {--------Simulation period -} Reporter.ReportALL; end.