program ManuelsShop ; { the PROCESS-oriented version using the new process manager toolbox ! } { one customer STARTs, each starts the next. uses MESSAGES for queuing} {the OOP version for turbo Pascal 6.0} USES simobj, mcobj, statobj, qnetobj, clock, queue, coproc, proc_man, MESSAGE, usebios; const NoDelay = 0.0; AlongNumber = MAXINT; PreSimulationSamples = 500; ExperimentSamples = 1000; type PosIntType = WORD; {UNsigned numbers} customer = ^custproc; custproc = object(procdescr) procedure lifecycle;virtual; end; clerk = ^clerkproc; clerkproc = object(procdescr) procedure lifecycle;virtual; end; var { TheClock -- in CLock TheMonitor -- in Proc_man Reporter : ReportList; -- in SIMOBJ } Arrivals, Service : RandomNegExp; {source and sink are really counters!} Source : Counter; Sink : Counter; { Q : aQueueType; -- replaced by semaphore } { this type had statistics which are similar to a MEASURE } FlowTime : Histogram; { bar graph of time spent in shop } Q : PORTDESCR; { processes wait for service here } Manuel : aServerType; { gathers utilization statistics } {------------- CUSTOMER LIFE CYCLE -----------------------------} procedure custproc.lifecycle; var birthTime : REAL; romeo:customer; ticket:notePtr; {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; {put him into the Q and schedule a start event} new (ticket); Q.SEND(ticket); SUSPEND; FlowTime.Update (TheClock.TellTime - BirthTime); {time in shop} Sink.Update ; Monitor.RecordSample; end; { of Customer Life Cycle -------------------------------------------} procedure clerkproc.lifecycle; var who:process; begin repeat who := Q.RECEIVE^.sender ; Manuel.SeizeServer (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.ReleaseServer (1); RESUME (WHO); until false; end; procedure ReadAndInitialize; { initiates the model's entities ! } var romeo : customer; myclerk : clerk; numberServers : integer; {vary the number of clerks in shop} x : integer; begin ClrScr; prompt ('Manuel''s shop. How many servers? '); readln (numberServers); Arrivals.Init (12345, 0.8*numberServers); Service.Init (67891, 1.0 ); Source.Init; Source.SpecificLabel ('Source Creation'); Sink.Init; Sink.SpecificLabel ('Sink Departure'); Manuel.Init (numberServers); Manuel.SpecificLabel ('Manuel''s performance'); FlowTime.Init ( 0, 25, 10 ); FlowTime.SpecificLabel ('Customers'' Time in Shop'); Q.Init; {message port, for service requests} new (romeo, INIt ('ROMEO',0)); {ready first customer} RESUME (romeo); For x := 1 to numberServers do begin New (myclerk, INIT ( 'Manuel',x)); RESUME(myclerk); end; end; 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.