diff options
| author | Mike Vink <mike1994vink@gmail.com> | 2023-07-06 22:31:56 +0200 |
|---|---|---|
| committer | Mike Vink <mike1994vink@gmail.com> | 2023-07-06 22:31:56 +0200 |
| commit | a8a8e239968d45cc2539b6a55f4dcde04f5543fd (patch) | |
| tree | 1f727653bf2f9d6ac5101a19796da851c6f53546 /coding-exercises/3/48.rkt | |
| parent | 872edd4013539f3dfe2535f95d7efdbb6ca5e797 (diff) | |
stuff
Diffstat (limited to 'coding-exercises/3/48.rkt')
| -rw-r--r-- | coding-exercises/3/48.rkt | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/coding-exercises/3/48.rkt b/coding-exercises/3/48.rkt new file mode 100644 index 0000000..a3d2f3e --- /dev/null +++ b/coding-exercises/3/48.rkt @@ -0,0 +1,64 @@ +#lang racket +(define (make-mutex) + (let ((the-mutex (make-semaphore 1))) + (define (dispatch m) + (cond ((eq? m 'acquire) + (semaphore-wait the-mutex)) + ((eq? m 'release) + (semaphore-post the-mutex)))) + dispatch)) + +(define (make-serializer) + (let ((mutex (make-mutex))) + (lambda (p) + (define (serialized-p . args) + (mutex 'acquire) + (let ((val (apply p args))) + (mutex 'release) + val)) + serialized-p))) + +(define (make-numbered-accounts n) + (let ((global-serializer (make-serializer))) + (global-serializer + (lambda (balance) + (define (withdraw amount) + (if (>= balance amount) + (begin (set! balance (- balance amount)) + balance) + "Insufficient funds")) + (define (deposit amount) + (set! balance (+ balance amount)) + balance) + (let ((number (begin (set! n (+ n 1)) + n)) + (balance-serializer (make-serializer))) + (lambda (m) + (cond ((eq? m 'withdraw) withdraw) + ((eq? m 'deposit) deposit) + ((eq? m 'balance) balance) + ((eq? m 'serializer) balance-serializer) + ((eq? m 'number) number)))))))) +(define account (make-numbered-accounts 0)) +(define a1 (account 100)) +(define a2 (account 50)) +(println (a1 'number)) +(println (a2 'number)) + +(define (exchange a1 a2) + (let ((delta (- (a1 'balance) + (a2 'balance)))) + ((a1 'withdraw) delta) + ((a2 'deposit) delta))) + +(define (serialized-exchange a1 a2) + (let ((s1 (a1 'serializer)) + (s2 (a2 'serializer))) + (let ((s (if (< (a1 'number) + (a2 'number)) + (lambda (f) (s1 (s2 f))) + (lambda (f) (s2 (s1 f)))))) + ((s exchange) a1 a2)))) +(serialized-exchange a1 a2) +(println (a1 'balance)) +(println (a2 'balance)) |
