about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2014-11-04 00:01:57 -0800
committerKartik K. Agaram <vc@akkartik.com>2014-11-04 00:01:57 -0800
commit4dbf55edbd3fd6a62601bcf8883c821efcd75d5e (patch)
treecf59ef932c928755b1cc6834bd3e2d11bd3dbebe
parent02b89cc7be8e7c977d7f1228e9f7f3364978b2c6 (diff)
downloadmu-4dbf55edbd3fd6a62601bcf8883c821efcd75d5e.tar.gz
221
-rw-r--r--mu.arc19
-rw-r--r--mu.arc.t15
2 files changed, 34 insertions, 0 deletions
diff --git a/mu.arc b/mu.arc
index 33622255..a75aab00 100644
--- a/mu.arc
+++ b/mu.arc
@@ -53,10 +53,16 @@
               ; tagged-values are the foundation of dynamic types
               tagged-value (obj size 2  record t  elems '(type location))
               tagged-value-address (obj size 1  address t  elem 'tagged-value)
+              tagged-value-array (obj array t  elem 'tagged-value)
+              tagged-value-array-address (obj size 1  address t  elem 'tagged-value-array)
+              tagged-value-array-address-address (obj size 1  address t  elem 'tagged-value-array-address)
               ; heterogeneous lists
               list (obj size 2  record t  elems '(tagged-value list-address))
               list-address (obj size 1  address t  elem 'list)
               list-address-address (obj size 1  address t  elem 'list-address)
+              ; parallel routines use channels to synchronize
+              channel (obj size 3  record t  elems '(integer integer tagged-value-array-address)  fields '(first-full first-free circular-buffer))
+              channel-address (obj size 1  address t  elem 'channel)
               ; editor
               line (obj array t  elem 'character)
               line-address (obj size 1  address t  elem 'line)
@@ -769,6 +775,19 @@
   ((new-list-result list-address) <- list-next (new-list-result list-address))  ; memory leak
   (reply (new-list-result list-address)))
 
+(init-fn new-channel
+  ((default-scope scope-address) <- new (scope literal) (30 literal))
+  ((capacity integer) <- arg)
+  ((buffer-address tagged-value-array-address) <- new (tagged-value-array literal) (capacity integer))
+  ((result channel-address) <- new (channel literal))
+  ((full integer-address) <- get-address (result channel-address deref) (first-full offset))
+  ((full integer-address deref) <- copy (0 literal))
+  ((free integer-address) <- get-address (result channel-address deref) (first-free offset))
+  ((free integer-address deref) <- copy (0 literal))
+  ((channel-buffer-address tagged-value-array-address-address) <- get-address (result channel-address deref) (circular-buffer offset))
+  ((channel-buffer-address tagged-value-array-address-address deref) <- copy (buffer-address tagged-value-array-address))
+  (reply (result channel-address)))
+
 ; drop all traces while processing above functions
 (on-init
   (= traces* (queue)))
diff --git a/mu.arc.t b/mu.arc.t
index 32960298..4d77eb6b 100644
--- a/mu.arc.t
+++ b/mu.arc.t
@@ -1691,4 +1691,19 @@
             ((3 integer) <- copy (6 literal))))
   (prn "F - convert-quotes can handle 'defer'"))
 
+; synchronization using channels like in Erlang or Go
+
+(reset)
+(new-trace "channel-new")
+(add-fns
+  '((main
+      ((1 channel-address) <- new-channel (3 literal)))))
+;? (set dump-trace*)
+(let before Memory-in-use-until
+  (run 'main)
+;?   (prn memory*)
+  (if (or (~is 0 (memory* memory*.1))
+          (~is 0 (memory* (+ 1 memory*.1))))
+    (prn "F - 'new-channel' initializes 'first-full and 'first-free to 0")))
+
 (reset)  ; end file with this to persist the trace for the final test