private define slave_task (s,k) { send_msg (s, SLAVE_READY); forever { variable r = recv_objs (s); variable index = r[0]; if (index < 0) break; vmessage ("\n Slave %d is performing call %d\n", k, index); sleep (int(urand()*6)); send_msg (s, SLAVE_RESULT); send_objs (s, k, index, index^2); } return 0; } private define maybe_finished (slaves) { variable s; foreach s (slaves) { if (s.status != SLAVE_READY) return; } foreach s (slaves) { send_objs (s, -1); } } private variable Task_List; private define send_next_task (s) { if (Task_List.index < length(Task_List.value)) { send_objs (s, Task_List.index); Task_List.index++; s.status = SLAVE_RUNNING; } else maybe_finished (s); } private define recv_slave_result (s) { variable objs = recv_objs(s); Task_List.results[objs[1]] = objs[2]; vmessage ("\n Thanks, slave %d, for doing call %d \n",objs[0],objs[1]); s.status = SLAVE_READY; return 0; } private define slave_handler(s,msg) { switch (msg.type) { case SLAVE_READY: send_next_task (s); } { case SLAVE_RESULT: () = recv_slave_result(s); send_next_task(s); } } define slave_test () { variable num_tasks = 10; Task_List = struct {index, value, results}; Task_List.index = 0; Task_List.value = [0:num_tasks-1]; Task_List.results = Double_Type[length(Task_List.value)]; variable num_slaves = min ([qualifier ("num_slaves", _num_cpus()), num_tasks]); if (qualifier_exists ("serial")) num_slaves=1; variable k, s, slaves = new_slave_list (); _for k (0, num_slaves-1, 1) { s = fork_slave (&slave_task, k); append_slave (slaves, s); } manage_slaves (slaves, &slave_handler ;; __qualifiers); vmessage ("\n Here are the answers you seek:\n\n"); print(Task_List.results); Task_List.index=0; }