From a8a8e239968d45cc2539b6a55f4dcde04f5543fd Mon Sep 17 00:00:00 2001 From: Mike Vink Date: Thu, 6 Jul 2023 22:31:56 +0200 Subject: stuff --- coding-exercises/3/48.rkt | 64 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 coding-exercises/3/48.rkt (limited to 'coding-exercises/3/48.rkt') 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)) -- cgit v1.2.3