- 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));
-
-}
-
-/* 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_get_state(task) == SD_RUNNABLE,
- "Task '%s' is not runnable! Task state: %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_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_get_state(task)== SD_RUNNING,
- "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);
- task->surf_action->unref();
- 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_get_state(candidate) == SD_IN_FIFO,
- "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_get_state(candidate) == SD_IN_FIFO,
- "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' on workstation %s (%d task left)",
- (candidate !=
- NULL) ? SD_task_get_name(candidate) : "NULL",
- SD_workstation_get_name(workstation),
- xbt_fifo_size(sg_host_sd(workstation)->task_fifo));
- 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: %d",
- SD_task_get_name(candidate), candidate->state);
- xbt_assert(SD_task_get_state(candidate) == SD_RUNNING,
- "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);
-}
-
-/*
- * Remove all dependencies associated with a task. This function is called
- * when the task is destroyed.
- */
-static 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;
- while (!xbt_dynar_is_empty(task->tasks_before)) {
- xbt_dynar_get_cpy(task->tasks_before, 0, &dependency);
- SD_task_dependency_remove(dependency->src, dependency->dst);
- }
-
- while (!xbt_dynar_is_empty(task->tasks_after)) {
- xbt_dynar_get_cpy(task->tasks_after, 0, &dependency);
- SD_task_dependency_remove(dependency->src, dependency->dst);
- }