<< Previous exercise (3.38) | Index | Next exercise (3.40) >>

I believe the above is wrong and

110: P2 changes x from 10 to 11 between the two times that P1 accesses the value of x during the evaluation of (* x x).

is indeed possible. The serializer doesn't protect P1 at all.

@leafac I think adams is right, as "(s (lambda () (* x x))))" protected the (* x x) from interleaved, P2 can not changes x between the two times that P1 accessed the x.

None of the above is correct!! Actually the right solution is 121, 100, 101 **AND** 11. *adams* has the right reasons for the first three. However you can also get 11: Lets label the 3 processes involved: S1: calculation of x^2, S2: setting x to calculated value of x^2; R1: acquisition of value of x and setting it to x+1. Now here is what can happen: S1: acquires the mutex and calculates the value of x^2 i.e. 100, now it releases the mutex. At this point R1 acquires the mutex and calculates a value of 11 BUT before it can set the value to 11, S2 occurs (nothing barring it from occuring concurrently with R1) and therefore R1 gets to set the final value of x, i.e. 11. You can convince yourselves by running the following simulation:

(define (run-many-times in-test num) (define (run-test numtimes output) (let ((m (in-test))) (cond ((= 0 numtimes) output) ((memq m output) (run-test (- numtimes 1) output)) (true (run-test (- numtimes 1) (cons m output)))))) (run-test num '())) (define (test-2) (define x 10) (define s (make-serializer)) (parallel-execute (lambda () (set! x ((s (lambda () (* x x)))))) (s (lambda () (set! x (+ x 1))))) x) (display (run-many-times test-2 10000)) ;;Output will be (11 100 101 121) in some order

I agree with karthikk. Here's the event sequence that produces 11:

- P1) access x: 10
- P1) new value: 10 * 10 = 100
- P2) access x: 10
- P2) new value: 10 + 1 = 11
**P1) set! x to 100**- P2) set! x to 11

The key idea here is that "P1) set! x to 100" can be interleaved between P2 events.

adams