RosettaCodeData/Task/Checkpoint-synchronization/Phix/checkpoint-synchronization....

51 lines
1.2 KiB
Plaintext

-- demo\rosetta\checkpoint_synchronisation.exw
constant NPARTS = 3
integer workers = 0
sequence waiters = {}
bool terminate = false
procedure checkpoint(integer task_id)
if length(waiters)+1=NPARTS or terminate then
printf(1,"checkpoint\n")
for i=1 to length(waiters) do
task_schedule(waiters[i],1)
end for
waiters = {}
else
waiters &= task_id
task_suspend(task_id)
task_yield()
end if
end procedure
procedure worker(string name)
printf(1,"worker %s running\n",{name})
while not terminate do
printf(1,"worker %s begins part\n",{name})
task_delay(rnd())
printf(1,"worker %s completes part\n",{name})
checkpoint(task_self())
if rnd()>0.95 then exit end if
task_delay(rnd())
end while
printf(1,"worker %s leaves\n",{name})
workers -= 1
end procedure
string name = "A"
while get_key()!=#1B do -- (key escape to shut down)
if workers<NPARTS then
integer task_id = task_create(routine_id("worker"),{name})
task_schedule(task_id,1)
name[1] += 1
workers += 1
end if
task_yield()
end while
printf(1,"escape keyed\n")
terminate = true
while workers>0 do
task_yield()
end while