diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-07-03 03:11:46 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-07-03 03:11:46 -0700 |
commit | 3ef2f7dfe02837e9ce156cb668c29025d9d49f16 (patch) | |
tree | 4a193ad54d778cf0d386c31840afb98df2f29723 | |
parent | 26965dd683137d3f8cf2fab62f02a8dbf5991a68 (diff) | |
download | mu-3ef2f7dfe02837e9ce156cb668c29025d9d49f16.tar.gz |
3094 - start using deep-copy when writing channels
-rw-r--r-- | 073deep_copy.cc | 3 | ||||
-rw-r--r-- | 074channel.mu | 20 |
2 files changed, 16 insertions, 7 deletions
diff --git a/073deep_copy.cc b/073deep_copy.cc index 7c67425b..02da9e68 100644 --- a/073deep_copy.cc +++ b/073deep_copy.cc @@ -6,6 +6,9 @@ // Implications: Refcounts of all data pointed to by the original ingredient // will remain unchanged. Refcounts of all data pointed to by the (newly // created) result will be 1, in the absence of cycles. +// +// We do handle cycles in the ingredient, however. All cycles are translated +// to new cycles in the product. :(scenario deep_copy_number) def main [ diff --git a/074channel.mu b/074channel.mu index c7e3dae0..361fae1a 100644 --- a/074channel.mu +++ b/074channel.mu @@ -1,12 +1,17 @@ # Mu synchronizes using channels rather than locks, like Erlang and Go. # # The two ends of a channel will usually belong to different routines, but -# each end should only be used by a single one. Don't try to read from or -# write to it from multiple routines at once. +# each end should (currently) only be used by a single one. Don't try to read +# from or write to it from multiple routines at once. # -# The key property of channels is that writing to a full channel or reading -# from an empty one will put the current routine in 'waiting' state until the -# operation can be completed. +# Key properties of channels: +# +# a) Writing to a full channel or reading from an empty one will put the +# current routine in 'waiting' state until the operation can be completed. +# +# b) Writing to a channel implicitly performs a deep copy, to prevent +# addresses from being shared between routines, thereby causing race +# conditions. scenario channel [ run [ @@ -71,10 +76,11 @@ def write out:address:sink:_elem, val:_elem -> out:address:sink:_elem [ full-address:location <- get-location *chan, first-full:offset wait-for-location full-address } - # store val + # store a deep copy of val circular-buffer:address:array:_elem <- get *chan, data:offset free:number <- get *chan, first-free:offset - *circular-buffer <- put-index *circular-buffer, free, val + val-copy:_elem <- deep-copy val # on this instruction rests all Mu's concurrency-safety + *circular-buffer <- put-index *circular-buffer, free, val-copy # mark its slot as filled free <- add free, 1 { |