Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot//simgrid/simgrid
[simgrid.git] / examples / simdag / scheduling / minmin_test.c
index 194cb28..4131089 100644 (file)
@@ -20,6 +20,7 @@ typedef struct _WorkstationAttribute *WorkstationAttribute;
 struct _WorkstationAttribute {
   /* Earliest time at wich a workstation is ready to execute a task */
   double available_at;
+  SD_task_t last_scheduled_task;
 };
 
 static void SD_workstation_allocate_attribute(SD_workstation_t workstation)
@@ -51,6 +52,19 @@ static void SD_workstation_set_available_at(SD_workstation_t workstation,
   SD_workstation_set_data(workstation, attr);
 }
 
+static SD_task_t SD_workstation_get_last_scheduled_task( SD_workstation_t workstation){
+  WorkstationAttribute attr =
+      (WorkstationAttribute) SD_workstation_get_data(workstation);
+  return attr->last_scheduled_task;
+}
+
+static void SD_workstation_set_last_scheduled_task(SD_workstation_t workstation,
+    SD_task_t task){
+  WorkstationAttribute attr =
+      (WorkstationAttribute) SD_workstation_get_data(workstation);
+  attr->last_scheduled_task=task;
+  SD_workstation_set_data(workstation, attr);
+}
 
 static xbt_dynar_t get_ready_tasks(xbt_dynar_t dax)
 {
@@ -80,12 +94,11 @@ static double finish_on_at(SD_task_t task, SD_workstation_t workstation)
   SD_task_t parent, grand_parent;
   xbt_dynar_t parents, grand_parents;
 
-  int grand_parent_nworkstations;
   SD_workstation_t *grand_parent_workstation_list;
 
   parents = SD_task_get_parents(task);
 
-  if (xbt_dynar_length(parents)) {
+  if (!xbt_dynar_is_empty(parents)) {
     /* compute last_data_available */
     last_data_available = -1.0;
     xbt_dynar_foreach(parents, i, parent) {
@@ -100,8 +113,6 @@ static double finish_on_at(SD_task_t task, SD_workstation_t workstation)
         }
         xbt_dynar_get_cpy(grand_parents, 0, &grand_parent);
 
-        grand_parent_nworkstations =
-            SD_task_get_workstation_count(grand_parent);
         grand_parent_workstation_list =
             SD_task_get_workstation_list(grand_parent);
         /* Estimate the redistribution time from this parent */
@@ -236,9 +247,9 @@ static void output_xml(FILE * out, xbt_dynar_t dax)
 
 int main(int argc, char **argv)
 {
-  unsigned int cursor, selected_idx = 0;
+  unsigned int cursor;
   double finish_time, min_finish_time = -1.0;
-  SD_task_t task, selected_task = NULL;
+  SD_task_t task, selected_task = NULL, last_scheduled_task;
   xbt_dynar_t ready_tasks;
   SD_workstation_t workstation, selected_workstation = NULL;
   int total_nworkstations = 0;
@@ -295,7 +306,7 @@ int main(int argc, char **argv)
   while (!xbt_dynar_is_empty((changed = SD_simulate(-1.0)))) {
     /* Get the set of ready tasks */
     ready_tasks = get_ready_tasks(dax);
-    if (!xbt_dynar_length(ready_tasks)) {
+    if (xbt_dynar_is_empty(ready_tasks)) {
       xbt_dynar_free_container(&ready_tasks);
       xbt_dynar_free_container(&changed);
       /* there is no ready task, let advance the simulation */
@@ -314,7 +325,6 @@ int main(int argc, char **argv)
         min_finish_time = finish_time;
         selected_task = task;
         selected_workstation = workstation;
-        selected_idx = cursor;
       }
     }
 
@@ -322,6 +332,31 @@ int main(int argc, char **argv)
           SD_workstation_get_name(selected_workstation));
 
     SD_task_schedulel(selected_task, 1, selected_workstation);
+
+    /*
+     * SimDag allows tasks to be executed concurrently when they can by default.
+     * Yet schedulers take decisions assuming that tasks wait for resource
+     * availability to start.
+     * The solution (well crude hack is to keep track of the last task scheduled
+     * on a workstation and add a special type of dependency if needed to
+     * force the sequential execution meant by the scheduler.
+     * If the last scheduled task is already done, has failed or is a 
+     * predecessor of the current task, no need for a new dependency
+    */
+
+    last_scheduled_task = 
+      SD_workstation_get_last_scheduled_task(selected_workstation);
+    if (last_scheduled_task && 
+  (SD_task_get_state(last_scheduled_task) != SD_DONE) &&
+  (SD_task_get_state(last_scheduled_task) != SD_FAILED) &&
+  !SD_task_dependency_exists(
+     SD_workstation_get_last_scheduled_task(selected_workstation),
+     selected_task))
+      SD_task_dependency_add("resource", NULL,
+           last_scheduled_task, selected_task);
+    
+    SD_workstation_set_last_scheduled_task(selected_workstation, selected_task);
+    
     SD_workstation_set_available_at(selected_workstation, min_finish_time);
 
     xbt_dynar_free_container(&ready_tasks);
@@ -339,7 +374,7 @@ int main(int argc, char **argv)
       ("------------------- Produce the trace file---------------------------");
   XBT_INFO("Producing the trace of the run into %s", tracefilename);
   out = fopen(tracefilename, "w");
-  xbt_assert1(out, "Cannot write to %s", tracefilename);
+  xbt_assert(out, "Cannot write to %s", tracefilename);
   free(tracefilename);
 
   output_xml(out, dax);