X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/e9a3ff64a8ae1a5566286e3b68a5d669a1bf2949..424d509a49e75c18f5b4de3b9065f6623b39a0c5:/src/simdag/sd_task.cpp diff --git a/src/simdag/sd_task.cpp b/src/simdag/sd_task.cpp index eabb10ea45..9309197d37 100644 --- a/src/simdag/sd_task.cpp +++ b/src/simdag/sd_task.cpp @@ -4,6 +4,8 @@ /* 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. */ +#include "src/surf/surf_interface.hpp" +#include "src/surf/host_interface.hpp" #include "src/simdag/simdag_private.h" #include "simgrid/simdag.h" #include "xbt/sysdep.h" @@ -31,13 +33,8 @@ void SD_task_recycle_f(void *t) /* Reset the content */ task->kind = SD_TASK_NOT_TYPED; - task->state_hookup.prev = NULL; - task->state_hookup.next = NULL; - task->state_set = sd_global->not_scheduled_task_set; - xbt_swag_insert(task, task->state_set); - task->state = SD_NOT_SCHEDULED; - task->return_hookup.prev = NULL; - task->return_hookup.next = NULL; + task->state= SD_NOT_SCHEDULED; + xbt_dynar_push(sd_global->initial_task_set,&task); task->marked = 0; @@ -53,8 +50,8 @@ void SD_task_recycle_f(void *t) task->is_not_ready = 0; /* scheduling parameters */ - task->workstation_nb = 0; - task->workstation_list = NULL; + task->host_count = 0; + task->host_list = NULL; task->flops_amount = NULL; task->bytes_amount = NULL; task->rate = -1; @@ -90,8 +87,6 @@ SD_task_t SD_task_create(const char *name, void *data, double amount) sd_global->task_number++; - TRACE_sd_task_create(task); - return task; } @@ -102,8 +97,8 @@ static XBT_INLINE SD_task_t SD_task_create_sized(const char *name, SD_task_t task = SD_task_create(name, data, amount); task->bytes_amount = xbt_new0(double, ws_count * ws_count); task->flops_amount = xbt_new0(double, ws_count); - task->workstation_nb = ws_count; - task->workstation_list = xbt_new0(SD_workstation_t, ws_count); + task->host_count = ws_count; + task->host_list = xbt_new0(sg_host_t, ws_count); return task; } @@ -124,9 +119,6 @@ SD_task_t SD_task_create_comm_e2e(const char *name, void *data, res->bytes_amount[2] = amount; res->kind = SD_TASK_COMM_E2E; - TRACE_category("COMM_E2E"); - TRACE_sd_set_task_category(res, "COMM_E2E"); - return res; } @@ -152,9 +144,6 @@ SD_task_t SD_task_create_comp_seq(const char *name, void *data, res->flops_amount[0] = flops_amount; res->kind = SD_TASK_COMP_SEQ; - TRACE_category("COMP_SEQ"); - TRACE_sd_set_task_category(res, "COMP_SEQ"); - return res; } @@ -185,9 +174,6 @@ SD_task_t SD_task_create_comp_par_amdahl(const char *name, void *data, res->alpha = alpha; res->kind = SD_TASK_COMP_PAR_AMDAHL; - TRACE_category("COMP_PAR_AMDAHL"); - TRACE_sd_set_task_category(res, "COMP_PAR_AMDAHL"); - return res; } @@ -214,12 +200,9 @@ SD_task_t SD_task_create_comm_par_mxn_1d_block(const char *name, void *data, double amount) { SD_task_t res = SD_task_create(name, data, amount); - res->workstation_list=NULL; + res->host_list=NULL; res->kind = SD_TASK_COMM_PAR_MXN_1D_BLOCK; - TRACE_category("COMM_PAR_MXN_1D_BLOCK"); - TRACE_sd_set_task_category(res, "COMM_PAR_MXN_1D_BLOCK"); - return res; } @@ -233,28 +216,28 @@ SD_task_t SD_task_create_comm_par_mxn_1d_block(const char *name, void *data, */ void SD_task_destroy(SD_task_t task) { + int idx; XBT_DEBUG("Destroying task %s...", SD_task_get_name(task)); __SD_task_remove_dependencies(task); /* if the task was scheduled or runnable we have to free the scheduling parameters */ if (__SD_task_is_scheduled_or_runnable(task)) __SD_task_destroy_scheduling_data(task); - if (task->state_set != NULL) /* would be null if just created */ - xbt_swag_remove(task, task->state_set); - xbt_swag_remove(task, sd_global->return_set); + idx = xbt_dynar_search_or_negative(sd_global->return_set, &task); + if (idx >=0) { + xbt_dynar_remove_at(sd_global->return_set, idx, NULL); + } xbt_free(task->name); if (task->surf_action != NULL) - surf_action_unref(task->surf_action); + task->surf_action->unref(); - xbt_free(task->workstation_list); + xbt_free(task->host_list); xbt_free(task->bytes_amount); xbt_free(task->flops_amount); - TRACE_sd_task_destroy(task); - xbt_mallocator_release(sd_global->task_mallocator,task); sd_global->task_number--; @@ -329,44 +312,51 @@ e_SD_task_state_t SD_task_get_state(SD_task_t task) /* Changes the state of a task. Updates the swags and the flag sd_global->watch_point_reached. */ -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); + int idx; switch (new_state) { case SD_NOT_SCHEDULED: - task->state_set = sd_global->not_scheduled_task_set; - break; case SD_SCHEDULABLE: - task->state_set = sd_global->schedulable_task_set; + if (SD_task_get_state(task) == SD_FAILED){ + xbt_dynar_remove_at(sd_global->completed_task_set, + xbt_dynar_search(sd_global->completed_task_set, &task), NULL); + xbt_dynar_push(sd_global->initial_task_set,&task); + } break; case SD_SCHEDULED: - task->state_set = sd_global->scheduled_task_set; + if (SD_task_get_state(task) == SD_RUNNABLE){ + xbt_dynar_remove_at(sd_global->executable_task_set, + xbt_dynar_search(sd_global->executable_task_set, &task), NULL); + xbt_dynar_push(sd_global->initial_task_set,&task); + } break; case SD_RUNNABLE: - task->state_set = sd_global->runnable_task_set; - break; - case SD_IN_FIFO: - task->state_set = sd_global->in_fifo_task_set; + idx = xbt_dynar_search_or_negative(sd_global->initial_task_set, &task); + if (idx >= 0) { + xbt_dynar_remove_at(sd_global->initial_task_set, idx, NULL); + xbt_dynar_push(sd_global->executable_task_set,&task); + } break; case SD_RUNNING: - task->state_set = sd_global->running_task_set; - task->start_time = surf_action_get_start_time(task->surf_action); + xbt_dynar_remove_at(sd_global->executable_task_set, + xbt_dynar_search(sd_global->executable_task_set, &task), NULL); break; case SD_DONE: - task->state_set = sd_global->done_task_set; - task->finish_time = surf_action_get_finish_time(task->surf_action); + xbt_dynar_push(sd_global->completed_task_set,&task); + task->finish_time = task->surf_action->getFinishTime(); task->remains = 0; #ifdef HAVE_JEDULE jedule_log_sd_event(task); #endif break; case SD_FAILED: - task->state_set = sd_global->failed_task_set; + xbt_dynar_push(sd_global->completed_task_set,&task); break; default: xbt_die( "Invalid state"); } - xbt_swag_insert(task, task->state_set); + task->state = new_state; if (task->watch_points & new_state) { @@ -439,7 +429,7 @@ xbt_dynar_t SD_task_get_children(SD_task_t task) */ int SD_task_get_workstation_count(SD_task_t task) { - return task->workstation_nb; + return task->host_count; } /** @@ -448,9 +438,9 @@ int SD_task_get_workstation_count(SD_task_t task) * Only call this on already scheduled tasks! * \param task a task */ -SD_workstation_t *SD_task_get_workstation_list(SD_task_t task) +sg_host_t *SD_task_get_workstation_list(SD_task_t task) { - return task->workstation_list; + return task->host_list; } /** @@ -514,7 +504,7 @@ double SD_task_get_remaining_amount(SD_task_t task) return task->remains; } -int SD_task_get_kind(SD_task_t task) +e_SD_task_kind_t SD_task_get_kind(SD_task_t task) { return task->kind; } @@ -527,18 +517,17 @@ void SD_task_dump(SD_task_t task) char *statename; XBT_INFO("Displaying task %s", SD_task_get_name(task)); - statename = bprintf("%s %s %s %s %s %s %s %s", - (task->state == SD_NOT_SCHEDULED ? "not scheduled" : + statename = bprintf("%s%s%s%s%s%s%s", + (task->state == SD_NOT_SCHEDULED ? " not scheduled" : ""), - (task->state == SD_SCHEDULABLE ? "schedulable" : ""), - (task->state == SD_SCHEDULED ? "scheduled" : ""), - (task->state == SD_RUNNABLE ? "runnable" : - "not runnable"), - (task->state == SD_IN_FIFO ? "in fifo" : ""), - (task->state == SD_RUNNING ? "running" : ""), - (task->state == SD_DONE ? "done" : ""), - (task->state == SD_FAILED ? "failed" : "")); - XBT_INFO(" - state: %s", statename); + (task->state == SD_SCHEDULABLE ? " schedulable" : ""), + (task->state == SD_SCHEDULED ? " scheduled" : ""), + (task->state == SD_RUNNABLE ? " runnable" : + " not runnable"), + (task->state == SD_RUNNING ? " running" : ""), + (task->state == SD_DONE ? " done" : ""), + (task->state == SD_FAILED ? " failed" : "")); + XBT_INFO(" - state:%s", statename); free(statename); if (task->kind != 0) { @@ -634,6 +623,7 @@ void SD_task_dependency_add(const char *name, void *data, SD_task_t src, int found = 0; unsigned long i; SD_dependency_t dependency; + e_SD_task_state_t state; dynar = src->tasks_after; length = xbt_dynar_length(dynar); @@ -643,18 +633,19 @@ void SD_task_dependency_add(const char *name, void *data, SD_task_t src, "Cannot add a dependency between task '%s' and itself", SD_task_get_name(src)); - if (!__SD_task_is_not_scheduled(src) && !__SD_task_is_schedulable(src) - && !__SD_task_is_scheduled_or_runnable(src) && !__SD_task_is_running(src)) + state = SD_task_get_state(src); + if (state != SD_NOT_SCHEDULED && state != SD_SCHEDULABLE && + state != SD_RUNNING && !__SD_task_is_scheduled_or_runnable(src)) THROWF(arg_error, 0, - "Task '%s' must be SD_NOT_SCHEDULED, SD_SCHEDULABLE, SD_SCHEDULED or SD_RUNNABLE" - " or SD_RUNNING", - SD_task_get_name(src)); + "Task '%s' must be SD_NOT_SCHEDULED, SD_SCHEDULABLE, SD_SCHEDULED," + " SD_RUNNABLE or SD_RUNNING", SD_task_get_name(src)); - if (!__SD_task_is_not_scheduled(dst) && !__SD_task_is_schedulable(dst) - && !__SD_task_is_scheduled_or_runnable(dst)) + state = SD_task_get_state(dst); + if (state != SD_NOT_SCHEDULED && state != SD_SCHEDULABLE && + !__SD_task_is_scheduled_or_runnable(dst)) THROWF(arg_error, 0, - "Task '%s' must be SD_NOT_SCHEDULED, SD_SCHEDULABLE, SD_SCHEDULED or SD_RUNNABLE", - SD_task_get_name(dst)); + "Task '%s' must be SD_NOT_SCHEDULED, SD_SCHEDULABLE, SD_SCHEDULED," + "or SD_RUNNABLE", SD_task_get_name(dst)); XBT_DEBUG("SD_task_dependency_add: src = %s, dst = %s", SD_task_get_name(src), SD_task_get_name(dst)); @@ -686,11 +677,11 @@ void SD_task_dependency_add(const char *name, void *data, SD_task_t src, /* if the task was runnable, then dst->tasks_before is not empty anymore, so we must go back to state SD_SCHEDULED */ - if (__SD_task_is_runnable(dst)) { + if (SD_task_get_state(dst) == SD_RUNNABLE) { XBT_DEBUG ("SD_task_dependency_add: %s was runnable and becomes scheduled!", SD_task_get_name(dst)); - __SD_task_set_state(dst, SD_SCHEDULED); + SD_task_set_state(dst, SD_SCHEDULED); } } /** @@ -801,14 +792,14 @@ void SD_task_dependency_remove(SD_task_t src, SD_task_t dst) /* if the task was scheduled and dst->tasks_before is empty now, we can make it runnable */ if (dst->unsatisfied_dependencies == 0) { - if (__SD_task_is_scheduled(dst)) - __SD_task_set_state(dst, SD_RUNNABLE); + if (SD_task_get_state(dst) == SD_SCHEDULED) + SD_task_set_state(dst, SD_RUNNABLE); else - __SD_task_set_state(dst, SD_SCHEDULABLE); + SD_task_set_state(dst, SD_SCHEDULABLE); } if (dst->is_not_ready == 0) - __SD_task_set_state(dst, SD_SCHEDULABLE); + SD_task_set_state(dst, SD_SCHEDULABLE); /* __SD_print_dependencies(src); __SD_print_dependencies(dst); */ @@ -844,29 +835,6 @@ void *SD_task_dependency_get_data(SD_task_t src, SD_task_t dst) return dependency->data; } -/* temporary function for debugging */ -static void __SD_print_watch_points(SD_task_t task) -{ - static const int state_masks[] = - { SD_SCHEDULABLE, SD_SCHEDULED, SD_RUNNING, SD_RUNNABLE, SD_DONE, - SD_FAILED - }; - static const char *state_names[] = - { "schedulable", "scheduled", "running", "runnable", "done", - "failed" - }; - int i; - - XBT_INFO("Task '%s' watch points (%x): ", SD_task_get_name(task), - task->watch_points); - - - for (i = 0; i < 5; i++) { - if (task->watch_points & state_masks[i]) - XBT_INFO("%s ", state_names[i]); - } -} - /** * \brief Adds a watch point to a task * @@ -886,7 +854,6 @@ void SD_task_watch(SD_task_t task, e_SD_task_state_t state) "Cannot add a watch point for state SD_NOT_SCHEDULED"); task->watch_points = task->watch_points | state; - /* __SD_print_watch_points(task); */ } /** @@ -902,7 +869,6 @@ void SD_task_unwatch(SD_task_t task, e_SD_task_state_t state) "SimDag error: Cannot have a watch point for state SD_NOT_SCHEDULED"); task->watch_points = task->watch_points & ~state; - /* __SD_print_watch_points(task); */ } /** @@ -920,7 +886,7 @@ void SD_task_unwatch(SD_task_t task, e_SD_task_state_t state) */ double SD_task_get_execution_time(SD_task_t task, int workstation_nb, - const SD_workstation_t * + const sg_host_t * workstation_list, const double *flops_amount, const double *bytes_amount) @@ -934,18 +900,17 @@ double SD_task_get_execution_time(SD_task_t task, for (i = 0; i < workstation_nb; i++) { time = 0.0; if (flops_amount != NULL) - time = - SD_workstation_get_computation_time(workstation_list[i], - flops_amount[i]); + time = flops_amount[i] / sg_host_speed(workstation_list[i]); if (bytes_amount != NULL) for (j = 0; j < workstation_nb; j++) { - time += - SD_route_get_communication_time(workstation_list[i], - workstation_list[j], - bytes_amount[i * - workstation_nb - + j]); + if (bytes_amount[i * workstation_nb + j] !=0 ) { + time += (SD_route_get_latency(workstation_list[i], + workstation_list[j]) + + bytes_amount[i * workstation_nb + j] / + SD_route_get_bandwidth(workstation_list[i], + workstation_list[j])); + } } if (time > max_time) { @@ -957,15 +922,15 @@ double SD_task_get_execution_time(SD_task_t task, static XBT_INLINE void SD_task_do_schedule(SD_task_t task) { - if (!__SD_task_is_not_scheduled(task) && !__SD_task_is_schedulable(task)) + if (SD_task_get_state(task) > SD_SCHEDULABLE) THROWF(arg_error, 0, "Task '%s' has already been scheduled", SD_task_get_name(task)); /* update the task state */ if (task->unsatisfied_dependencies == 0) - __SD_task_set_state(task, SD_RUNNABLE); + SD_task_set_state(task, SD_RUNNABLE); else - __SD_task_set_state(task, SD_SCHEDULED); + SD_task_set_state(task, SD_SCHEDULED); } /** @@ -984,16 +949,13 @@ static XBT_INLINE void SD_task_do_schedule(SD_task_t task) * \see SD_task_unschedule() */ void SD_task_schedule(SD_task_t task, int workstation_count, - const SD_workstation_t * workstation_list, + const sg_host_t * workstation_list, const double *flops_amount, const double *bytes_amount, double rate) { - int communication_nb; - task->workstation_nb = 0; - task->rate = -1; xbt_assert(workstation_count > 0, "workstation_nb must be positive"); - task->workstation_nb = workstation_count; + task->host_count = workstation_count; task->rate = rate; if (flops_amount) { @@ -1006,7 +968,7 @@ void SD_task_schedule(SD_task_t task, int workstation_count, task->flops_amount = NULL; } - communication_nb = workstation_count * workstation_count; + int communication_nb = workstation_count * workstation_count; if (bytes_amount) { task->bytes_amount = (double*)xbt_realloc(task->bytes_amount, sizeof(double) * communication_nb); @@ -1017,11 +979,11 @@ void SD_task_schedule(SD_task_t task, int workstation_count, task->bytes_amount = NULL; } - task->workstation_list = (SD_workstation_t*) - xbt_realloc(task->workstation_list, - sizeof(SD_workstation_t) * workstation_count); - memcpy(task->workstation_list, workstation_list, - sizeof(SD_workstation_t) * workstation_count); + task->host_list = (sg_host_t*) + xbt_realloc(task->host_list, + sizeof(sg_host_t) * workstation_count); + memcpy(task->host_list, workstation_list, + sizeof(sg_host_t) * workstation_count); SD_task_do_schedule(task); } @@ -1038,10 +1000,10 @@ void SD_task_schedule(SD_task_t task, int workstation_count, */ void SD_task_unschedule(SD_task_t task) { - if (task->state_set != sd_global->scheduled_task_set && - task->state_set != sd_global->runnable_task_set && - task->state_set != sd_global->running_task_set && - task->state_set != sd_global->failed_task_set) + if (task->state != SD_SCHEDULED && + task->state != SD_RUNNABLE && + task->state != SD_RUNNING && + task->state != SD_FAILED) THROWF(arg_error, 0, "Task %s: the state must be SD_SCHEDULED, SD_RUNNABLE, SD_RUNNING or SD_FAILED", SD_task_get_name(task)); @@ -1050,18 +1012,19 @@ void SD_task_unschedule(SD_task_t task) && ((task->kind == SD_TASK_COMP_PAR_AMDAHL) || (task->kind == SD_TASK_COMM_PAR_MXN_1D_BLOCK))) { /* Don't free scheduling data for typed tasks */ __SD_task_destroy_scheduling_data(task); - xbt_free(task->workstation_list); - task->workstation_list=NULL; - task->workstation_nb = 0; + xbt_free(task->host_list); + task->host_list=NULL; + task->host_count = 0; } - if (__SD_task_is_running(task)) /* the task should become SD_FAILED */ - surf_action_cancel(task->surf_action); + if (SD_task_get_state(task) == SD_RUNNING) + /* the task should become SD_FAILED */ + task->surf_action->cancel(); else { if (task->unsatisfied_dependencies == 0) - __SD_task_set_state(task, SD_SCHEDULABLE); + SD_task_set_state(task, SD_SCHEDULABLE); else - __SD_task_set_state(task, SD_NOT_SCHEDULED); + SD_task_set_state(task, SD_NOT_SCHEDULED); } task->remains = task->amount; task->start_time = -1.0; @@ -1072,10 +1035,9 @@ void SD_task_unschedule(SD_task_t task) */ static void __SD_task_destroy_scheduling_data(SD_task_t task) { - if (!__SD_task_is_scheduled_or_runnable(task) - && !__SD_task_is_in_fifo(task)) + if (!__SD_task_is_scheduled_or_runnable(task)) THROWF(arg_error, 0, - "Task '%s' must be SD_SCHEDULED, SD_RUNNABLE or SD_IN_FIFO", + "Task '%s' must be SD_SCHEDULED or SD_RUNNABLE", SD_task_get_name(task)); xbt_free(task->flops_amount); @@ -1087,62 +1049,41 @@ static void __SD_task_destroy_scheduling_data(SD_task_t task) * the task doesn't have to wait in FIFOs. Otherwise, it is called by * __SD_task_just_done when the task gets out of its FIFOs. */ -void __SD_task_really_run(SD_task_t task) +void SD_task_run(SD_task_t task) { int i; sg_host_t *hosts; - xbt_assert(__SD_task_is_runnable_or_in_fifo(task), - "Task '%s' is not runnable or in a fifo! Task state: %d", + xbt_assert(SD_task_get_state(task) == SD_RUNNABLE, + "Task '%s' is not runnable! Task state: %d", SD_task_get_name(task), (int)SD_task_get_state(task)); - xbt_assert(task->workstation_list != NULL, + xbt_assert(task->host_list != NULL, "Task '%s': workstation_list is NULL!", SD_task_get_name(task)); - XBT_DEBUG("Really running task '%s'", SD_task_get_name(task)); - int host_nb = task->workstation_nb; - - /* set this task as current task for the workstations in sequential mode */ - for (i = 0; i < host_nb; i++) { - if (SD_workstation_get_access_mode(task->workstation_list[i]) == - SD_WORKSTATION_SEQUENTIAL_ACCESS) { - sg_host_sd(task->workstation_list[i])->current_task = task; - xbt_assert(__SD_workstation_is_busy(task->workstation_list[i]), - "The workstation should be busy now"); - } - } - - XBT_DEBUG("Task '%s' set as current task for its workstations", - SD_task_get_name(task)); - - /* start the task */ + XBT_DEBUG("Running task '%s'", SD_task_get_name(task)); /* Copy the elements of the task into the action */ + int host_nb = task->host_count; hosts = xbt_new(sg_host_t, host_nb); for (i = 0; i < host_nb; i++) - hosts[i] = task->workstation_list[i]; + hosts[i] = task->host_list[i]; double *flops_amount = xbt_new0(double, host_nb); double *bytes_amount = xbt_new0(double, host_nb * host_nb); - if(task->flops_amount) - memcpy(flops_amount, task->flops_amount, sizeof(double) * - host_nb); + memcpy(flops_amount, task->flops_amount, sizeof(double) * host_nb); if(task->bytes_amount) memcpy(bytes_amount, task->bytes_amount, sizeof(double) * host_nb * host_nb); - task->surf_action = surf_host_model_execute_parallel_task((surf_host_model_t)surf_host_model, - host_nb, - hosts, - flops_amount, - bytes_amount, - task->rate); + task->surf_action = surf_host_model->executeParallelTask( + host_nb, hosts, flops_amount, bytes_amount, task->rate); - surf_action_set_data(task->surf_action, task); + task->surf_action->setData(task); XBT_DEBUG("surf_action = %p", task->surf_action); @@ -1150,210 +1091,11 @@ void __SD_task_really_run(SD_task_t task) TRACE_surf_action(task->surf_action, task->category); __SD_task_destroy_scheduling_data(task); /* now the scheduling data are not useful anymore */ - __SD_task_set_state(task, SD_RUNNING); - xbt_assert(__SD_task_is_running(task), "Bad state of task '%s': %d", - SD_task_get_name(task), (int)SD_task_get_state(task)); - -} - -/* Tries to run a task. This function is called by SD_simulate() when a - * scheduled task becomes SD_RUNNABLE (i.e., when its dependencies are - * satisfied). - * If one of the workstations where the task is scheduled on is busy (in - * sequential mode), the task doesn't start. - * Returns whether the task has started. - */ -int __SD_task_try_to_run(SD_task_t task) -{ - - int can_start = 1; - int i; - SD_workstation_t workstation; - - xbt_assert(__SD_task_is_runnable(task), - "Task '%s' is not runnable! Task state: %d", + SD_task_set_state(task, SD_RUNNING); + xbt_assert(SD_task_get_state(task) == SD_RUNNING, + "Bad state of task '%s': %d", SD_task_get_name(task), (int)SD_task_get_state(task)); - - for (i = 0; i < task->workstation_nb; i++) { - can_start = can_start && - !__SD_workstation_is_busy(task->workstation_list[i]); - } - - XBT_DEBUG("Task '%s' can start: %d", SD_task_get_name(task), can_start); - - if (!can_start) { /* if the task cannot start and is not in the FIFOs yet */ - for (i = 0; i < task->workstation_nb; i++) { - workstation = task->workstation_list[i]; - if (sg_host_sd(workstation)->access_mode == SD_WORKSTATION_SEQUENTIAL_ACCESS) { - XBT_DEBUG("Pushing task '%s' in the FIFO of workstation '%s'", - SD_task_get_name(task), - SD_workstation_get_name(workstation)); - xbt_fifo_push(sg_host_sd(workstation)->task_fifo, task); - } - } - __SD_task_set_state(task, SD_IN_FIFO); - xbt_assert(__SD_task_is_in_fifo(task), "Bad state of task '%s': %d", - SD_task_get_name(task), (int)SD_task_get_state(task)); - XBT_DEBUG("Task '%s' state is now SD_IN_FIFO", SD_task_get_name(task)); - } else { - __SD_task_really_run(task); - } - - return can_start; -} - -/* This function is called by SD_simulate when a task is done. - * It updates task->state and task->action and executes if necessary the tasks - * which were waiting in FIFOs for the end of `task' - */ -void __SD_task_just_done(SD_task_t task) -{ - int i, j; - SD_workstation_t workstation; - - SD_task_t candidate; - int candidate_nb = 0; - int candidate_capacity = 8; - SD_task_t *candidates; - int can_start = 1; - - xbt_assert(__SD_task_is_running(task), - "The task must be running! Task state: %d", - (int)SD_task_get_state(task)); - xbt_assert(task->workstation_list != NULL, - "Task '%s': workstation_list is NULL!", - SD_task_get_name(task)); - - - candidates = xbt_new(SD_task_t, 8); - - __SD_task_set_state(task, SD_DONE); - surf_action_unref(task->surf_action); - task->surf_action = NULL; - - XBT_DEBUG("Looking for candidates"); - - /* if the task was executed on sequential workstations, - maybe we can execute the next task of the FIFO for each workstation */ - for (i = 0; i < task->workstation_nb; i++) { - workstation = task->workstation_list[i]; - XBT_DEBUG("Workstation '%s': access_mode = %d", - SD_workstation_get_name(workstation), (int)sg_host_sd(workstation)->access_mode); - if (sg_host_sd(workstation)->access_mode == SD_WORKSTATION_SEQUENTIAL_ACCESS) { - xbt_assert(sg_host_sd(workstation)->task_fifo != NULL, - "Workstation '%s' has sequential access but no FIFO!", - SD_workstation_get_name(workstation)); - xbt_assert(sg_host_sd(workstation)->current_task = - task, "Workstation '%s': current task should be '%s'", - SD_workstation_get_name(workstation), - SD_task_get_name(task)); - - /* the task is over so we can release the workstation */ - sg_host_sd(workstation)->current_task = NULL; - - XBT_DEBUG("Getting candidate in FIFO"); - candidate = (SD_task_t) - xbt_fifo_get_item_content(xbt_fifo_get_first_item - (sg_host_sd(workstation)->task_fifo)); - - if (candidate != NULL) { - XBT_DEBUG("Candidate: '%s'", SD_task_get_name(candidate)); - xbt_assert(__SD_task_is_in_fifo(candidate), - "Bad state of candidate '%s': %d", - SD_task_get_name(candidate), - (int)SD_task_get_state(candidate)); - } - - XBT_DEBUG("Candidate in fifo: %p", candidate); - - /* if there was a task waiting for my place */ - if (candidate != NULL) { - /* Unfortunately, we are not sure yet that we can execute the task now, - because the task can be waiting more deeply in some other - workstation's FIFOs ... - So we memorize all candidate tasks, and then we will check for each - candidate whether or not all its workstations are available. */ - - /* realloc if necessary */ - if (candidate_nb == candidate_capacity) { - candidate_capacity *= 2; - candidates = (SD_task_t*) - xbt_realloc(candidates, - sizeof(SD_task_t) * candidate_capacity); - } - - /* register the candidate */ - candidates[candidate_nb++] = candidate; - candidate->fifo_checked = 0; - } - } - } - - XBT_DEBUG("Candidates found: %d", candidate_nb); - - /* now we check every candidate task */ - for (i = 0; i < candidate_nb; i++) { - candidate = candidates[i]; - - if (candidate->fifo_checked) { - continue; /* we have already evaluated that task */ - } - - xbt_assert(__SD_task_is_in_fifo(candidate), - "Bad state of candidate '%s': %d", - SD_task_get_name(candidate), (int)SD_task_get_state(candidate)); - - for (j = 0; j < candidate->workstation_nb && can_start; j++) { - workstation = candidate->workstation_list[j]; - - /* I can start on this workstation if the workstation is shared - or if I am the first task in the FIFO */ - can_start = sg_host_sd(workstation)->access_mode == SD_WORKSTATION_SHARED_ACCESS - || candidate == - xbt_fifo_get_item_content(xbt_fifo_get_first_item - (sg_host_sd(workstation)->task_fifo)); - } - - XBT_DEBUG("Candidate '%s' can start: %d", SD_task_get_name(candidate), - can_start); - - /* now we are sure that I can start! */ - if (can_start) { - for (j = 0; j < candidate->workstation_nb && can_start; j++) { - workstation = candidate->workstation_list[j]; - - /* update the FIFO */ - if (sg_host_sd(workstation)->access_mode == SD_WORKSTATION_SEQUENTIAL_ACCESS) { - candidate = (SD_task_t)xbt_fifo_shift(sg_host_sd(workstation)->task_fifo); /* the return value is stored just for debugging */ - XBT_DEBUG("Head of the FIFO: '%s'", - (candidate != - NULL) ? SD_task_get_name(candidate) : "NULL"); - xbt_assert(candidate == candidates[i], - "Error in __SD_task_just_done: bad first task in the FIFO"); - } - } /* for each workstation */ - - /* finally execute the task */ - XBT_DEBUG("Task '%s' state: %d", SD_task_get_name(candidate), - (int)SD_task_get_state(candidate)); - __SD_task_really_run(candidate); - - XBT_DEBUG - ("Calling __SD_task_is_running: task '%s', state set: %p, running_task_set: %p, is running: %d", - SD_task_get_name(candidate), candidate->state_set, - sd_global->running_task_set, __SD_task_is_running(candidate)); - xbt_assert(__SD_task_is_running(candidate), - "Bad state of task '%s': %d", - SD_task_get_name(candidate), - (int)SD_task_get_state(candidate)); - XBT_DEBUG("Okay, the task is running."); - - } /* can start */ - candidate->fifo_checked = 1; - } /* for each candidate */ - - xbt_free(candidates); } /* @@ -1387,7 +1129,7 @@ static void __SD_task_remove_dependencies(SD_task_t task) double SD_task_get_start_time(SD_task_t task) { if (task->surf_action) - return surf_action_get_start_time(task->surf_action); + return task->surf_action->getStartTime(); else return task->start_time; } @@ -1406,7 +1148,7 @@ double SD_task_get_start_time(SD_task_t task) double SD_task_get_finish_time(SD_task_t task) { if (task->surf_action) /* should never happen as actions are destroyed right after their completion */ - return surf_action_get_finish_time(task->surf_action); + return task->surf_action->getFinishTime(); else return task->finish_time; } @@ -1422,9 +1164,9 @@ void SD_task_distribute_comp_amdahl(SD_task_t task, int ws_count) SD_task_get_name(task)); task->flops_amount = xbt_new0(double, ws_count); task->bytes_amount = xbt_new0(double, ws_count * ws_count); - xbt_free(task->workstation_list); - task->workstation_nb = ws_count; - task->workstation_list = xbt_new0(SD_workstation_t, ws_count); + xbt_free(task->host_list); + task->host_count = ws_count; + task->host_list = xbt_new0(sg_host_t, ws_count); for(i=0;iflops_amount[i] = @@ -1455,7 +1197,7 @@ void SD_task_distribute_comp_amdahl(SD_task_t task, int ws_count) * comm cost alongside to comp one) */ void SD_task_schedulev(SD_task_t task, int count, - const SD_workstation_t * list) + const sg_host_t * list) { int i, j; SD_dependency_t dep; @@ -1468,11 +1210,11 @@ void SD_task_schedulev(SD_task_t task, int count, SD_task_distribute_comp_amdahl(task, count); case SD_TASK_COMM_E2E: case SD_TASK_COMP_SEQ: - xbt_assert(task->workstation_nb == count, + xbt_assert(task->host_count == count, "Got %d locations, but were expecting %d locations", - count,task->workstation_nb); + count,task->host_count); for (i = 0; i < count; i++) - task->workstation_list[i] = list[i]; + task->host_list[i] = list[i]; if (SD_task_get_kind(task)== SD_TASK_COMP_SEQ && !task->flops_amount){ /*This task has failed and is rescheduled. Reset the flops_amount*/ task->flops_amount = xbt_new0(double, 1); @@ -1487,8 +1229,8 @@ void SD_task_schedulev(SD_task_t task, int count, if (task->kind == SD_TASK_COMM_E2E) { XBT_VERB("Schedule comm task %s between %s -> %s. It costs %.f bytes", SD_task_get_name(task), - SD_workstation_get_name(task->workstation_list[0]), - SD_workstation_get_name(task->workstation_list[1]), + sg_host_get_name(task->host_list[0]), + sg_host_get_name(task->host_list[1]), task->bytes_amount[2]); } @@ -1498,23 +1240,22 @@ void SD_task_schedulev(SD_task_t task, int count, if (task->kind == SD_TASK_COMP_SEQ) { XBT_VERB("Schedule computation task %s on %s. It costs %.f flops", SD_task_get_name(task), - SD_workstation_get_name(task->workstation_list[0]), + sg_host_get_name(task->host_list[0]), task->flops_amount[0]); xbt_dynar_foreach(task->tasks_before, cpt, dep) { SD_task_t before = dep->src; if (before->kind == SD_TASK_COMM_E2E) { - before->workstation_list[1] = task->workstation_list[0]; + before->host_list[1] = task->host_list[0]; - if (before->workstation_list[0] && - (__SD_task_is_schedulable(before) - || __SD_task_is_not_scheduled(before))) { + if (before->host_list[0] && + (SD_task_get_state(before)< SD_SCHEDULED)) { SD_task_do_schedule(before); XBT_VERB ("Auto-Schedule comm task %s between %s -> %s. It costs %.f bytes", SD_task_get_name(before), - SD_workstation_get_name(before->workstation_list[0]), - SD_workstation_get_name(before->workstation_list[1]), + sg_host_get_name(before->host_list[0]), + sg_host_get_name(before->host_list[1]), before->bytes_amount[2]); } } @@ -1522,16 +1263,15 @@ void SD_task_schedulev(SD_task_t task, int count, xbt_dynar_foreach(task->tasks_after, cpt, dep) { SD_task_t after = dep->dst; if (after->kind == SD_TASK_COMM_E2E) { - after->workstation_list[0] = task->workstation_list[0]; - if (after->workstation_list[1] - && (__SD_task_is_not_scheduled(after) - || __SD_task_is_schedulable(after))) { + after->host_list[0] = task->host_list[0]; + if (after->host_list[1] + && (SD_task_get_state(after)< SD_SCHEDULED)) { SD_task_do_schedule(after); XBT_VERB ("Auto-Schedule comm task %s between %s -> %s. It costs %.f bytes", SD_task_get_name(after), - SD_workstation_get_name(after->workstation_list[0]), - SD_workstation_get_name(after->workstation_list[1]), + sg_host_get_name(after->host_list[0]), + sg_host_get_name(after->host_list[1]), after->bytes_amount[2]); } @@ -1543,42 +1283,42 @@ void SD_task_schedulev(SD_task_t task, int count, if (task->kind == SD_TASK_COMP_PAR_AMDAHL) { XBT_VERB("Schedule computation task %s on %d workstations. %.f flops" " will be distributed following Amdahl's Law", - SD_task_get_name(task), task->workstation_nb, + SD_task_get_name(task), task->host_count, task->flops_amount[0]); xbt_dynar_foreach(task->tasks_before, cpt, dep) { SD_task_t before = dep->src; if (before->kind == SD_TASK_COMM_PAR_MXN_1D_BLOCK){ - if (!before->workstation_list){ + if (!before->host_list){ XBT_VERB("Sender side of Task %s is not scheduled yet", SD_task_get_name(before)); - before->workstation_list = xbt_new0(SD_workstation_t, count); - before->workstation_nb = count; + before->host_list = xbt_new0(sg_host_t, count); + before->host_count = count; XBT_VERB("Fill the workstation list with list of Task '%s'", SD_task_get_name(task)); for (i=0;iworkstation_list[i] = task->workstation_list[i]; + before->host_list[i] = task->host_list[i]; } else { XBT_VERB("Build communication matrix for task '%s'", SD_task_get_name(before)); int src_nb, dst_nb; double src_start, src_end, dst_start, dst_end; - src_nb = before->workstation_nb; + src_nb = before->host_count; dst_nb = count; - before->workstation_list = (SD_workstation_t*) xbt_realloc( - before->workstation_list, - (before->workstation_nb+count)*sizeof(s_SD_workstation_t)); + before->host_list = (sg_host_t*) xbt_realloc( + before->host_list, + (before->host_count+count)*sizeof(sg_host_t)); for(i=0; iworkstation_list[before->workstation_nb+i] = - task->workstation_list[i]; + before->host_list[before->host_count+i] = + task->host_list[i]; - before->workstation_nb += count; + before->host_count += count; xbt_free(before->flops_amount); xbt_free(before->bytes_amount); before->flops_amount = xbt_new0(double, - before->workstation_nb); + before->host_count); before->bytes_amount = xbt_new0(double, - before->workstation_nb* - before->workstation_nb); + before->host_count* + before->host_count); for(i=0;iamount/src_nb; @@ -1587,8 +1327,8 @@ void SD_task_schedulev(SD_task_t task, int count, dst_start = j*before->amount/dst_nb; dst_end = dst_start + before->amount/dst_nb; XBT_VERB("(%s->%s): (%.2f, %.2f)-> (%.2f, %.2f)", - SD_workstation_get_name(before->workstation_list[i]), - SD_workstation_get_name(before->workstation_list[src_nb+j]), + sg_host_get_name(before->host_list[i]), + sg_host_get_name(before->host_list[src_nb+j]), src_start, src_end, dst_start, dst_end); if ((src_end <= dst_start) || (dst_end <= src_start)) { before->bytes_amount[i*(src_nb+dst_nb)+src_nb+j]=0.0; @@ -1601,8 +1341,7 @@ void SD_task_schedulev(SD_task_t task, int count, } } - if (__SD_task_is_schedulable(before) || - __SD_task_is_not_scheduled(before)) { + if (SD_task_get_state(before)< SD_SCHEDULED) { SD_task_do_schedule(before); XBT_VERB ("Auto-Schedule redistribution task %s. Send %.f bytes from %d hosts to %d hosts.", @@ -1614,37 +1353,37 @@ void SD_task_schedulev(SD_task_t task, int count, xbt_dynar_foreach(task->tasks_after, cpt, dep) { SD_task_t after = dep->dst; if (after->kind == SD_TASK_COMM_PAR_MXN_1D_BLOCK){ - if (!after->workstation_list){ + if (!after->host_list){ XBT_VERB("Receiver side of Task '%s' is not scheduled yet", SD_task_get_name(after)); - after->workstation_list = xbt_new0(SD_workstation_t, count); - after->workstation_nb = count; + after->host_list = xbt_new0(sg_host_t, count); + after->host_count = count; XBT_VERB("Fill the workstation list with list of Task '%s'", SD_task_get_name(task)); for (i=0;iworkstation_list[i] = task->workstation_list[i]; + after->host_list[i] = task->host_list[i]; } else { int src_nb, dst_nb; double src_start, src_end, dst_start, dst_end; src_nb = count; - dst_nb = after->workstation_nb; - after->workstation_list = (SD_workstation_t*) xbt_realloc( - after->workstation_list, - (after->workstation_nb+count)*sizeof(s_SD_workstation_t)); - for(i=after->workstation_nb - 1; i>=0; i--) - after->workstation_list[count+i] = after->workstation_list[i]; + dst_nb = after->host_count; + after->host_list = (sg_host_t*) xbt_realloc( + after->host_list, + (after->host_count+count)*sizeof(sg_host_t)); + for(i=after->host_count - 1; i>=0; i--) + after->host_list[count+i] = after->host_list[i]; for(i=0; iworkstation_list[i] = task->workstation_list[i]; + after->host_list[i] = task->host_list[i]; - after->workstation_nb += count; + after->host_count += count; xbt_free(after->flops_amount); xbt_free(after->bytes_amount); - after->flops_amount = xbt_new0(double, after->workstation_nb); + after->flops_amount = xbt_new0(double, after->host_count); after->bytes_amount = xbt_new0(double, - after->workstation_nb* - after->workstation_nb); + after->host_count* + after->host_count); for(i=0;iamount/src_nb; @@ -1665,8 +1404,7 @@ void SD_task_schedulev(SD_task_t task, int count, } } - if (__SD_task_is_schedulable(after) || - __SD_task_is_not_scheduled(after)) { + if (SD_task_get_state(after)< SD_SCHEDULED) { SD_task_do_schedule(after); XBT_VERB ("Auto-Schedule redistribution task %s. Send %.f bytes from %d hosts to %d hosts.", @@ -1687,11 +1425,11 @@ void SD_task_schedulev(SD_task_t task, int count, void SD_task_schedulel(SD_task_t task, int count, ...) { va_list ap; - SD_workstation_t *list = xbt_new(SD_workstation_t, count); + sg_host_t *list = xbt_new(sg_host_t, count); int i; va_start(ap, count); for (i = 0; i < count; i++) { - list[i] = va_arg(ap, SD_workstation_t); + list[i] = va_arg(ap, sg_host_t); } va_end(ap); SD_task_schedulev(task, count, list);