about summary refs log tree commit diff stats
path: root/mu.arc.t
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-01-25 16:40:11 -0800
committerKartik K. Agaram <vc@akkartik.com>2015-01-25 16:40:11 -0800
commit4f686be1ebb6713933298531531fbef0898c6b2b (patch)
tree3a46478c288a8b6fa835c16882363f41a5c891f4 /mu.arc.t
parentd1f57fa1ab95a36a562d2b75a064bc387bd2d5d3 (diff)
downloadmu-4f686be1ebb6713933298531531fbef0898c6b2b.tar.gz
623 - 'nochange' to guard against race conditions
I dunno, this may all be a wild goose chase. I haven't been disciplined
in tagging in-out arguments in 'read-move' and its helpers. Maybe I
should just drop those 'nochange' oargs in 'read' and 'write'. Maybe I
should reserve output args only for return values that callers might
actually care about, and use more conventional metadata like 'const' or
'unique' or 'inout' on other args.
Diffstat (limited to 'mu.arc.t')
-rw-r--r--mu.arc.t76
1 files changed, 53 insertions, 23 deletions
diff --git a/mu.arc.t b/mu.arc.t
index 9c321af6..f6ba0534 100644
--- a/mu.arc.t
+++ b/mu.arc.t
@@ -1321,6 +1321,7 @@
                          4 1  5 3  6 4))
   (prn "F - 'reply' permits a function to return multiple values at once"))
 
+; 'prepare-reply' is useful for doing cleanup before exiting a function
 (reset)
 (new-trace "new-fn-prepare-reply")
 (add-code
@@ -1344,6 +1345,35 @@
                          4 1  5 3  6 4))
   (prn "F - without args, 'reply' returns values from previous 'prepare-reply'."))
 
+; When you have arguments that are both read from and written to, include them
+; redundantly in both ingredients and results. That'll help tools track what
+; changed.
+
+; To enforce that the result and ingredient must always match, use the
+; 'nochange' property. Results with 'nochange' properties should only be
+; copied to themselves.
+(reset)
+(new-trace "new-fn-nochange")
+(add-code
+  '((function test1 [
+      ; increment the contents of an address
+      (default-space:space-address <- new space:literal 2:literal)
+      (x:integer-address <- next-input)
+      (x:integer-address/deref <- add x:integer-address/deref 1:literal)
+      (reply x:integer-address/nochange)
+    ])
+    (function main [
+      (1:integer-address <- new integer:literal)
+      (1:integer-address/deref <- copy 0:literal)
+      (2:integer-address <- test1 1:integer-address)
+    ])))
+(run 'main)
+(let routine (car completed-routines*)
+;?   (prn rep.routine!error) ;? 1
+  (when (no rep.routine!error)
+    (prn "F - 'nochange' results are never copied to other locations")))
+;? (quit) ;? 1
+
 )  ; section 20
 
 (section 11
@@ -3039,7 +3069,7 @@
       (1:channel-address <- init-channel 3:literal)
       (2:integer <- copy 34:literal)
       (3:tagged-value <- save-type 2:integer)
-      (1:channel-address/deref <- write 1:channel-address 3:tagged-value)
+      (1:channel-address/deref/nochange <- write 1:channel-address 3:tagged-value)
       (5:integer <- get 1:channel-address/deref first-full:offset)
       (6:integer <- get 1:channel-address/deref first-free:offset)
      ])))
@@ -3064,8 +3094,8 @@
       (1:channel-address <- init-channel 3:literal)
       (2:integer <- copy 34:literal)
       (3:tagged-value <- save-type 2:integer)
-      (1:channel-address/deref <- write 1:channel-address 3:tagged-value)
-      (5:tagged-value 1:channel-address/deref <- read 1:channel-address)
+      (1:channel-address/deref/nochange <- write 1:channel-address 3:tagged-value)
+      (5:tagged-value 1:channel-address/deref/nochange <- read 1:channel-address)
       (7:integer <- maybe-coerce 5:tagged-value integer:literal)
       (8:integer <- get 1:channel-address/deref first-full:offset)
       (9:integer <- get 1:channel-address/deref first-free:offset)
@@ -3089,13 +3119,13 @@
       ; write a value
       (2:integer <- copy 34:literal)
       (3:tagged-value <- save-type 2:integer)
-      (1:channel-address/deref <- write 1:channel-address 3:tagged-value)
+      (1:channel-address/deref/nochange <- write 1:channel-address 3:tagged-value)
       ; first-free will now be 1
       (5:integer <- get 1:channel-address/deref first-free:offset)
       ; read one value
-      (_ 1:channel-address/deref <- read 1:channel-address)
+      (_ 1:channel-address/deref/nochange <- read 1:channel-address)
       ; write a second value; verify that first-free wraps around to 0.
-      (1:channel-address/deref <- write 1:channel-address 3:tagged-value)
+      (1:channel-address/deref/nochange <- write 1:channel-address 3:tagged-value)
       (6:integer <- get 1:channel-address/deref first-free:offset)
      ])))
 ;? (set dump-trace*)
@@ -3115,15 +3145,15 @@
       ; write a value
       (2:integer <- copy 34:literal)
       (3:tagged-value <- save-type 2:integer)
-      (1:channel-address/deref <- write 1:channel-address 3:tagged-value)
+      (1:channel-address/deref/nochange <- write 1:channel-address 3:tagged-value)
       ; read one value
-      (_ 1:channel-address/deref <- read 1:channel-address)
+      (_ 1:channel-address/deref/nochange <- read 1:channel-address)
       ; first-full will now be 1
       (5:integer <- get 1:channel-address/deref first-full:offset)
       ; write a second value
