program ManuelsShop ; { A single queue, single or multiple server queueing model } { the PROCESS-oriented version using the process manager toolbox ! } { one customer STARTs, each starts the next. uses a RESOURCE for queuing, and manuel is UNAVAILABLE during 10-minute breaks, about 100 munutes apart. LOST Customers are counted, whenever the queue exceeds 10. } {Using the simulation toolboxes, Author Lin Jensen Date Nov. 15, 1996 } {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 are implemented as objects. Global Reset and Report implemented in SIMOBJ. } USES clock, queue,simobj, mcobj, statobj, qnetobj, coproc, proc_man, resource, usebios; const NoDelay = 0.0; AlongNumber = MAXINT; PreSimulationSamples = 500; ExperimentSamples = 1000; type PosIntType = WORD; {UNsigned numbers} custptr = ^ customer; customer = object (procdescr) procedure lifecycle; virtual; end; breakptr = ^break; {process scheduling manuel's breaks} break = object (procdescr) procedure lifecycle; virtual; end; var numberServers : integer; {vary the number of clerks in shop} { Declared and initialized in units: TheClock -- in CLock TheMonitor -- in Proc_man Reporter : ReportList; -- in SIMOBJ } Arrivals, Service, BreakTime : RandomNegExp; {source and sink are really counters!} Source : Counter; Sink : Counter; LostCustomers : Counter; { Q : SEMQUEUE; } { processes wait for service here } Manuel : aRESOURCE; { & gathers utilization statistics } FlowTime : Histogram; { bar graph of time spent in shop } {------------- CUSTOMER LIFE CYCLE -----------------------------} procedure customer.lifecycle; var birthTime : REAL; romeo : custptr; {creates incoming customers and puts them in a queue in front of Manuel} begin {random arrival} SLEEP_FOR ( Arrivals.NegExp ); birthTime := theClock.TellTime; {record time of entry into shop} { create next customer} NEW (romeo, Init('ROMEO',GetNumber+1)); resume(romeo); Source.Update; if Manuel.QueueLength > 10 then lostCustomers.update {lose discouraged customer} else begin {put him into the Q and schedule a start event} Manuel.Acquire (1); { turn attention to waiting customer} {diagnose degree of lovesickness, mix, and hand over remedy; accept donation } SLEEP_FOR ( Service.NegExp ); {time required for service} Manuel.Release (1); FlowTime.Update (TheClock.TellTime - BirthTime); {time in shop} Sink.Update ; Monitor.RecordSample; end; {if} { TERMINATE;} {This Customer dissappears} end; { of Customer Life Cycle -------------------------------------------} procedure break.lifecycle; {manuel will need to take some breaks, in case of cauldron fire, etc.} begin while true do begin Sleep_for (breaktime.Negexp); write ('~~~~Manuel wants break at'); theclock.rite; writeln; monitor.trace; Manuel.MakeUnavailable; {waits until current services finish} write ('~~~~Manuel starts break at'); theclock.rite; writeln; Sleep_for (10); {breaks last exactly 10 minutes} write ('~~~~Manuel ends break at'); theclock.rite; writeln; manuel.MakeAvailable; monitor.untrace; end; {while} end; procedure ReadAndInitialize; { initiates the model's entities ! } var romeo : custptr; lunchtime:breakptr; begin ClrScr; prompt ('Manuel''s shop. How many servers? '); readln (numberServers); Arrivals.Init (12345, 0.8*numberServers); Service.Init (67891, 1.0 ); BreakTime.Init (42681, 0.01); {about every 100 mins} Source.Init; Source.SpecificLabel ('Source Creation'); Sink.Init; Sink.SpecificLabel ('Sink Departure'); LostCustomers.Init; LostCustomers.SpecificLabel ('Lost Customer'); Manuel.Init (numberServers); Manuel.SpecificLabel ('Manuel''s performance'); FlowTime.Init ( 0, 25, 10 ); FlowTime.SpecificLabel ('Customers'' Time in Shop'); { ScheduleEvent -- first hello } {ready first customer} NEW (romeo, Init('ROMEO', 0)); resume(romeo); NEW (lunchtime, Init('Break scheduler',10)); resume(lunchtime); end; {Procedure RunModelForSamples -- replaced by RUNSIMULATION } begin { * * * * * Body of MAIN program * * * * * } ReadAndInitialize; Monitor.RunSIMULATION (aLongNumber, PreSimulationSamples); Monitor.Report; {see processes at reset} WaitKeyPress; Reporter.ResetALL; Monitor.RunSIMULATION (aLongNumber, ExperimentSamples); WaitKeyPress; Reporter.ReportALL; WaitKeyPress; end.