/* Copyright (C) 2015-2022 Free Software Foundation, Inc.
   Contributed by Aldy Hernandez <aldyh@redhat.com>.

   This file is part of the GNU Offloading and Multi Processing Library
   (libgomp).

   Libgomp is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.

   Under Section 7 of GPL version 3, you are granted additional
   permissions described in the GCC Runtime Library Exception, version
   3.1, as published by the Free Software Foundation.

   You should have received a copy of the GNU General Public License and
   a copy of the GCC Runtime Library Exception along with this program;
   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
   <http://www.gnu.org/licenses/>.  */

/* Header file for a priority queue of GOMP tasks.  */

/* ?? Perhaps all the priority_tree_* functions are complex and rare
   enough to go out-of-line and be moved to priority_queue.c.  ??  */

#ifndef _PRIORITY_QUEUE_H_
#define _PRIORITY_QUEUE_H_

/* One task.  */

struct priority_node
{
  /* Next and previous chains in a circular doubly linked list for
     tasks within this task's priority.  */
  struct priority_node *next, *prev;
};

/* All tasks within the same priority.  */

struct priority_list
{
  /* Priority of the tasks in this set.  */
  int priority;

  /* Tasks.  */
  struct priority_node *tasks;

  /* This points to the last of the higher priority WAITING tasks.
     Remember that for the children queue, we have:

	parent_depends_on WAITING tasks.
	!parent_depends_on WAITING tasks.
	TIED tasks.

     This is a pointer to the last of the parent_depends_on WAITING
     tasks which are essentially, higher priority items within their
     priority.  */
  struct priority_node *last_parent_depends_on;
};

/* Another splay tree instantiation, for priority_list's.  */
typedef struct prio_splay_tree_node_s *prio_splay_tree_node;
typedef struct prio_splay_tree_s *prio_splay_tree;
typedef struct prio_splay_tree_key_s *prio_splay_tree_key;
struct prio_splay_tree_key_s {
  /* This structure must only containing a priority_list, as we cast
     prio_splay_tree_key to priority_list throughout.  */
  struct priority_list l;
};
#define splay_tree_prefix prio
#include "splay-tree.h"

/* The entry point into a priority queue of tasks.

   There are two alternate implementations with which to store tasks:
   as a balanced tree of sorts, or as a simple list of tasks.  If
   there are only priority-0 items (ROOT is NULL), we use the simple
   list, otherwise (ROOT is non-NULL) we use the tree.  */

struct priority_queue
{
  /* If t.root != NULL, this is a splay tree of priority_lists to hold
     all tasks.  This is only used if multiple priorities are in play,
     otherwise we use the priority_list `l' below to hold all
     (priority-0) tasks.  */
  struct prio_splay_tree_s t;

  /* If T above is NULL, only priority-0 items exist, so keep them
     in a simple list.  */
  struct priority_list l;
};

enum priority_insert_type {
  /* Insert at the beginning of a priority list.  */
  PRIORITY_INSERT_BEGIN,
  /* Insert at the end of a priority list.  */
  PRIORITY_INSERT_END
};

/* Used to determine in which queue a given priority node belongs in.
   See pnode field of gomp_task.  */

enum priority_queue_type
{
  PQ_TEAM,	    /* Node belongs in gomp_team's task_queue.  */
  PQ_CHILDREN,	    /* Node belongs in parent's children_queue.  */
  PQ_TASKGROUP,	    /* Node belongs in taskgroup->taskgroup_queue.  */
  PQ_IGNORED = 999
};

typedef bool (*priority_queue_predicate) (struct gomp_task *);

/* Priority queue implementation prototypes.  */

extern bool priority_queue_task_in_queue_p (enum priority_queue_type,
					    struct priority_queue *,
					    struct gomp_task *);
extern void priority_queue_dump (enum priority_queue_type,
				 struct priority_queue *);
extern void priority_queue_verify (enum priority_queue_type,
				   struct priority_queue *, bool);
extern struct gomp_task *priority_queue_find (enum priority_queue_type,
					      struct priority_queue *,
					      priority_queue_predicate);