-      (1:channel-address/deref <- write 1:channel-address 3:tagged-value)
+      (1:channel-address/deref/nochange <- write 1:channel-address 3:tagged-value)
       ; read second value; verify that first-full wraps around to 0.
-      (_ 1:channel-address/deref <- read 1:channel-address)
+      (_ 1:channel-address/deref/nochange <- read 1:channel-address)
       (6:integer <- get 1:channel-address/deref first-full:offset)
      ])))
 ;? (set dump-trace*)
@@ -3156,7 +3186,7 @@
       (1:channel-address <- init-channel 3:literal)
       (2:integer <- copy 34:literal)
       (3:tagged-value <- save-type 2:integer)
-      (1:channel-address/deref <- write 1:channel-address 3:tagged-value)
+      (1:channel-address/deref/nochange <- write 1:channel-address 3:tagged-value)
       (5:boolean <- empty? 1:channel-address/deref)
       (6:boolean <- full? 1:channel-address/deref)
      ])))
@@ -3174,7 +3204,7 @@
       (1:channel-address <- init-channel 1:literal)
       (2:integer <- copy 34:literal)
       (3:tagged-value <- save-type 2:integer)
-      (1:channel-address/deref <- write 1:channel-address 3:tagged-value)
+      (1:channel-address/deref/nochange <- write 1:channel-address 3:tagged-value)
       (5:boolean <- empty? 1:channel-address/deref)
       (6:boolean <- full? 1:channel-address/deref)
      ])))
@@ -3192,9 +3222,9 @@
       (1:channel-address <- init-channel 3:literal)
       (2:integer <- copy 34:literal)
       (3:tagged-value <- save-type 2:integer)
-      (1:channel-address/deref <- write 1:channel-address 3:tagged-value)
-      (1:channel-address/deref <- write 1:channel-address 3:tagged-value)
-      (_ 1:channel-address/deref <- read 1:channel-address)
+      (1:channel-address/deref/nochange <- write 1:channel-address 3:tagged-value)
+      (1:channel-address/deref/nochange <- write 1:channel-address 3:tagged-value)
+      (_ 1:channel-address/deref/nochange <- read 1:channel-address)
       (5:boolean <- empty? 1:channel-address/deref)
       (6:boolean <- full? 1:channel-address/deref)
      ])))
@@ -3213,7 +3243,7 @@
       (2:integer <- copy 34:literal)
       (3:tagged-value <- save-type 2:integer)
       (1:channel-address/deref <- write 1:channel-address 3:tagged-value)
-      (_ 1:channel-address/deref <- read 1:channel-address)
+      (_ 1:channel-address/deref/nochange <- read 1:channel-address)
       (5:boolean <- empty? 1:channel-address/deref)
       (6:boolean <- full? 1:channel-address/deref)
      ])))
@@ -3233,7 +3263,7 @@
   '((function main [
       (1:channel-address <- init-channel 3:literal)
       ; channel is empty, but receives a read
-      (2:tagged-value 1:channel-address/deref <- read 1:channel-address)
+      (2:tagged-value 1:channel-address/deref/nochange <- read 1:channel-address)
      ])))
 ;? (set dump-trace*)
 ;? (= dump-trace* (obj whitelist '("run" "schedule")))
@@ -3257,9 +3287,9 @@
       (1:channel-address <- init-channel 1:literal)
       (2:integer <- copy 34:literal)
       (3:tagged-value <- save-type 2:integer)
-      (1:channel-address/deref <- write 1:channel-address 3:tagged-value)
+      (1:channel-address/deref/nochange <- write 1:channel-address 3:tagged-value)
       ; channel has capacity 1, but receives a second write
-      (1:channel-address/deref <- write 1:channel-address 3:tagged-value)
+      (1:channel-address/deref/nochange <- write 1:channel-address 3:tagged-value)
      ])))
 ;? (set dump-trace*)
 ;? (= dump-trace* (obj whitelist '("run" "schedule" "addr")))
@@ -3284,14 +3314,14 @@
       (default-space:space-address <- new space:literal 30:literal)
       (chan:channel-address <- init-channel 3:literal)  ; create a channel
       (fork producer:fn nil:literal/globals nil:literal/limit chan:channel-address)  ; fork a routine to produce a value in it
-      (1:tagged-value/raw <- read chan:channel-address)  ; wait for input on channel
+      (1:tagged-value/raw/nochange <- read chan:channel-address)  ; wait for input on channel
      ])
     (function producer [
       (default-space:space-address <- new space:literal 30:literal)
       (n:integer <- copy 24:literal)
       (ochan:channel-address <- next-input)
       (x:tagged-value <- save-type n:integer)
-      (ochan:channel-address/deref <- write ochan:channel-address x:tagged-value)
+      (ochan:channel-address/deref/nochange <- write ochan:channel-address x:tagged-value)
      ])))
 ;? (set dump-trace*)
 ;? (= dump-trace* (obj whitelist '("schedule" "run" "addr")))
@@ -3311,13 +3341,13 @@
       (default-space:space-address <- new space:literal 30:literal)
       (1:channel-address <- init-channel 3:literal)  ; create a channel
       (fork producer:fn default-space:space-address/globals nil:literal/limit)  ; pass it as a global to another routine
-      (1:tagged-value/raw <- read 1:channel-address)  ; wait for input on channel
+      (1:tagged-value/raw/nochange <- read 1:channel-address)  ; wait for input on channel
      ])
     (function producer [
       (default-space:space-address <- new space:literal 30:literal)
       (n:integer <- copy 24:literal)
       (x:tagged-value <- save-type n:integer)
-      (1:channel-address/space:global/deref <- write 1:channel-address/space:global x:tagged-value)
+      (1:channel-address/space:global/deref/nochange <- write 1:channel-address/space:global x:tagged-value)
      ])))
 (run 'consumer)
 (each routine completed-routines*