--- /dev/null
+#lang racket
+
+(define (test-and-set! cell)
+ (if (car cell)
+ true
+ (begin (set-car! cell true)
+ false)))
+#|
+
+If there are two concurrent processes doing the above test-and-set! function,
+there could be many things that can happen.
+
+Assume that the cell is having a #f value initially. Process 1 tests the
+value and finds that it is false. At the same instant, Process 2 also tests
+the cell and finds that it is false and both of them set the cell to true at
+the same instant. Both the processes get a false value from test-and-set!
+and think that they are holding the mutex.
+
+Another scenario is when the Process 1 does the test and then finds that the
+cell is false. Next Process 2's test is executed and it also finds that the
+cell is false. Now, both of them proceed to do a set and so both gets the
+mutex.
+
+In reality, only one of the processes should hold a mutex (Mutual exclusion).
+So, that assumption is violated in this case. As footnote 47 indicate, if the
+instruction that atomically implement test-and-set! is executed at the same
+cycle by two separate concurrent processes, a hardware arbiter resolves who
+gets the chance to execute it.
+
+|#
--- /dev/null
+#lang racket
+
+;; semaphore implementation using mutex
+(define (make-mutex)
+ (let ([cell (mcons #f '())])
+ (define (the-mutex m)
+ (cond [(eq? m 'acquire)
+ (when (test-and-set! cell)
+ (the-mutex 'acquire))] ;; loop till we acquire the mutex
+ [(eq? m 'release) (clear! cell)]))
+ the-mutex))
+
+(define (clear! cell)
+ (set-mcar! cell #f))
+
+(define (test-and-set! cell)
+ (if (mcar cell)
+ #t
+ (begin (set-mcar! cell #t)
+ #f)))
+
+;; semaphore implementation
+(define (make-semaphore n)
+ (let ([cell 0]
+ [mutex (make-mutex)])
+ (define (the-semaphore s)
+ (cond [(eq? s 'acquire)
+ (mutex 'acquire)
+ (if (>= (+ cell 1) n)
+ (begin
+ (mutex 'release)
+ (the-semaphore 'acquire))
+ (begin
+ (set! cell (+ cell 1))
+ (mutex 'release)))]
+ [(eq? s 'release)
+ (mutex 'acquire)
+ (when (> cell 0)
+ (set! cell (- cell 1)))
+ (mutex 'release)]))
+ the-semaphore))
+
+;; using test-and-set!
+(define (make-semaphore n)
+ (let ([cell 0]
+ [flag #f])
+ (define (the-semaphore s)
+ (cond [(eq? s 'acquire)
+ (if (test-and-set! flag)
+ (the-semaphore 'acquire))
+ (if (>= (+ cell 1) n)
+ (begin
+ (clear! flag)
+ (the-semaphore 'acquire))
+ (begin
+ (set! cell (+ cell 1))
+ (clear flag)))]
+ [(eq? s 'release)
+ (if (test-and-set! flag)
+ (the-semaphore 'acquire))
+ (when (> cell 0)
+ (set! cell (- cell 1)))
+ (clear! flag)]))
+ the-semaphore))
--- /dev/null
+#lang racket
+
+#|
+
+by giving a unique number to each account, we are ordering the access to the account
+in a specific manner (say in the ascending order of the number). The reason why deadlock
+occurs is be cause of the concurrent access to the accounts in a specific order (Paul
+attempts to transfer a1 and a2 while Peter attempts to transfer a2 and a1. With the
+suggested change, both will concurrently try to access a1 first but only one of them
+will get access while the other will wait until the serializer for a1 is released.
+
+|#
+
+(define (make-account-and-serializer account-number balance)
+ (define (withdraw amount)
+ (if (>= balance amount)
+ (begin (set! balance (- balance amount))
+ balance)
+ "Insufficient funds"))
+ (define (deposit amount)
+ (set! balance (+ balance amount))
+ balance)
+ (let ((balance-serializer (make-serializer)))
+ (define (dispatch m)
+ (cond ((eq? m 'withdraw) withdraw)
+ ((eq? m 'deposit) deposit)
+ ((eq? m 'balance) balance)
+ ((eq? m 'account-number) account-number)
+ ((eq? m 'serializer) balance-serializer)
+ (else (error "Unknown request -- MAKE-ACCOUNT"
+ m))))
+ dispatch))
+
+(define (serialized-exchange account1 account2)
+ (let ((serializer1 (account1 'serializer))
+ (serializer2 (account2 'serializer))
+ (number1 (account1 'account-number))
+ (number2 (account2 'account-number)))
+ (if (< number1 number2)
+ ((serializer2 (serializer1 exchange))
+ account1
+ account2)
+ ((serializer1 (serializer2 exchange))
+ account1
+ account2)
+))
\ No newline at end of file
--- /dev/null
+#lang racket
+
+#|
+
+Process 1 needs access to a shared resource depending on some runtime condition and needs
+another resource depending on another condition.
+
+Consider another similar process being executed concurrently. We cannot determine
+the order of the resource acquisition apriori in this case.
+
+|#
\ No newline at end of file
+++ /dev/null
-#lang racket
-
-(define (test-and-set! cell)
- (if (car cell)
- true
- (begin (set-car! cell true)
- false)))
-#|
-
-If there are two concurrent processes doing the above test-and-set! function,
-there could be many things that can happen.
-
-Assume that the cell is having a #f value initially. Process 1 tests the
-value and finds that it is false. At the same instant, Process 2 also tests
-the cell and finds that it is false and both of them set the cell to true at
-the same instant. Both the processes get a false value from test-and-set!
-and think that they are holding the mutex.
-
-Another scenario is when the Process 1 does the test and then finds that the
-cell is false. Next Process 2's test is executed and it also finds that the
-cell is false. Now, both of them proceed to do a set and so both gets the
-mutex.
-
-In reality, only one of the processes should hold a mutex (Mutual exclusion).
-So, that assumption is violated in this case. As footnote 47 indicate, if the
-instruction that atomically implement test-and-set! is executed at the same
-cycle by two separate concurrent processes, a hardware arbiter resolves who
-gets the chance to execute it.
-
-|#
+++ /dev/null
-#lang racket
-
-;; semaphore implementation using mutex
-(define (make-mutex)
- (let ([cell (mcons #f '())])
- (define (the-mutex m)
- (cond [(eq? m 'acquire)
- (when (test-and-set! cell)
- (the-mutex 'acquire))] ;; loop till we acquire the mutex
- [(eq? m 'release) (clear! cell)]))
- the-mutex))
-
-(define (clear! cell)
- (set-mcar! cell #f))
-
-(define (test-and-set! cell)
- (if (mcar cell)
- #t
- (begin (set-mcar! cell #t)
- #f)))
-
-;; semaphore implementation
-(define (make-semaphore n)
- (let ([cell 0]
- [mutex (make-mutex)])
- (define (the-semaphore s)
- (cond [(eq? s 'acquire)
- (mutex 'acquire)
- (if (>= (+ cell 1) n)
- (begin
- (mutex 'release)
- (the-semaphore 'acquire))
- (begin
- (set! cell (+ cell 1))
- (mutex 'release)))]
- [(eq? s 'release)
- (mutex 'acquire)
- (when (> cell 0)
- (set! cell (- cell 1)))
- (mutex 'release)]))
- the-semaphore))
-
-;; using test-and-set!
-(define (make-semaphore n)
- (let ([cell 0]
- [flag #f])
- (define (the-semaphore s)
- (cond [(eq? s 'acquire)
- (if (test-and-set! flag)
- (the-semaphore 'acquire))
- (if (>= (+ cell 1) n)
- (begin
- (clear! flag)
- (the-semaphore 'acquire))
- (begin
- (set! cell (+ cell 1))
- (clear flag)))]
- [(eq? s 'release)
- (if (test-and-set! flag)
- (the-semaphore 'acquire))
- (when (> cell 0)
- (set! cell (- cell 1)))
- (clear! flag)]))
- the-semaphore))
+++ /dev/null
-#lang racket
-
-#|
-
-by giving a unique number to each account, we are ordering the access to the account
-in a specific manner (say in the ascending order of the number). The reason why deadlock
-occurs is be cause of the concurrent access to the accounts in a specific order (Paul
-attempts to transfer a1 and a2 while Peter attempts to transfer a2 and a1. With the
-suggested change, both will concurrently try to access a1 first but only one of them
-will get access while the other will wait until the serializer for a1 is released.
-
-|#
-
-(define (make-account-and-serializer account-number balance)
- (define (withdraw amount)
- (if (>= balance amount)
- (begin (set! balance (- balance amount))
- balance)
- "Insufficient funds"))
- (define (deposit amount)
- (set! balance (+ balance amount))
- balance)
- (let ((balance-serializer (make-serializer)))
- (define (dispatch m)
- (cond ((eq? m 'withdraw) withdraw)
- ((eq? m 'deposit) deposit)
- ((eq? m 'balance) balance)
- ((eq? m 'account-number) account-number)
- ((eq? m 'serializer) balance-serializer)
- (else (error "Unknown request -- MAKE-ACCOUNT"
- m))))
- dispatch))
-
-(define (serialized-exchange account1 account2)
- (let ((serializer1 (account1 'serializer))
- (serializer2 (account2 'serializer))
- (number1 (account1 'account-number))
- (number2 (account2 'account-number)))
- (if (< number1 number2)
- ((serializer2 (serializer1 exchange))
- account1
- account2)
- ((serializer1 (serializer2 exchange))
- account1
- account2)
-))
\ No newline at end of file
+++ /dev/null
-#lang racket
-
-#|
-
-Process 1 needs access to a shared resource depending on some runtime condition and needs
-another resource depending on another condition.
-
-Consider another similar process being executed concurrently. We cannot determine
-the order of the resource acquisition apriori in this case.
-
-|#
\ No newline at end of file