about summary refs log tree commit diff stats
path: root/075channel.mu
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-09-14 20:24:04 -0700
committerKartik K. Agaram <vc@akkartik.com>2016-09-15 00:48:55 -0700
commit05fe4be58a11eb83373d66069cbd64f75846a4ed (patch)
tree88e3c259ad119d135d5a3068ab30bbcbae5201ca /075channel.mu
parent5e080ed4969eb3e6c520da8efea7af87e644f3eb (diff)
downloadmu-05fe4be58a11eb83373d66069cbd64f75846a4ed.tar.gz
3353
Fix failing scenarios in channel layer. We do so by introducing a kludgy
new instruction to explicitly signal when a routine is stuck ('blocked')
and waiting on another.

All this locking and blocking may well be a crap design. We'll see if we
find ourselves using these primitives again. Ideally we don't need them
for anything else now that we're done building channels.

Still some failing scenarios left in chessboard.mu. Let's see how that
goes.
Diffstat (limited to '075channel.mu')
-rw-r--r--075channel.mu5
1 files changed, 5 insertions, 0 deletions
diff --git a/075channel.mu b/075channel.mu
index 7720ccdd..49ebad87 100644
--- a/075channel.mu
+++ b/075channel.mu
@@ -78,9 +78,11 @@ def write out:address:sink:_elem, val:_elem -> out:address:sink:_elem [
     # channel is full; relinquish lock and give a reader the opportunity to
     # create room on it
     reset lock
+    current-routine-is-blocked
     switch  # avoid spinlocking
     loop
   }
+  current-routine-is-unblocked
 #?   $print [performing write], 10/newline
   # store a deep copy of val
   circular-buffer:address:array:_elem <- get *chan, data:offset
@@ -121,10 +123,12 @@ def read in:address:source:_elem -> result:_elem, eof?:boolean, in:address:sourc
     # channel is empty; relinquish lock and give a writer the opportunity to
     # add to it
     reset lock
+    current-routine-is-blocked
     <channel-read-empty>
     switch  # avoid spinlocking
     loop
   }
+  current-routine-is-unblocked
   # pull result off
   full:number <- get *chan, first-full:offset
   circular-buffer:address:array:_elem <- get *chan, data:offset
@@ -327,6 +331,7 @@ after <channel-read-empty> [
   {
     break-unless closed?
     empty-result:address:_elem <- new _elem:type
+    current-routine-is-unblocked
     return *empty-result, 1/true
   }
 ]