Active object: Difference between revisions

m (→‎{{header|Perl 6}}: eliminate a race)
Line 1,865:
After 2 seconds: -0.0005555887464620366
f(0): 0</pre>
 
=={{header|Phix}}==
Note that in Phix you cannot pass a variable to another procedure and have it "change under your feet".<br>
The copy-on-write semantics mean it would not have any effect, in that the original would be preserved
(deemed in phix to be a "very good thing") while the value passed along, a shared reference until it gets
modified and a copy made, would most likely simply be discarded, unless explicitly returned and stored,
which obviously cannot be done from a separate thread.
Instead we pass around an index (dx) as a way of emulating the "pointer references" of other languages.
 
If anything phix requires more locking that other languages due to the hidden shared reference counts.<br>
Just lock everything, it is not that hard, and you should never need much more than the stuff below.
<lang Phix>sequence x = {}
enum TERMINATE, INTERVAL, KFUN, VALUE, T0, K0, ID, ISIZE=$
integer xlock = init_cs()
 
function zero(atom /*t*/) return 0 end function
function sine(atom t) return sin(2*PI*0.5*t) end function
 
procedure update(integer dx)
enter_cs(xlock)
atom t1 = time(),
k1 = call_func(x[dx][KFUN],{t1})
x[dx][VALUE] += (k1 + x[dx][K0]) * (t1 - x[dx][T0]) / 2
x[dx][T0] = t1
x[dx][K0] = k1
leave_cs(xlock)
end procedure
 
procedure tick(integer dx)
while not x[dx][TERMINATE] do
sleep(x[dx][INTERVAL])
update(dx)
end while
end procedure
 
function new_integrator(integer rid, atom interval)
x = append(x,repeat(0,ISIZE))
integer dx = length(x)
x[dx][TERMINATE] = false
x[dx][INTERVAL] = interval
x[dx][KFUN] = rid
x[dx][T0] = time()
update(dx)
x[dx][ID] = create_thread(routine_id("tick"),{dx})
return dx
end function
 
procedure set_input(integer dx, rid)
enter_cs(xlock)
x[dx][KFUN] = rid
x[dx][K0] = 0
leave_cs(xlock)
end procedure
 
function get_output(integer dx)
enter_cs(xlock)
atom v = x[dx][VALUE]
leave_cs(xlock)
return v
end function
 
procedure stop_integrator(integer dx)
x[dx][TERMINATE] = true
wait_thread(x[dx][ID])
end procedure
 
puts(1,"")
integer dx = new_integrator(routine_id("sine"),0.01)
sleep(2)
printf(1,"%f\n",get_output(dx))
set_input(dx,routine_id("zero"))
sleep(0.5)
printf(1,"%f\n",get_output(dx))
stop_integrator(dx)</lang>
{{out}}
<pre>
-0.00326521
0.00196980
</pre>
 
=={{header|PicoLisp}}==
7,795

edits