/* Creates a link.
*/
SD_link_t __SD_link_create(void *surf_link, void *data) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(surf_link != NULL, "surf_link is NULL !");
SD_link_data_t sd_data = xbt_new0(s_SD_link_data_t, 1); /* link private data */
/* Returns the user data of a link. The user data can be NULL.
*/
void* SD_link_get_data(SD_link_t link) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(link != NULL, "Invalid parameter");
return link->data;
}
/* Sets the user data of a link. The new data can be NULL. The old data should have been freed first if it was not NULL.
*/
void SD_link_set_data(SD_link_t link, void *data) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(link != NULL, "Invalid parameter");
link->data = data;
}
/* Returns the name of a link. The name cannot be NULL.
*/
const char* SD_link_get_name(SD_link_t link) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(link != NULL, "Invalid parameter");
return surf_workstation_resource->extension_public->get_link_name(link->sd_data->surf_link);
}
/* Return the current bandwidth of a link.
*/
double SD_link_get_current_bandwidth(SD_link_t link) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(link != NULL, "Invalid parameter");
return surf_workstation_resource->extension_public->get_link_bandwidth(link->sd_data->surf_link);
}
/* Return the current latency of a link.
*/
double SD_link_get_current_latency(SD_link_t link) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(link != NULL, "Invalid parameter");
return surf_workstation_resource->extension_public->get_link_latency(link->sd_data->surf_link);
}
/* Destroys a link. The user data (if any) should have been destroyed first.
*/
void __SD_link_destroy(void *link) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(link != NULL, "Invalid parameter");
SD_link_data_t sd_data = ((SD_link_t) link)->data;
/* Creates a task.
*/
SD_task_t SD_task_create(const char *name, void *data, double amount) {
- CHECK_INIT_DONE();
- xbt_assert0(name != NULL, "name is NULL !");
+ SD_CHECK_INIT_DONE();
xbt_assert0(amount > 0, "amount must be positive");
SD_task_data_t sd_data = xbt_new0(s_SD_task_data_t, 1); /* task private data */
- sd_data->name = xbt_strdup(name);
+
+ /* general information */
+ if (name != NULL)
+ sd_data->name = xbt_strdup(name);
+ else
+ sd_data->name = NULL;
+
sd_data->state = SD_NOT_SCHEDULED;
sd_data->amount = amount;
sd_data->surf_action = NULL;
sd_data->watch_points = 0;
+ /* dependencies */
+ sd_data->tasks_before = xbt_dynar_new(sizeof(SD_task_t), NULL);
+ sd_data->tasks_after = xbt_dynar_new(sizeof(SD_task_t), NULL);
+
+ /* scheduling parameters */
+ sd_data->workstation_nb = 0;
+ sd_data->workstation_list = NULL;
+ sd_data->computation_amount = NULL;
+ sd_data->communication_amount = NULL;
+ sd_data->rate = 0;
+
SD_task_t task = xbt_new0(s_SD_task_t, 1);
task->sd_data = sd_data; /* private data */
task->data = data; /* user data */
- /* TODO: dependencies */
-
return task;
}
/* Schedules a task.
+ * task: the task to schedule
+ * workstation_nb: number of workstations where the task will be executed
+ * workstation_list: workstations where the task will be executed
+ * computation_amount: computation amount for each workstation
+ * communication_amount: communication amount between each pair of workstations
+ * rate: task execution speed rate
*/
-int SD_task_schedule(SD_task_t task, int workstation_nb,
- SD_workstation_t **workstation_list, double *computation_amount,
+void SD_task_schedule(SD_task_t task, int workstation_nb,
+ const SD_workstation_t *workstation_list, double *computation_amount,
double *communication_amount, double rate) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(task, "Invalid parameter");
- /* TODO */
+ xbt_assert0(SD_task_get_state(task) == SD_NOT_SCHEDULED, "This task has already been scheduled.");
+ xbt_assert0(workstation_nb > 0, "workstation_nb must be positive");
+
+ SD_task_data_t sd_data = task->sd_data;
+ sd_data->workstation_nb = workstation_nb;
+ sd_data->rate = rate;
+
+ sd_data->computation_amount = xbt_new0(double, workstation_nb);
+ memcpy(sd_data->computation_amount, computation_amount, sizeof(double) * workstation_nb);
+
+ int communication_nb = workstation_nb * workstation_nb;
+ sd_data->communication_amount = xbt_new0(double, communication_nb);
+ memcpy(sd_data->communication_amount, communication_amount, sizeof(double) * communication_nb);
+
+ /* we have to create a Surf workstation array instead of the SimDag workstation array */
+ sd_data->workstation_list = xbt_new0(void*, workstation_nb);
+ int i;
+ for (i = 0; i < workstation_nb; i++) {
+ sd_data->workstation_list[i] = workstation_list[i]->sd_data->surf_workstation;
+ }
- return 0;
+ sd_data->state = SD_SCHEDULED;
}
/* Returns the data of a task.
*/
void* SD_task_get_data(SD_task_t task) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(task, "Invalid parameter");
return task->data;
}
/* Sets the data of a task.
*/
void SD_task_set_data(SD_task_t task, void *data) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(task, "Invalid parameter");
task->data = data;
}
-/* Returns the name of a task.
+/* Returns the name of a task. The name can be NULL.
*/
const char* SD_task_get_name(SD_task_t task) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(task, "Invalid parameter");
return task->sd_data->name;
}
/* Returns the computing amount of a task.
*/
double SD_task_get_amount(SD_task_t task) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(task, "Invalid parameter");
return task->sd_data->amount;
}
/* Returns the remaining computing amount of a task.
*/
double SD_task_get_remaining_amount(SD_task_t task) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(task, "Invalid parameter");
SD_task_data_t sd_data = task->sd_data;
- if (sd_data->surf_action == NULL)
+ if (sd_data->surf_action)
return sd_data->amount;
else
return sd_data->surf_action->remains;
/* Adds a dependency between two tasks.
*/
void SD_task_dependency_add(const char *name, void *data, SD_task_t src, SD_task_t dst) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(src != NULL && dst != NULL, "Invalid parameter");
/* TODO */
}
/* Removes a dependency between two tasks.
*/
void SD_task_dependency_remove(SD_task_t src, SD_task_t dst) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(src != NULL && dst != NULL, "Invalid parameter");
/* TODO */
}
/* Returns the state of a task: SD_NOT_SCHEDULED, SD_SCHEDULED, SD_RUNNING, SD_DONE or SD_FAILED.
*/
SD_task_state_t SD_task_get_state(SD_task_t task) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(task, "Invalid parameter");
return task->sd_data->state;
}
for (i = 0; i < 4; i++) {
if (task->sd_data->watch_points & state_masks[i])
printf("%s ", state_names[i]);
-
}
printf("\n");
}
Watch point is then automatically removed.
*/
void SD_task_watch(SD_task_t task, SD_task_state_t state) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(task, "Invalid parameter");
task->sd_data->watch_points = task->sd_data->watch_points | state;
/* Removes a watch point from a task.
*/
void SD_task_unwatch(SD_task_t task, SD_task_state_t state) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(task, "Invalid parameter");
task->sd_data->watch_points = task->sd_data->watch_points & ~state;
__SD_print_watch_points(task);
}
-/* Unschedules a task.
- Change state and rerun
+/* Unschedules a task. The state must be SD_SCHEDULED, SD_RUNNING or SD_FAILED.
+ * The task is reinitialised and its state becomes SD_NOT_SCHEDULED.
+ * Call SD_task_schedule to schedule it again.
*/
void SD_task_unschedule(SD_task_t task) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(task, "Invalid parameter");
- /* TODO */
+ xbt_assert1(task->sd_data->state == SD_SCHEDULED ||
+ task->sd_data->state == SD_RUNNING ||
+ task->sd_data->state == SD_FAILED,
+ "Task %s: the state must be SD_SCHEDULED, SD_RUNNING or SD_FAILED", task->sd_data->name);
+
+ if (task->sd_data->state == SD_SCHEDULED)
+ __SD_task_destroy_scheduling_data(task);
+
+ task->sd_data->state = SD_NOT_SCHEDULED;
+}
+
+/* Runs a task. This function is called by SD_simulate when a scheduled task can start
+ * (ie when its dependencies are satisfied).
+ */
+void __SD_task_run(SD_task_t task) {
+ SD_CHECK_INIT_DONE();
+ xbt_assert0(task, "Invalid parameter");
+
+ SD_task_data_t sd_data = task->sd_data;
+ surf_workstation_resource->extension_public->
+ execute_parallel_task(sd_data->workstation_nb,
+ sd_data->workstation_list,
+ sd_data->computation_amount,
+ sd_data->communication_amount,
+ sd_data->amount,
+ sd_data->rate);
+ task->sd_data->state = SD_RUNNING;
+
+ __SD_task_destroy_scheduling_data(task); /* now the scheduling data are not useful anymore */
}
+
/* Destroys a task. The user data (if any) should have been destroyed first.
*/
void SD_task_destroy(SD_task_t task) {
- CHECK_INIT_DONE();
- xbt_free(task->sd_data->name);
+ SD_CHECK_INIT_DONE();
+ xbt_assert0(task, "Invalid parameter");
+
+ if (task->sd_data->state == SD_SCHEDULED)
+ __SD_task_destroy_scheduling_data(task);
+
+ if (task->sd_data->name != NULL)
+ xbt_free(task->sd_data->name);
+
+ xbt_dynar_free(&task->sd_data->tasks_before);
+ xbt_dynar_free(&task->sd_data->tasks_after);
xbt_free(task->sd_data);
- /* TODO: dependencies */
xbt_free(task);
}
+
+/* Destroys the data memorised by SD_task_schedule. Task state must be SD_SCHEDULED.
+ */
+void __SD_task_destroy_scheduling_data(SD_task_t task) {
+ xbt_free(task->sd_data->workstation_list);
+ xbt_free(task->sd_data->computation_amount);
+ xbt_free(task->sd_data->communication_amount);
+}
/* Creates a workstation and registers it in SD.
*/
SD_workstation_t __SD_workstation_create(void *surf_workstation, void *data) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(surf_workstation != NULL, "surf_workstation is NULL !");
SD_workstation_data_t sd_data = xbt_new0(s_SD_workstation_data_t, 1); /* workstation private data */
/* Returns a workstation given its name, or NULL if there is no such workstation.
*/
SD_workstation_t SD_workstation_get_by_name(const char *name) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(name != NULL, "Invalid parameter");
/* Returns a NULL-terminated array of existing workstations.
*/
SD_workstation_t* SD_workstation_get_list(void) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
SD_workstation_t* array = xbt_new0(SD_workstation_t, sd_global->workstation_count + 1);
/* Returns the number or workstations.
*/
int SD_workstation_get_number(void) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
return sd_global->workstation_count;
}
/* Sets the data of a workstation. The new data can be NULL. The old data should have been freed first if it was not NULL.
*/
void SD_workstation_set_data(SD_workstation_t workstation, void *data) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(workstation != NULL, "Invalid parameter");
workstation->data = data;
}
/* Returns the data of a workstation. The user data can be NULL.
*/
void* SD_workstation_get_data(SD_workstation_t workstation) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(workstation != NULL, "Invalid parameter");
return workstation->data;
}
/* Returns the name of a workstation.
*/
const char* SD_workstation_get_name(SD_workstation_t workstation) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(workstation != NULL, "Invalid parameter");
return surf_workstation_resource->common_public->get_resource_name(workstation->sd_data->surf_workstation);
}
/* Returns an new array of links representating the route between two workstations.
*/
SD_link_t* SD_workstation_route_get_list(SD_workstation_t src, SD_workstation_t dst) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
void *surf_src = src->sd_data->surf_workstation;
void *surf_dst = dst->sd_data->surf_workstation;
/* Returns the number of links on the route between two workstations.
*/
int SD_workstation_route_get_size(SD_workstation_t src, SD_workstation_t dst) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
return surf_workstation_resource->extension_public->
get_route_size(src->sd_data->surf_workstation, dst->sd_data->surf_workstation);
}
/* Returns the total power of a workstation.
*/
double SD_workstation_get_power(SD_workstation_t workstation) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(workstation != NULL, "Invalid parameter");
return surf_workstation_resource->extension_public->get_speed(workstation->sd_data->surf_workstation, 1.0);
}
/* Returns the proportion of available power in a workstation (normally a number between 0 and 1).
*/
double SD_workstation_get_available_power(SD_workstation_t workstation) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(workstation != NULL, "Invalid parameter");
return surf_workstation_resource->extension_public->get_available_speed(workstation->sd_data->surf_workstation);
}
/* Destroys a workstation. The user data (if any) should have been destroyed first.
*/
void __SD_workstation_destroy(void *workstation) {
- CHECK_INIT_DONE();
+ SD_CHECK_INIT_DONE();
xbt_assert0(workstation != NULL, "Invalid parameter");
if (((SD_workstation_t) workstation)->sd_data != NULL) {