with Paes_Utilities; use Paes_Utilities; procedure paes_general_form is -- for parallel execution -- a ToDo and a Done lists, protected by a mutex ToDoSolList : array (0 .. MAX_SLAVES) of solution; ToDoIndex : integer := 0; DoneSolList : array (0 .. MAX_SLAVES) of solution; DoneIndex : integer := 0; task type Mutex is entry P; entry V; entry E; end Mutex; task body Mutex is finished : boolean := false; begin loop select accept P; or accept E do finished := true; -- loop end E; end select; if (not finished) then accept V; else exit; end if; end loop; end Mutex; DoneSolMutex : mutex; TodoSolMutex : mutex; task type slave_task; task body slave_task is found : integer; tomute : solution; eidx : integer; begin loop loop found := 0; ToDoSolMutex.P; if ToDoIndex > 0 then ToDoIndex := ToDoIndex - 1; tomute := ToDoSolList (ToDoIndex); found := 1; end if; ToDoSolMutex.V; if found = 1 then exit; end if; delay 0.5; end loop; eidx := tomute.grid_loc; if eidx < 0 then -- marked for ending task exit; end if; mutate (tomute, eidx); evaluate (tomute, eidx); DoneSolMutex.P; DoneSolList (DoneIndex) := tomute; DoneIndex := DoneIndex + 1; DoneSolMutex.V; end loop; --Put_Line("I am dead"); end slave_task; RunningSlaves : array (1 .. MAX_SLAVES) of slave_task; mfound : integer; begin -- Initializing the current solution c, -- the initial_system -- and the list of all possible Fitness functions init; add_to_archive(c); update_grid(c); ------------------------- -- begin the main loop -- ------------------------- --Parallel running of first mutations --useless tasks are told to die if slaves > 0 then ToDoSolMutex.P; for i in 0..MAX_SLAVES-1 loop ToDoSolList(i) := c; if i < slaves then ToDoSolList(i).grid_loc := i; else ToDoSolList(i).grid_loc := -1; end if; end loop; ToDoIndex := MAX_SLAVES; ToDoSolMutex.V; else --killing all tasks (except mutex) ToDoSolMutex.P; for i in 0..MAX_SLAVES-1 loop ToDoSolList(i).grid_loc := -1; end loop; ToDoIndex := MAX_SLAVES; ToDoSolMutex.V; end if; for i in 0..iterations-1 loop -- copy the current solution m := c; -- in sequential: -- mutate (m, 0); -- in parallel, when deployed: -- run_mutate(m, i); -- for test of reentrant code if slaves < 1 then mutate(m, 0); --sequential evaluate(m,0); else mfound := 0; loop DoneSolMutex.P; if DoneIndex > 0 then DoneIndex := DoneIndex - 1; m := DoneSolList(DoneIndex); mfound := 1; end if; DoneSolMutex.V; if mfound = 1 then exit; end if; delay 0.5; end loop; end if; Selection_and_archiving; if slaves > 0 then if i <= (iterations - slaves) then ToDoSolMutex.P; ToDoSolList(ToDoIndex) := c; ToDoSolList(ToDoIndex).grid_loc := slaves + i; ToDoIndex := ToDoIndex + 1; ToDoSolMutex.V; end if; end if; end loop; --send invalid task to end the slaves if slaves > 0 then ToDoSolMutex.P; for i in 0..slaves-1 loop ToDoSolList(i) := c; ToDoSolList(i).grid_loc := -1; end loop; ToDoIndex := slaves; ToDoSolMutex.V; end if; -- end all tasks ToDoSolMutex.E; DoneSolMutex.E; end paes_general_form;