Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Update function SD_simulate.
authorthiery <thiery@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Mon, 26 Jun 2006 08:33:54 +0000 (08:33 +0000)
committerthiery <thiery@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Mon, 26 Jun 2006 08:33:54 +0000 (08:33 +0000)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@2429 48e7efb5-ca39-0410-a469-dd3cf9ba447f

src/simdag/private.h
src/simdag/sd_global.c
src/simdag/sd_task.c
testsuite/simdag/sd_test.c

index d8bf9f7..eafc778 100644 (file)
@@ -15,7 +15,6 @@ typedef struct SD_global {
   xbt_dict_t workstations; /* workstation list */
   int workstation_count; /* number of workstations */
   xbt_dict_t links; /* link list */
-  xbt_dynar_t tasks; /* task list */
   int watch_point_reached; /* has a task just reached a watch point? */
   
   /* task state sets */
@@ -50,6 +49,7 @@ typedef struct SD_task {
   double amount;
   surf_action_t surf_action;
   unsigned short watch_points;
+  int state_changed;
 
   /* dependencies */
   xbt_dynar_t tasks_before;
@@ -80,6 +80,8 @@ void __SD_link_destroy(void *link);
 SD_workstation_t __SD_workstation_create(void *surf_workstation, void *data);
 void __SD_workstation_destroy(void *workstation);
 
+void __SD_task_set_state(SD_task_t task, e_SD_task_state_t new_state);
 surf_action_t __SD_task_run(SD_task_t task);
+void __SD_task_remove_dependencies(SD_task_t task);
 
 #endif
index 254f7c0..7c153b4 100644 (file)
@@ -4,6 +4,9 @@
 #include "xbt/dynar.h"
 #include "surf/surf.h"
 
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(sd_kernel, msg,
+                               "Logging specific to SimDag (kernel)");
+
 SD_global_t sd_global = NULL;
 
 /* Initialises SD internal data. This function should be called before any other SD function.
@@ -15,7 +18,6 @@ void SD_init(int *argc, char **argv) {
   sd_global->workstations = xbt_dict_new();
   sd_global->workstation_count = 0;
   sd_global->links = xbt_dict_new();
-  sd_global->tasks = xbt_dynar_new(sizeof(SD_task_t), NULL);
   sd_global->watch_point_reached = 0;
 
   s_SD_task_t task;
@@ -69,42 +71,69 @@ SD_task_t* SD_simulate(double how_long)
 
   double total_time = 0.0; /* we stop the simulation when total_time >= how_long */
   double elapsed_time = 0.0;
-  int i;
   SD_task_t task;
-  surf_action_t surf_action;
+  surf_action_t action;
+
+  /* create the array that will be returned */
+  const int task_number = xbt_swag_size(sd_global->scheduled_task_set) + xbt_swag_size(sd_global->running_task_set);
+  SD_task_t *changed_tasks = xbt_new0(SD_task_t, task_number + 1);
+  changed_tasks[task_number] = NULL;
+  int changed_task_number = 0;
 
   surf_solve(); /* Takes traces into account. Returns 0.0 */
 
+  sd_global->watch_point_reached = 0;
+
   /* main loop */
   while (elapsed_time >= 0.0 && total_time < how_long && !sd_global->watch_point_reached) {
-    for (i = 0 ; i < xbt_dynar_length(sd_global->tasks); i++) {
-      xbt_dynar_get_cpy(sd_global->tasks, i, &task);
-      printf("Examining task '%s'...\n", SD_task_get_name(task));
-
-      /* if the task is scheduled and the dependencies are satisfied,
-        we can execute the task */
-      if (SD_task_get_state(task) == SD_SCHEDULED) {
-       printf("Task '%s' is scheduled.\n", SD_task_get_name(task));
-
-       if (xbt_dynar_length(task->tasks_before) == 0) {
-         printf("The dependencies are satisfied. Executing task '%s'\n", SD_task_get_name(task));
-         surf_action = __SD_task_run(task);
-       }
-       else {
-         printf("Cannot execute task '%s' because some depencies are not satisfied.\n", SD_task_get_name(task));
-       }
+
+    /* explore the scheduled tasks */
+    xbt_swag_foreach(task, sd_global->scheduled_task_set) {
+      INFO1("Examining task '%s'...", SD_task_get_name(task));
+      task->state_changed = 0;
+      if (xbt_dynar_length(task->tasks_before) == 0) {
+       INFO1("The dependencies are satisfied. Executing task '%s'", SD_task_get_name(task));
+       action = __SD_task_run(task);
+       surf_workstation_resource->common_public->action_set_data(action, task);
+       task->state_changed = 1;
+       changed_tasks[changed_task_number++] = task;
       }
       else {
-       printf("Task '%s' is not scheduled. Nothing to do.\n", SD_task_get_name(task));
+       INFO1("Cannot execute task '%s' now because some depencies are not satisfied.", SD_task_get_name(task));
       }
     }
+
     elapsed_time = surf_solve();
     if (elapsed_time > 0.0)
       total_time += elapsed_time;
-    printf("Total time: %f\n", total_time);
+    /*    INFO1("Total time: %f", total_time);*/
+
+    while ((action = xbt_swag_extract(surf_workstation_resource->common_public->states.done_action_set))) {
+      task = action->data;
+      INFO1("Task '%s' done", SD_task_get_name(task));
+      __SD_task_set_state(task, SD_DONE);
+      __SD_task_remove_dependencies(task);
+      if (!task->state_changed) {
+       task->state_changed = 1;
+       changed_tasks[changed_task_number++] = task;
+      }
+    }
+
+    while ((action = xbt_swag_extract(surf_workstation_resource->common_public->states.failed_action_set))) {
+      task = action->data;
+      INFO1("Task '%s' failed", SD_task_get_name(task));
+      __SD_task_set_state(task, SD_FAILED);
+      if (!task->state_changed) {
+       task->state_changed = 1;
+       changed_tasks[changed_task_number++] = task;
+      }
+    }
   }
 
-  return NULL;
+  INFO0("Simulation finished");
+
+  INFO1("Number of tasks whose state has changed: %d", changed_task_number);
+  return changed_tasks;
 }
 
 void SD_test() {
@@ -155,7 +184,6 @@ void SD_exit() {
   if (sd_global != NULL) {
     xbt_dict_free(&sd_global->workstations);
     xbt_dict_free(&sd_global->links);
-    xbt_dynar_free(&sd_global->tasks);
     xbt_free(sd_global);
 
     xbt_swag_free(sd_global->not_scheduled_task_set);
index d9b5ed6..1e91daf 100644 (file)
@@ -3,8 +3,6 @@
 #include "xbt/sysdep.h"
 #include "xbt/dynar.h"
 
-static void __SD_task_set_state(SD_task_t task, e_SD_task_state_t new_state);
-
 /* Creates a task.
  */
 SD_task_t SD_task_create(const char *name, void *data, double amount) {
@@ -26,6 +24,7 @@ SD_task_t SD_task_create(const char *name, void *data, double amount) {
   task->amount = amount;
   task->surf_action = NULL;
   task->watch_points = 0;
+  task->state_changed = 0;
 
   /* dependencies */
   task->tasks_before = xbt_dynar_new(sizeof(SD_dependency_t), NULL);
@@ -38,8 +37,6 @@ SD_task_t SD_task_create(const char *name, void *data, double amount) {
   task->communication_amount = NULL;
   task->rate = 0;
 
-  xbt_dynar_push(sd_global->tasks, &task);
-
   return task;
 }
 
@@ -70,7 +67,7 @@ e_SD_task_state_t SD_task_get_state(SD_task_t task) {
 
 /* Changes the state of a task. Update the swags and the flag sd_global->watch_point_reached.
  */
-static void __SD_task_set_state(SD_task_t task, e_SD_task_state_t new_state) {
+void __SD_task_set_state(SD_task_t task, e_SD_task_state_t new_state) {
   xbt_swag_remove(task, task->state_set);
   switch (new_state) {
   case SD_NOT_SCHEDULED:
@@ -379,19 +376,9 @@ surf_action_t __SD_task_run(SD_task_t task) {
   return surf_action;
 }
 
-
-/* Destroys a task. The user data (if any) should have been destroyed first.
+/* Remove all dependencies associated with a task. This function is called when the task is done.
  */
-void SD_task_destroy(SD_task_t task) {
-  SD_CHECK_INIT_DONE();
-  xbt_assert0(task != NULL, "Invalid parameter");
-
-  /*printf("Destroying task %s...\n", SD_task_get_name(task));*/
-
-  /* remove the task from SimDag task list */
-  int index = xbt_dynar_search(sd_global->tasks, &task);
-  xbt_dynar_remove_at(sd_global->tasks, index, NULL);
-
+void __SD_task_remove_dependencies(SD_task_t task) {
   /* we must destroy the dependencies carefuly (with SD_dependency_remove)
      because each one is stored twice */
   SD_dependency_t dependency;
@@ -404,6 +391,17 @@ void SD_task_destroy(SD_task_t task) {
     xbt_dynar_get_cpy(task->tasks_after, 0, &dependency);
     SD_task_dependency_remove(dependency->src, dependency->dst);
   }
+}
+
+/* Destroys a task. The user data (if any) should have been destroyed first.
+ */
+void SD_task_destroy(SD_task_t task) {
+  SD_CHECK_INIT_DONE();
+  xbt_assert0(task != NULL, "Invalid parameter");
+
+  /*printf("Destroying task %s...\n", SD_task_get_name(task));*/
+
+  __SD_task_remove_dependencies(task);
 
   /* if the task was scheduled we have to free the scheduling parameters */
   if (SD_task_get_state(task) == SD_SCHEDULED)
@@ -417,5 +415,4 @@ void SD_task_destroy(SD_task_t task) {
   xbt_free(task);
 
   /*printf("Task destroyed.\n");*/
-
 }
index 9445658..bf026bf 100644 (file)
@@ -30,52 +30,53 @@ int main(int argc, char **argv) {
   SD_task_t taskA = SD_task_create("Task A", NULL, 10.0);
   SD_task_t taskB = SD_task_create("Task B", NULL, 40.0);
   SD_task_t taskC = SD_task_create("Task C", NULL, 30.0);
+  SD_task_t taskD = SD_task_create("Task D", NULL, 60.0);
   
 
-  SD_task_dependency_add(NULL, NULL, taskA, taskB);
-  SD_task_dependency_add(NULL, NULL, taskA, taskC);
+  SD_task_dependency_add(NULL, NULL, taskB, taskA);
+  SD_task_dependency_add(NULL, NULL, taskC, taskA);
+  SD_task_dependency_add(NULL, NULL, taskD, taskB);
+  SD_task_dependency_add(NULL, NULL, taskD, taskC);
+  /*  SD_task_dependency_add(NULL, NULL, taskA, taskD); /\* deadlock */
 
-  xbt_ex_t ex;
+/*   xbt_ex_t ex; */
 
-  TRY {
-    SD_task_dependency_add(NULL, NULL, taskA, taskA); /* shouldn't work and must raise an exception */
-    xbt_assert0(0, "Hey, I can add a dependency between Task A and Task A!");
-  }
-  CATCH (ex) {
-  }
+/*   TRY { */
+/*     SD_task_dependency_add(NULL, NULL, taskA, taskA); /\* shouldn't work and must raise an exception *\/ */
+/*     xbt_assert0(0, "Hey, I can add a dependency between Task A and Task A!"); */
+/*   } */
+/*   CATCH (ex) { */
+/*   } */
   
-  TRY {
-    SD_task_dependency_add(NULL, NULL, taskA, taskB); /* shouldn't work and must raise an exception */
-    xbt_assert0(0, "Oh oh, I can add an already existing dependency!");
-  }
-  CATCH (ex) {
-  }
-
-  SD_task_dependency_remove(taskA, taskB);
+/*   TRY { */
+/*     SD_task_dependency_add(NULL, NULL, taskA, taskB); /\* shouldn't work and must raise an exception *\/ */
+/*     xbt_assert0(0, "Oh oh, I can add an already existing dependency!"); */
+/*   } */
+/*   CATCH (ex) { */
+/*   } */
+
+/*   SD_task_dependency_remove(taskA, taskB); */
+
+/*   TRY { */
+/*     SD_task_dependency_remove(taskC, taskA); /\* shouldn't work and must raise an exception *\/ */
+/*     xbt_assert0(0, "Dude, I can remove an unknown dependency!"); */
+/*   } */
+/*   CATCH (ex) { */
+/*   } */
+
+/*   TRY { */
+/*     SD_task_dependency_remove(taskC, taskC); /\* shouldn't work and must raise an exception *\/ */
+/*     xbt_assert0(0, "Wow, I can remove a dependency between Task C and itself!"); */
+/*   } */
+/*   CATCH (ex) { */
+/*   } */
 
-  TRY {
-    SD_task_dependency_remove(taskC, taskA); /* shouldn't work and must raise an exception */
-    xbt_assert0(0, "Dude, I can remove an unknown dependency!");
-  }
-  CATCH (ex) {
-  }
 
-  TRY {
-    SD_task_dependency_remove(taskC, taskC); /* shouldn't work and must raise an exception */
-    xbt_assert0(0, "Wow, I can remove a dependency between Task C and itself!");
-  }
-  CATCH (ex) {
-  }
   /* if everything is ok, no exception is forwarded or rethrown by main() */
 
   /* watch points */
-  /*  SD_task_watch(taskA, SD_SCHEDULED);
-  SD_task_watch(taskA, SD_DONE);
-  SD_task_unwatch(taskA, SD_SCHEDULED);
-  SD_task_watch(taskA, SD_DONE);
-  SD_task_watch(taskA, SD_SCHEDULED);*/
+  /*  SD_task_watch(taskB, SD_DONE);*/
 
-  SD_task_watch(taskA, SD_SCHEDULED);
 
   /* let's launch the simulation! */
 
@@ -89,10 +90,14 @@ int main(int argc, char **argv) {
     };
   double rate = 1;
 
-  /*  printf("Scheduling task A (state = %d)...\n", SD_task_get_state(taskA));*/
   SD_task_schedule(taskA, workstation_number, workstation_list,
                   computation_amount, communication_amount, rate);
-  /*  printf("Done. Task A state: %d\n", SD_task_get_state(taskA));*/
+  SD_task_schedule(taskB, workstation_number, workstation_list,
+                  computation_amount, communication_amount, rate);
+  SD_task_schedule(taskC, workstation_number, workstation_list,
+                  computation_amount, communication_amount, rate);
+  SD_task_schedule(taskD, workstation_number, workstation_list,
+                  computation_amount, communication_amount, rate);
 
   printf("Launching simulation...\n");
   SD_simulate(100);
@@ -100,6 +105,7 @@ int main(int argc, char **argv) {
   SD_task_destroy(taskA);
   SD_task_destroy(taskB);
   SD_task_destroy(taskC);
+  SD_task_destroy(taskD);
   SD_exit();
   return 0;
 }