From: thiery Date: Mon, 26 Jun 2006 08:33:54 +0000 (+0000) Subject: Update function SD_simulate. X-Git-Tag: v3.3~2929 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/fde322aea2fa9ee1dc887875f4719f8a818bb6d4 Update function SD_simulate. git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@2429 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- diff --git a/src/simdag/private.h b/src/simdag/private.h index d8bf9f7cdb..eafc778a80 100644 --- a/src/simdag/private.h +++ b/src/simdag/private.h @@ -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 diff --git a/src/simdag/sd_global.c b/src/simdag/sd_global.c index 254f7c0adf..7c153b4845 100644 --- a/src/simdag/sd_global.c +++ b/src/simdag/sd_global.c @@ -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); diff --git a/src/simdag/sd_task.c b/src/simdag/sd_task.c index d9b5ed6a24..1e91daf0d5 100644 --- a/src/simdag/sd_task.c +++ b/src/simdag/sd_task.c @@ -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");*/ - } diff --git a/testsuite/simdag/sd_test.c b/testsuite/simdag/sd_test.c index 944565891c..bf026bfe01 100644 --- a/testsuite/simdag/sd_test.c +++ b/testsuite/simdag/sd_test.c @@ -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; }