New Process Synchronization Mechanism in the Simulation Collection
I have added a new process synchronization / communication mechanism to the simulation collection - similar to the Ada rendezvous mechanism. This adds call and accept syntaxes that allow processes to communicate in a synchronized manner. The call syntax allows the caller process to send a request to the callee process. The call syntax has the form:
Where callee
The accept syntax allows the callee process to accept a request from a caller process. The accept syntax has the form:
(let loop ()
(accept caller (lock))
(accept caller (unlock))
(loop)))
(printf "~a: process p1(~a) started.~n"
(current-simulation-time) i)
(call a-lock (lock))
(printf "~a: process p1(~a) acquired lock.~n"
(current-simulation-time) i)
(wait (random-flat 0.0 10.0))
(printf "~a: process p1(~a) releasing lock.~n"
(current-simulation-time) i)
(call a-lock (unlock)))
(with-new-simulation-environment
(let ((a-lock (schedule #:now (lock))))
(for ((i (in-range n)))
(schedule #:at (random-flat 0.0 10.0) (p1 i a-lock)))
(start-simulation))))
0.13863292728449428: process p1(5) acquired lock.
1.1536616785362432: process p1(7) started.
2.0751959904191937: process p1(8) started.
2.876463473845367: process p1(1) started.
3.344929657351545: process p1(4) started.
7.029086638253653: process p1(5) releasing lock.
7.029086638253653: process p1(7) acquired lock.
7.342236104231587: process p1(2) started.
7.824845469456133: process p1(9) started.
7.921942925957062: process p1(6) started.
8.162050798467028: process p1(3) started.
8.574025375628212: process p1(0) started.
8.624836102585753: process p1(7) releasing lock.
8.624836102585753: process p1(8) acquired lock.
16.152957766273808: process p1(8) releasing lock.
16.152957766273808: process p1(1) acquired lock.
18.243251499858758: process p1(1) releasing lock.
18.243251499858758: process p1(4) acquired lock.
22.293434873464157: process p1(4) releasing lock.
22.293434873464157: process p1(2) acquired lock.
27.693559748646905: process p1(2) releasing lock.
27.693559748646905: process p1(9) acquired lock.
32.4025230155617: process p1(9) releasing lock.
32.4025230155617: process p1(6) acquired lock.
39.54837751017477: process p1(6) releasing lock.
39.54837751017477: process p1(3) acquired lock.
39.86720234676685: process p1(3) releasing lock.
39.86720234676685: process p1(0) acquired lock.
44.316970186291684: process p1(0) releasing lock.
(let ((process #f)
(locked? #f))
(let loop ()
(select
((when (not locked?)
(accept caller (lock)
(set! process caller)))
(set! locked? #t))
((accept caller (unlock)
(unless (eq? caller process)
(error 'unlock
"process does not have the lock"
caller)))
(set! process #f)
(set! locked? #f)))
(loop))))
(let ((process #f)
(count 0))
(let loop ()
(select
((accept caller (lock)
(if process
(if (eq? caller process)
(set! count (+ count 1))
(requeue))
(begin
(set! process caller)
(set! count 1)))))
((accept caller (unlock)
(if (eq? caller process)
(begin
(set! count (- count 1))
(when (= count 0)
(set! process #f)))
(error 'unlock
"process does not have the lock"
caller)))))
(loop))))
Labels: simulation