Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Use a portable inline and declare variables at the beginning
[simgrid.git] / src / simdag / sd_task.c
index 959eebd..0de83bb 100644 (file)
@@ -1,4 +1,5 @@
-/* Copyright (c) 2007-2009 Da SimGrid Team.  All rights reserved.           */
+/* Copyright (c) 2006, 2007, 2008, 2009, 2010. The SimGrid Team.
+ * All rights reserved.                                                     */
 
 /* This program is free software; you can redistribute it and/or modify it
  * under the terms of the license (GNU LGPL) which comes with this package. */
@@ -168,6 +169,12 @@ const char *SD_task_get_name(SD_task_t task)
   return task->name;
 }
 
+/** @brief Allows to change the name of a task */
+void SD_task_set_name(SD_task_t task, const char *name) {
+  xbt_free(task->name);
+  task->name = xbt_strdup(name);
+}
+
 /** @brief Returns the dynar of the parents of a task
  *
  * \param task a task
@@ -644,25 +651,27 @@ double SD_task_get_execution_time(SD_task_t task,
   double time, max_time = 0.0;
   int i, j;
   SD_CHECK_INIT_DONE();
-  xbt_assert0(task != NULL && workstation_nb > 0 && workstation_list != NULL
-              && computation_amount != NULL
-              && communication_amount != NULL, "Invalid parameter");
+  xbt_assert0(task != NULL && workstation_nb > 0 && workstation_list != NULL,
+              "Invalid parameter");
 
   /* the task execution time is the maximum execution time of the parallel tasks */
 
   for (i = 0; i < workstation_nb; i++) {
-    time =
-      SD_workstation_get_computation_time(workstation_list[i],
-                                          computation_amount[i]);
-
-    for (j = 0; j < workstation_nb; j++) {
-      time +=
-        SD_route_get_communication_time(workstation_list[i],
-                                        workstation_list[j],
-                                        communication_amount[i *
-                                                             workstation_nb +
-                                                             j]);
-    }
+    time = 0.0;
+    if (computation_amount != NULL)
+      time =
+          SD_workstation_get_computation_time(workstation_list[i],
+              computation_amount[i]);
+
+    if (communication_amount != NULL)
+      for (j = 0; j < workstation_nb; j++) {
+        time +=
+            SD_route_get_communication_time(workstation_list[i],
+                workstation_list[j],
+                communication_amount[i *
+                                     workstation_nb +
+                                     j]);
+      }
 
     if (time > max_time) {
       max_time = time;
@@ -670,7 +679,7 @@ double SD_task_get_execution_time(SD_task_t task,
   }
   return max_time;
 }
-static inline void SD_task_do_schedule(SD_task_t task) {
+static XBT_INLINE void SD_task_do_schedule(SD_task_t task) {
   SD_CHECK_INIT_DONE();
 
    if (!__SD_task_is_not_scheduled(task))
@@ -704,21 +713,30 @@ void SD_task_schedule(SD_task_t task, int workstation_count,
                       const double *computation_amount,
                       const double *communication_amount, double rate)
 {
-  xbt_assert0(workstation_count > 0, "workstation_nb must be positive");
-
   int communication_nb;
+  task->workstation_nb = 0;
+  task->rate = 0;
+  xbt_assert0(workstation_count > 0, "workstation_nb must be positive");
 
   task->workstation_nb = workstation_count;
   task->rate = rate;
 
-  task->computation_amount = xbt_new(double, workstation_count);
-  memcpy(task->computation_amount, computation_amount,
-         sizeof(double) * workstation_count);
+  if (computation_amount) {
+    task->computation_amount = xbt_new(double, workstation_count);
+    memcpy(task->computation_amount, computation_amount,
+        sizeof(double) * workstation_count);
+  } else {
+    task->computation_amount = NULL;
+  }
 
   communication_nb = workstation_count * workstation_count;
-  task->communication_amount = xbt_new(double, communication_nb);
-  memcpy(task->communication_amount, communication_amount,
-         sizeof(double) * communication_nb);
+  if (communication_amount) {
+    task->communication_amount = xbt_new(double, communication_nb);
+    memcpy(task->communication_amount, communication_amount,
+        sizeof(double) * communication_nb);
+  } else {
+    task->communication_amount = NULL;
+  }
 
   task->workstation_list = xbt_new(SD_workstation_t, workstation_count);
   memcpy(task->workstation_list, workstation_list,
@@ -816,31 +834,34 @@ void __SD_task_really_run(SD_task_t task)
   /* we have to create a Surf workstation array instead of the SimDag workstation array */
   surf_workstations = xbt_new(void *, task->workstation_nb);
 
-  for (i = 0; i < task->workstation_nb; i++) {
+  for (i = 0; i < task->workstation_nb; i++)
     surf_workstations[i] = task->workstation_list[i]->surf_workstation;
-  }
+
+  /* It's allowed to pass a NULL vector as cost to mean vector of 0.0 (easing user's life). Let's deal with it */
+#define cost_or_zero(array,pos) ((array)?(array)[pos]:0.0)
 
   task->surf_action = NULL;
-  if ((task->workstation_nb == 1) && (task->communication_amount[0] == 0.0)) {
+  if ((task->workstation_nb == 1) && (cost_or_zero(task->communication_amount,0) == 0.0)) {
     task->surf_action =
       surf_workstation_model->extension.
-      workstation.execute(surf_workstations[0], task->computation_amount[0]);
+      workstation.execute(surf_workstations[0], cost_or_zero(task->computation_amount,0));
   } else if ((task->workstation_nb == 1)
-             && (task->computation_amount[0] == 0.0)) {
+             && (cost_or_zero(task->computation_amount,0) == 0.0)) {
+
     task->surf_action =
       surf_workstation_model->extension.
       workstation.communicate(surf_workstations[0], surf_workstations[0],
-                              task->communication_amount[0], task->rate);
+                              cost_or_zero(task->communication_amount,0), task->rate);
   } else if ((task->workstation_nb == 2)
-             && (task->computation_amount[0] == 0.0)
-             && (task->computation_amount[1] == 0.0)) {
+             && (cost_or_zero(task->computation_amount,0) == 0.0)
+             && (cost_or_zero(task->computation_amount,1) == 0.0)) {
     int nb = 0;
     double value = 0.0;
 
     for (i = 0; i < task->workstation_nb * task->workstation_nb; i++) {
-      if (task->communication_amount[i] > 0.0) {
+      if (cost_or_zero(task->communication_amount,i) > 0.0) {
         nb++;
-        value = task->communication_amount[i];
+        value = cost_or_zero(task->communication_amount,i);
       }
     }
     if (nb == 1) {
@@ -850,6 +871,8 @@ void __SD_task_really_run(SD_task_t task)
                                 value, task->rate);
     }
   }
+#undef cost_or_zero
+
   if (!task->surf_action) {
     double *computation_amount = xbt_new(double, task->workstation_nb);
     double *communication_amount = xbt_new(double, task->workstation_nb *
@@ -902,7 +925,8 @@ int __SD_task_try_to_run(SD_task_t task)
 
 
   for (i = 0; i < task->workstation_nb; i++) {
-    can_start = !__SD_workstation_is_busy(task->workstation_list[i]);
+    can_start = can_start && 
+      !__SD_workstation_is_busy(task->workstation_list[i]);
   }
 
   DEBUG2("Task '%s' can start: %d", SD_task_get_name(task), can_start);
@@ -1181,7 +1205,7 @@ void SD_task_destroy(SD_task_t task)
 }
 
 
-static inline SD_task_t SD_task_create_sized(const char*name,void*data,double amount,int ws_count) {
+static XBT_INLINE SD_task_t SD_task_create_sized(const char*name,void*data,double amount,int ws_count) {
   SD_task_t task = SD_task_create(name,data,amount);
   task->communication_amount = xbt_new0(double,ws_count*ws_count);
   task->computation_amount = xbt_new0(double,ws_count);
@@ -1243,6 +1267,8 @@ SD_task_t SD_task_create_comp_seq(const char*name, void *data, double amount) {
  */
 void SD_task_schedulev(SD_task_t task, int count, const SD_workstation_t*list) {
   int i;
+  SD_dependency_t dep;
+  unsigned int cpt;
   xbt_assert1(task->kind != 0,"Task %s is not typed. Cannot automatically schedule it.",SD_task_get_name(task));
   switch(task->kind) {
   case SD_TASK_COMM_E2E:
@@ -1268,8 +1294,7 @@ void SD_task_schedulev(SD_task_t task, int count, const SD_workstation_t*list) {
     VERB3("Schedule computation task %s on %s. It costs %.f flops",
         SD_task_get_name(task),SD_workstation_get_name(task->workstation_list[0]),
         task->computation_amount[0]);
-    SD_dependency_t dep;
-    unsigned int cpt;
+
     xbt_dynar_foreach(task->tasks_before,cpt,dep) {
       SD_task_t before = dep->src;
       if (before->kind == SD_TASK_COMM_E2E) {