diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2014-11-08 10:31:37 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2014-11-08 10:35:25 -0800 |
commit | fc46ebddf0c802e3942d80446dcd6c8fc339c4fd (patch) | |
tree | 54cb92b6544dd71ed46a93f55f5f6951f99be509 | |
parent | 3bec25ce266aef848fb2a87b9a9ee33ab80566b0 (diff) | |
download | mu-fc46ebddf0c802e3942d80446dcd6c8fc339c4fd.tar.gz |
263
I'm trying to think about how to write a test for the race condition, and how to fix it. One thing that's been hard is even remembering where it lies. It's not between wiping the watch and sleeping on it; that's innocuous because the sleep would just immediately wake up. No, the race condition lies between the empty check and the wipe. For the innocuous race we could just create an atomic wipe-and-sleep. But the more serious race requires a lock. If we need a lock anyway, is there any reason to have two watch variables? I'm going to preserve these alternative functions in the code. Alternatives will only ever be called from other alteratives or tests.
-rw-r--r-- | mu.arc | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/mu.arc b/mu.arc index d9d6321b..3bffa39f 100644 --- a/mu.arc +++ b/mu.arc @@ -868,6 +868,7 @@ ((chan channel) <- arg) ((val tagged-value) <- arg) { begin + ; block if chan is full ((full boolean) <- full? (chan channel)) ; race condition: might unnecessarily sleep if consumer routine reads from ; channel between previous check and the set to watch below @@ -895,6 +896,7 @@ ((default-scope scope-address) <- new (scope literal) (30 literal)) ((chan channel) <- arg) { begin + ; block if chan is empty ((empty boolean) <- empty? (chan channel)) ; race condition: might unnecessarily sleep if consumer routine writes to ; channel between previous check and the set to watch below @@ -918,9 +920,6 @@ (reply (result tagged-value) (chan channel))) ; An empty channel has first-empty and first-full both at the same value. -; A full channel has first-empty just before first-full, wasting one slot. -; (Other alternatives: https://en.wikipedia.org/wiki/Circular_buffer#Full_.2F_Empty_Buffer_Distinction) - (init-fn empty? ((default-scope scope-address) <- new (scope literal) (30 literal)) ((chan channel) <- arg) @@ -929,6 +928,8 @@ ((result boolean) <- eq (full integer) (free integer)) (reply (result boolean))) +; A full channel has first-empty just before first-full, wasting one slot. +; (Other alternatives: https://en.wikipedia.org/wiki/Circular_buffer#Full_.2F_Empty_Buffer_Distinction) (init-fn full? ((default-scope scope-address) <- new (scope literal) (30 literal)) ((chan channel) <- arg) |