extern void priority_tree_remove (enum priority_queue_type,
				  struct priority_queue *,
				  struct priority_node *);
extern struct gomp_task *priority_tree_next_task (enum priority_queue_type,
						  struct priority_queue *,
						  enum priority_queue_type,
						  struct priority_queue *,
						  bool *);

/* Return TRUE if there is more than one priority in HEAD.  This is
   used throughout to to choose between the fast path (priority 0 only
   items) and a world with multiple priorities.  */

static inline bool
priority_queue_multi_p (struct priority_queue *head)
{
  return __builtin_expect (head->t.root != NULL, 0);
}

/* Initialize a priority queue.  */

static inline void
priority_queue_init (struct priority_queue *head)
{
  head->t.root = NULL;
  /* To save a few microseconds, we don't initialize head->l.priority
     to 0 here.  It is implied that priority will be 0 if head->t.root
     == NULL.

     priority_tree_insert() will fix this when we encounter multiple
     priorities.  */
  head->l.tasks = NULL;
  head->l.last_parent_depends_on = NULL;
}

static inline void
priority_queue_free (struct priority_queue *head)
{
  /* There's nothing to do, as tasks were freed as they were removed
     in priority_queue_remove.  */
}

/* Forward declarations.  */
static inline size_t priority_queue_offset (enum priority_queue_type);
static inline struct gomp_task *priority_node_to_task
				(enum priority_queue_type,
				 struct priority_node *);
static inline struct priority_node *task_to_priority_node
				    (enum priority_queue_type,
				     struct gomp_task *);

/* Return TRUE if priority queue HEAD is empty.

   MODEL IS MEMMODEL_ACQUIRE if we should use an acquire atomic to
   read from the root of the queue, otherwise MEMMODEL_RELAXED if we
   should use a plain load.  */

static inline _Bool
priority_queue_empty_p (struct priority_queue *head, enum memmodel model)
{
  /* Note: The acquire barriers on the loads here synchronize with
     the write of a NULL in gomp_task_run_post_remove_parent.  It is
     not necessary that we synchronize with other non-NULL writes at
     this point, but we must ensure that all writes to memory by a
     child thread task work function are seen before we exit from
     GOMP_taskwait.  */
  if (priority_queue_multi_p (head))
    {
      if (model == MEMMODEL_ACQUIRE)
	return __atomic_load_n (&head->t.root, MEMMODEL_ACQUIRE) == NULL;
      return head->t.root == NULL;
    }
  if (model == MEMMODEL_ACQUIRE)
    return __atomic_load_n (&head->l.tasks, MEMMODEL_ACQUIRE) == NULL;
  return head->l.tasks == NULL;
}

/* Look for a given PRIORITY in HEAD.  Return it if found, otherwise
   return NULL.  This only applies to the tree variant in HEAD.  There
   is no point in searching for priorities in HEAD->L.  */

static inline struct priority_list *
priority_queue_lookup_priority (struct priority_queue *head, int priority)
{
  if (head->t.root == NULL)
    return NULL;
  struct prio_splay_tree_key_s k;
  k.l.priority = priority;
  return (struct priority_list *)
    prio_splay_tree_lookup (&head->t, &k);
}

/* Insert task in DATA, with PRIORITY, in the priority list in LIST.
   LIST contains items of type TYPE.

   If POS is PRIORITY_INSERT_BEGIN, the new task is inserted at the
   top of its respective priority.  If POS is PRIORITY_INSERT_END, the
   task is inserted at the end of its priority.

   If ADJUST_PARENT_DEPENDS_ON is TRUE, LIST is a children queue, and
   we must keep track of higher and lower priority WAITING tasks by
   keeping the queue's last_parent_depends_on field accurate.  This
   only applies to the children queue, and the caller must ensure LIST
   is a children queue in this case.

   If ADJUST_PARENT_DEPENDS_ON is TRUE, TASK_IS_PARENT_DEPENDS_ON is
   set to the task's parent_depends_on field.  If
   ADJUST_PARENT_DEPENDS_ON is FALSE, this field is irrelevant.

   Return the new priority_node.  */

