Active object: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) m (→{{header|Perl 6}}: eliminate a race) |
|||
Line 1,865: | Line 1,865: | ||
After 2 seconds: -0.0005555887464620366 |
After 2 seconds: -0.0005555887464620366 |
||
f(0): 0</pre> |
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}}== |
=={{header|PicoLisp}}== |