From: thiery Date: Wed, 21 Jun 2006 14:26:21 +0000 (+0000) Subject: Implement SD_task_schedule, SD_task_unschedule and other SimDag stuff. X-Git-Tag: v3.3~2941 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/3e96889c27396fab9cf26b4c22d282dfc962a1a5 Implement SD_task_schedule, SD_task_unschedule and other SimDag stuff. git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@2417 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- diff --git a/include/simdag/simdag.h b/include/simdag/simdag.h index f32f330285..e34f8ce9b0 100644 --- a/include/simdag/simdag.h +++ b/include/simdag/simdag.h @@ -43,10 +43,10 @@ void SD_workstation_destroy(SD_workstation_t workstation); /************************** Task handling ************************************/ SD_task_t SD_task_create(const char *name, void *data, double amount); -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); - +void SD_task_reset(SD_task_t task); void* SD_task_get_data(SD_task_t task); void SD_task_set_data(SD_task_t task, void *data); const char* SD_task_get_name(SD_task_t task); @@ -70,7 +70,7 @@ void SD_task_destroy(SD_task_t task); void SD_init(int *argc, char **argv); void SD_create_environment(const char *platform_file); SD_task_t *SD_simulate(double how_long); /* returns a NULL-terminated array of SD_task_t whose state has changed */ -void SD_clean(); /* cleans everything */ +void SD_exit(); /* cleans everything */ SG_END_DECL() diff --git a/src/simdag/private.h b/src/simdag/private.h index 209556f110..b00f35a381 100644 --- a/src/simdag/private.h +++ b/src/simdag/private.h @@ -2,11 +2,12 @@ #define SIMDAG_PRIVATE_H #include "xbt/dict.h" +#include "xbt/dynar.h" #include "simdag/simdag.h" #include "simdag/datatypes.h" #include "surf/surf.h" -#define CHECK_INIT_DONE() xbt_assert0(sd_global != NULL, "SD_init not called yet") +#define SD_CHECK_INIT_DONE() xbt_assert0(sd_global != NULL, "Call SD_init() first") /* Global variables */ @@ -36,8 +37,16 @@ typedef struct SD_task_data { surf_action_t surf_action; unsigned short watch_points; - /* double remaining_amount;*/ - /* TODO: dependencies */ + /* dependencies */ + xbt_dynar_t tasks_before; + xbt_dynar_t tasks_after; + + /* scheduling parameters (only exist in state SD_SCHEDULED) */ + int workstation_nb; + void **workstation_list; /* surf workstations */ + double *computation_amount; + double *communication_amount; + double rate; } s_SD_task_data_t; /* Private functions */ @@ -48,4 +57,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_run(SD_task_t task); +void __SD_task_destroy(SD_task_t task); +void __SD_task_destroy_scheduling_data(SD_task_t task); + #endif diff --git a/src/simdag/sd_global.c b/src/simdag/sd_global.c index c76bb2cfd6..9e8c7143a1 100644 --- a/src/simdag/sd_global.c +++ b/src/simdag/sd_global.c @@ -28,7 +28,7 @@ void SD_create_environment(const char *platform_file) { void *surf_workstation = NULL; void *surf_link = NULL; - CHECK_INIT_DONE(); + SD_CHECK_INIT_DONE(); surf_timer_resource_init(platform_file); /* tell Surf to create the environnement */ @@ -101,14 +101,14 @@ SD_task_t* SD_simulate(double how_long) return NULL; } -/* Destroys all SD data. This function should be called when the simulation is over. +/* Destroys all SD internal data. This function should be called when the simulation is over. + * The tasks should have been destroyed first. */ -void SD_clean() { +void SD_exit() { if (sd_global != NULL) { xbt_dict_free(&sd_global->workstations); xbt_dict_free(&sd_global->links); xbt_free(sd_global); surf_exit(); - /* TODO: destroy the tasks */ } } diff --git a/src/simdag/sd_link.c b/src/simdag/sd_link.c index 971d45a277..8308c9cda2 100644 --- a/src/simdag/sd_link.c +++ b/src/simdag/sd_link.c @@ -7,7 +7,7 @@ /* 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 */ @@ -26,7 +26,7 @@ SD_link_t __SD_link_create(void *surf_link, void *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; } @@ -34,7 +34,7 @@ void* SD_link_get_data(SD_link_t link) { /* 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; } @@ -42,7 +42,7 @@ void SD_link_set_data(SD_link_t link, void *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); } @@ -58,7 +58,7 @@ double SD_link_get_capacity(SD_link_t 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); } @@ -66,7 +66,7 @@ double SD_link_get_current_bandwidth(SD_link_t 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); } @@ -74,7 +74,7 @@ double SD_link_get_current_latency(SD_link_t 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; diff --git a/src/simdag/sd_task.c b/src/simdag/sd_task.c index 6368c706f5..54751c9aa1 100644 --- a/src/simdag/sd_task.c +++ b/src/simdag/sd_task.c @@ -5,42 +5,81 @@ /* 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; } @@ -48,15 +87,15 @@ void* SD_task_get_data(SD_task_t task) { /* 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; } @@ -64,7 +103,7 @@ const char* SD_task_get_name(SD_task_t task) { /* 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; } @@ -72,10 +111,10 @@ double SD_task_get_amount(SD_task_t task) { /* 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; @@ -84,7 +123,7 @@ double SD_task_get_remaining_amount(SD_task_t task) { /* 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 */ } @@ -92,7 +131,7 @@ void SD_task_dependency_add(const char *name, void *data, SD_task_t src, SD_task /* 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 */ } @@ -100,7 +139,7 @@ void SD_task_dependency_remove(SD_task_t src, SD_task_t dst) { /* 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; } @@ -116,7 +155,6 @@ void __SD_print_watch_points(SD_task_t task) { for (i = 0; i < 4; i++) { if (task->sd_data->watch_points & state_masks[i]) printf("%s ", state_names[i]); - } printf("\n"); } @@ -126,7 +164,7 @@ void __SD_print_watch_points(SD_task_t task) { 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; @@ -136,28 +174,74 @@ void SD_task_watch(SD_task_t task, SD_task_state_t 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); +} diff --git a/src/simdag/sd_workstation.c b/src/simdag/sd_workstation.c index 3d842eff6b..2d1b88064a 100644 --- a/src/simdag/sd_workstation.c +++ b/src/simdag/sd_workstation.c @@ -7,7 +7,7 @@ /* 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 */ @@ -26,7 +26,7 @@ SD_workstation_t __SD_workstation_create(void *surf_workstation, void *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"); @@ -36,7 +36,7 @@ SD_workstation_t SD_workstation_get_by_name(const char *name) { /* 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); @@ -56,14 +56,14 @@ SD_workstation_t* SD_workstation_get_list(void) { /* 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; } @@ -71,7 +71,7 @@ void SD_workstation_set_data(SD_workstation_t workstation, void *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; } @@ -79,7 +79,7 @@ void* SD_workstation_get_data(SD_workstation_t workstation) { /* 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); } @@ -87,7 +87,7 @@ const char* SD_workstation_get_name(SD_workstation_t 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; @@ -109,7 +109,7 @@ SD_link_t* SD_workstation_route_get_list(SD_workstation_t src, SD_workstation_t /* 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); } @@ -117,7 +117,7 @@ int SD_workstation_route_get_size(SD_workstation_t src, SD_workstation_t dst) { /* 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); } @@ -125,7 +125,7 @@ double SD_workstation_get_power(SD_workstation_t workstation) { /* 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); } @@ -133,7 +133,7 @@ double SD_workstation_get_available_power(SD_workstation_t 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) { diff --git a/testsuite/simdag/Makefile b/testsuite/simdag/Makefile index 4dd24071a5..c735476bcf 100644 --- a/testsuite/simdag/Makefile +++ b/testsuite/simdag/Makefile @@ -7,7 +7,7 @@ PEDANTIC_PARANOID_FREAK = -O0 -Wshadow -Wcast-align \ -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations \ -Wmissing-noreturn -Wredundant-decls -Wnested-externs \ -Wpointer-arith -Wwrite-strings -finline-functions -REASONABLY_CAREFUL_DUDE = -Wall +REASONABLY_CAREFUL_DUDE = -Wall -Werror NO_PRAYER_FOR_THE_WICKED = -w -O2 WARNINGS = $(REASONABLY_CAREFUL_DUDE) CFLAGS = -g $(WARNINGS) diff --git a/testsuite/simdag/sd_test.c b/testsuite/simdag/sd_test.c index c55ea762a5..3d13f81185 100644 --- a/testsuite/simdag/sd_test.c +++ b/testsuite/simdag/sd_test.c @@ -38,6 +38,7 @@ int main(int argc, char **argv) { /* let's launch the simulation! */ SD_simulate(100); - SD_clean(); + SD_task_destroy(task1); + SD_exit(); return 0; }