static inline void
priority_list_insert (enum priority_queue_type type,
		      struct priority_list *list,
		      struct gomp_task *task,
		      int priority,
		      enum priority_insert_type pos,
		      bool adjust_parent_depends_on,
		      bool task_is_parent_depends_on)
{
  struct priority_node *node = task_to_priority_node (type, task);
  if (list->tasks)
    {
      /* If we are keeping track of higher/lower priority items,
	 but this is a lower priority WAITING task
	 (parent_depends_on != NULL), put it after all ready to
	 run tasks.  See the comment in
	 priority_queue_upgrade_task for a visual on how tasks
	 should be organized.  */
      if (adjust_parent_depends_on
	  && pos == PRIORITY_INSERT_BEGIN
	  && list->last_parent_depends_on
	  && !task_is_parent_depends_on)
	{
	  struct priority_node *last_parent_depends_on
	    = list->last_parent_depends_on;
	  node->next = last_parent_depends_on->next;
	  node->prev = last_parent_depends_on;
	}
      /* Otherwise, put it at the top/bottom of the queue.  */
      else
	{
	  node->next = list->tasks;
	  node->prev = list->tasks->prev;
	  if (pos == PRIORITY_INSERT_BEGIN)
	    list->tasks = node;
	}
      node->next->prev = node;
      node->prev->next = node;
    }
  else
    {
      node->next = node;
      node->prev = node;
      list->tasks = node;
    }
  if (adjust_parent_depends_on
      && list->last_parent_depends_on == NULL
      && task_is_parent_depends_on)
    list->last_parent_depends_on = node;
}

/* Tree version of priority_list_insert.  */

static inline void
priority_tree_insert (enum priority_queue_type type,
		      struct priority_queue *head,
		      struct gomp_task *task,
		      int priority,
		      enum priority_insert_type pos,
		      bool adjust_parent_depends_on,
		      bool task_is_parent_depends_on)
{
  if (__builtin_expect (head->t.root == NULL, 0))
    {
      /* The first time around, transfer any priority 0 items to the
	 tree.  */
      if (head->l.tasks != NULL)
	{
	  prio_splay_tree_node k = gomp_malloc (sizeof (*k));
	  k->left = NULL;
	  k->right = NULL;
	  k->key.l.priority = 0;
	  k->key.l.tasks = head->l.tasks;
	  k->key.l.last_parent_depends_on = head->l.last_parent_depends_on;
	  prio_splay_tree_insert (&head->t, k);
	  head->l.tasks = NULL;
	}
    }
  struct priority_list *list
    = priority_queue_lookup_priority (head, priority);
  if (!list)
    {
      prio_splay_tree_node k = gomp_malloc (sizeof (*k));
      k->left = NULL;
      k->right = NULL;
      k->key.l.priority = priority;
      k->key.l.tasks = NULL;
      k->key.l.last_parent_depends_on = NULL;
      prio_splay_tree_insert (&head->t, k);
      list = &k->key.l;
    }
  priority_list_insert (type, list, task, priority, pos,
			adjust_parent_depends_on,
			task_is_parent_depends_on);
}

/* Generic version of priority_*_insert.  */

static inline void
priority_queue_insert (enum priority_queue_type type,
		       struct priority_queue *head,
		       struct gomp_task *task,
		       int priority,
		       enum priority_insert_type pos,
		       bool adjust_parent_depends_on,
		       bool task_is_parent_depends_on)
{
#if _LIBGOMP_CHECKING_
  if (priority_queue_task_in_queue_p (type, head, task))
    gomp_fatal ("Attempt to insert existing task %p", task);
#endif
  if (priority_queue_multi_p (head) || __builtin_expect (priority > 0, 0))
    priority_tree_insert (type, head, task, priority, pos,
			  adjust_parent_depends_on,
			  task_is_parent_depends_on);
  else
    priority_list_insert (type, &head->l, task, priority, pos,
			  adjust_parent_depends_on,
			  task_is_parent_depends_on);
}

