Example #1
0
static inline bool
gomp_task_run_pre (struct gomp_task *child_task, struct gomp_task *parent,
		   struct gomp_taskgroup *taskgroup, struct gomp_team *team)
{
  if (parent)
    {
      if (parent->children == child_task)
	parent->children = child_task->next_child;
      if (__builtin_expect (child_task->parent_depends_on, 0)
	  && parent->taskwait->last_parent_depends_on == child_task)
	{
	  if (child_task->prev_child->kind == GOMP_TASK_WAITING
	      && child_task->prev_child->parent_depends_on)
	    parent->taskwait->last_parent_depends_on = child_task->prev_child;
	  else
	    parent->taskwait->last_parent_depends_on = NULL;
	}
    }
  if (taskgroup && taskgroup->children == child_task)
    taskgroup->children = child_task->next_taskgroup;
  child_task->prev_queue->next_queue = child_task->next_queue;
  child_task->next_queue->prev_queue = child_task->prev_queue;
  if (team->task_queue == child_task)
    {
      if (child_task->next_queue != child_task)
	team->task_queue = child_task->next_queue;
      else
	team->task_queue = NULL;
    }
  child_task->kind = GOMP_TASK_TIED;
  if (--team->task_queued_count == 0)
    gomp_team_barrier_clear_task_pending (&team->barrier);
  if ((gomp_team_barrier_cancelled (&team->barrier)
       || (taskgroup && taskgroup->cancelled))
      && !child_task->copy_ctors_done)
    return true;
  return false;
}
Example #2
0
File: task.c Project: jtramm/gcc
static inline bool
gomp_task_run_pre (struct gomp_task *child_task, struct gomp_task *parent,
		   struct gomp_team *team)
{
#if _LIBGOMP_CHECKING
  verify_children_queue (child_task, parent);
  verify_taskgroup_queue (child_task);
  verify_task_queue (child_task, team);
#endif

  if (parent)
    {
      /* Adjust children such that it will point to a next child,
	 while the current one is scheduled to be executed.  This way,
	 GOMP_taskwait (and others) can schedule a next task while
	 waiting.

	 Do not remove it entirely from the circular list, as it is
	 still a child, though not one we should consider first (say
	 by GOMP_taskwait).  */
      if (parent->children == child_task)
	parent->children = child_task->next_child;
      /* TIED tasks cannot come before WAITING tasks.  If we're about
	 to make this task TIED, rewire things appropriately.
	 However, a TIED task at the end is perfectly fine.  */
      else if (child_task->next_child->kind == GOMP_TASK_WAITING
	       && child_task->next_child != parent->children)
	{
	  /* Remove from the list.  */
	  child_task->prev_child->next_child = child_task->next_child;
	  child_task->next_child->prev_child = child_task->prev_child;
	  /* Rewire at the end of its siblings.  */
	  child_task->next_child = parent->children;
	  child_task->prev_child = parent->children->prev_child;
	  parent->children->prev_child->next_child = child_task;
	  parent->children->prev_child = child_task;
	}

      /* If the current task (child_task) is at the top of the
	 parent's last_parent_depends_on, it's about to be removed
	 from it.  Adjust last_parent_depends_on appropriately.  */
      if (__builtin_expect (child_task->parent_depends_on, 0)
	  && parent->taskwait->last_parent_depends_on == child_task)
	{
	  /* The last_parent_depends_on list was built with all
	     parent_depends_on entries linked to the prev_child.  Grab
	     the next last_parent_depends_on head from this prev_child if
	     available...  */
	  if (child_task->prev_child->kind == GOMP_TASK_WAITING
	      && child_task->prev_child->parent_depends_on)
	    parent->taskwait->last_parent_depends_on = child_task->prev_child;
	  else
	    {
	      /* ...otherwise, there are no more parent_depends_on
		 entries waiting to run.  In which case, clear the
		 list.  */
	      parent->taskwait->last_parent_depends_on = NULL;
	    }
	}
    }

  /* Adjust taskgroup to point to the next taskgroup.  See note above
     regarding adjustment of children as to why the child_task is not
     removed entirely from the circular list.  */
  struct gomp_taskgroup *taskgroup = child_task->taskgroup;
  if (taskgroup)
    {
      if (taskgroup->children == child_task)
	taskgroup->children = child_task->next_taskgroup;
      /* TIED tasks cannot come before WAITING tasks.  If we're about
	 to make this task TIED, rewire things appropriately.
	 However, a TIED task at the end is perfectly fine.  */
      else if (child_task->next_taskgroup->kind == GOMP_TASK_WAITING
	       && child_task->next_taskgroup != taskgroup->children)
	{
	  /* Remove from the list.  */
	  child_task->prev_taskgroup->next_taskgroup
	    = child_task->next_taskgroup;
	  child_task->next_taskgroup->prev_taskgroup
	    = child_task->prev_taskgroup;
	  /* Rewire at the end of its taskgroup.  */
	  child_task->next_taskgroup = taskgroup->children;
	  child_task->prev_taskgroup = taskgroup->children->prev_taskgroup;
	  taskgroup->children->prev_taskgroup->next_taskgroup = child_task;
	  taskgroup->children->prev_taskgroup = child_task;
	}
    }

  /* Remove child_task from the task_queue.  */
  child_task->prev_queue->next_queue = child_task->next_queue;
  child_task->next_queue->prev_queue = child_task->prev_queue;
  if (team->task_queue == child_task)
    {
      if (child_task->next_queue != child_task)
	team->task_queue = child_task->next_queue;
      else
	team->task_queue = NULL;
    }
  child_task->kind = GOMP_TASK_TIED;

  if (--team->task_queued_count == 0)
    gomp_team_barrier_clear_task_pending (&team->barrier);
  if ((gomp_team_barrier_cancelled (&team->barrier)
       || (taskgroup && taskgroup->cancelled))
      && !child_task->copy_ctors_done)
    return true;
  return false;
}