; withdraw an amount from the account ; balance (define (withdraw amount) (set! balance (- balance amount))) (define (parallel-execute . args) (map thread args)) (define x 10) ; executes the two procedures in parallel (parallel-execute (lambda () (set! x (* x x))) (lambda () (set! x (+ x 1)))) ; if cell is already #t then return #t otherwise ; set it to #t and return #f (define (test-and-set! cell) (if (car cell) #t (begin (set-car! cell #t) #f))) ; provides a cell that can be used for ; mutual exclusion purposes among processes (define (make-mutex) (let ((cell (list #f))) (define (the-mutex m) (cond ((eq? m 'acquire) (if (test-and-set! cell) (the-mutex ‘acquire))) ;retry ((eq? m 'release) (clear! cell)) ((eq? m 'print) cell))) the-mutex)) (define (clear! Cell) (set-car! Cell #f)) ; make a serializer by creating a mutex ; to be shared by the mutually exclusive ; procedures (define (make-serializer) (let ((mutex (make-mutex))) (lambda (p) (define (serialized-p . args) (mutex 'acquire) (let ((value (apply p args))) (mutex 'release) value)) serialized-p))) ; create a bank account that is protected and ; allows parallel execution (define (make-account balance) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) (define (deposit amount) (set! balance (+ balance amount)) balance) (let ((s (make-serializer))) (define (dispatch m) (cond ((eq? m 'withdraw) (s withdraw)) ((eq? m 'deposit) (s deposit)) ((eq? m 'balance) balance) (else (error "unknown msg-MAKE-ACCOUNT" m)))) dispatch)) ; procedure evens up two accounts by splitting the difference (define (even-accounts account1 account2) (if (< (account1 'balance) (account2 'balance)) (let ((temp account1)) ; swap accounts (set! account1 account2) (set! account2 temp))) (let ((amount (/ (- (account1 'balance) (account2 'balance)) 2))) ((account1 'withdraw) amount) ((account2 'deposit) amount)))