#lang racket ;;; Example 6a - Simple Accepts and Calls ;;; ;;; This example uses sequential lock/unlock accepts to implement the lock. This ;;; works, but is very fragile. In particular, if the entry calls to lock or ;;; unlock are out of order or otherwise unmatched, the lock will not perform ;;; as expected. (require (planet williams/simulation/simulation)) ;;; process (lock) ;;; entry (lock) -> void? ;;; entry (unlock) -> void? ;;; This process implements a lock with sequential lock/unlock accepts. The lock ;;; entry locks the lock and the unlock entry unlocks the lock. There is no ;;; internal state. (define-process (lock) (let loop () (accept caller (lock)) (accept caller (unlock)) (loop))) ;;; process (p1 i a-lock) ;;; i : exact-nonnegative-integer? ;;; a-lock : process? ;;; This process uses the lock to protect its critical region, which just does a ;;; random wait in this case. (define-process (p1 i a-lock) (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))) ;;; (main n) -> void? ;;; n : exact-nonnegative-integer? ;;; Creates the lock process and schedules n p1 processes that use the lock. (define (main n) (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)))) ;;; Test with 10 p1 processes. (main 10)