/* If multiple priorities are in play, return the highest priority
   task from within Q1 and Q2, while giving preference to tasks from
   Q1.  If the returned task is chosen from Q1, *Q1_CHOSEN_P is set to
   TRUE, otherwise it is set to FALSE.

   If multiple priorities are not in play (only 0 priorities are
   available), the next task is chosen exclusively from Q1.

   As a special case, Q2 can be NULL, in which case, we just choose
   the highest priority WAITING task in Q1.  This is an optimization
   to speed up looking through only one queue.

   We assume Q1 has at least one item.  */

static inline struct gomp_task *
priority_queue_next_task (enum priority_queue_type t1,
			  struct priority_queue *q1,
			  enum priority_queue_type t2,
			  struct priority_queue *q2,
			  bool *q1_chosen_p)
{
#if _LIBGOMP_CHECKING_
  if (priority_queue_empty_p (q1, MEMMODEL_RELAXED))
    gomp_fatal ("priority_queue_next_task: Q1 is empty");
#endif
  if (priority_queue_multi_p (q1))
    {
      struct gomp_task *t
	= priority_tree_next_task (t1, q1, t2, q2, q1_chosen_p);
      /* If T is NULL, there are no WAITING tasks in Q1.  In which
	 case, return any old (non-waiting) task which will cause the
	 caller to do the right thing when checking T->KIND ==
	 GOMP_TASK_WAITING.  */
      if (!t)
	{
#if _LIBGOMP_CHECKING_
	  if (*q1_chosen_p == false)
	    gomp_fatal ("priority_queue_next_task inconsistency");
#endif
	  return priority_node_to_task (t1, q1->t.root->key.l.tasks);
	}
      return t;
    }
  else
    {
      *q1_chosen_p = true;
      return priority_node_to_task (t1, q1->l.tasks);
    }
}

/* Remove NODE from LIST.

   If we are removing the one and only item in the list, and MODEL is
   MEMMODEL_RELEASE, use an atomic release to clear the list.

   If the list becomes empty after the remove, return TRUE.  */

static inline bool
priority_list_remove (struct priority_list *list,
		      struct priority_node *node,
		      enum memmodel model)
{
  bool empty = false;
  node->prev->next = node->next;
  node->next->prev = node->prev;
  if (list->tasks == node)
    {
      if (node->next != node)
	list->tasks = node->next;
      else
	{
	  /* We access task->children in GOMP_taskwait outside of
	     the task lock mutex region, so need a release barrier
	     here to ensure memory written by child_task->fn above
	     is flushed before the NULL is written.  */
	  if (model == MEMMODEL_RELEASE)
	    __atomic_store_n (&list->tasks, NULL, MEMMODEL_RELEASE);
	  else
	    list->tasks = NULL;
	  empty = true;
	  goto remove_out;
	}
    }
remove_out:
#if _LIBGOMP_CHECKING_
  memset (node, 0xaf, sizeof (*node));
#endif
  return empty;
}

/* This is the generic version of priority_list_remove.

   Remove NODE from priority queue HEAD.  HEAD contains tasks of type TYPE.

   If we are removing the one and only item in the priority queue and
   MODEL is MEMMODEL_RELEASE, use an atomic release to clear the queue.

   If the queue becomes empty after the remove, return TRUE.  */

static inline bool
priority_queue_remove (enum priority_queue_type type,
		       struct priority_queue *head,
		       struct gomp_task *task,
		       enum memmodel model)
{
#if _LIBGOMP_CHECKING_
  if (!priority_queue_task_in_queue_p (type, head, task))
    gomp_fatal ("Attempt to remove missing task %p", task);
#endif
  if (priority_queue_multi_p (head))
    {
      priority_tree_remove (type, head, task_to_priority_node (type, task));
      if (head->t.root == NULL)
	{
	  if (model == MEMMODEL_RELEASE)
	    /* Errr, we store NULL twice, the alternative would be to
	       use an atomic release directly in the splay tree
	       routines.  Worth it?  */
	    __atomic_store_n (&head->t.root, NULL, MEMMODEL_RELEASE);
	  return true;
	}
      return false;
    }
  else
    return priority_list_remove (&head->l,
				 task_to_priority_node (type, task), model);
}

#endif /* _PRIORITY_QUEUE_H_ */
