summaryrefslogtreecommitdiff
path: root/coding-exercises/3/48.rkt
diff options
context:
space:
mode:
authorMike Vink <mike1994vink@gmail.com>2023-07-06 22:31:56 +0200
committerMike Vink <mike1994vink@gmail.com>2023-07-06 22:31:56 +0200
commita8a8e239968d45cc2539b6a55f4dcde04f5543fd (patch)
tree1f727653bf2f9d6ac5101a19796da851c6f53546 /coding-exercises/3/48.rkt
parent872edd4013539f3dfe2535f95d7efdbb6ca5e797 (diff)
stuff
Diffstat (limited to 'coding-exercises/3/48.rkt')
-rw-r--r--coding-exercises/3/48.rkt64
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))