1 /* PR target/78694.  */
2 
3 enum
4 {
5   MEMMODEL_RELAXED,
6   MEMMODEL_ACQUIRE,
7   PRIORITY_INSERT_END
8 };
9 enum
10 {
11   PQ_CHILDREN,
12   PQ_TASKGROUP
13 };
14 struct gomp_team_state
15 {
16   struct gomp_team *team;
17 };
18 enum gomp_task_kind
19 {
20   GOMP_TASK_UNDEFERRED,
21   GOMP_TASK_WAITING
22 };
23 struct gomp_taskwait
24 {
25   _Bool in_taskwait;
26 };
27 struct gomp_task
28 {
29   struct gomp_task *parent;
30   int children_queue;
31   struct gomp_taskgroup *taskgroup;
32   int dependers;
33   struct gomp_taskwait taskwait;
34   enum gomp_task_kind kind;
35   _Bool in_tied_task;
36 } j, q, *n;
37 struct gomp_taskgroup
38 {
39   _Bool in_taskgroup_wait;
40   int num_children;
41 } l;
42 struct gomp_team
43 {
44   int task_queue;
45   int task_running_count;
46 };
47 struct gomp_thread
48 {
49   struct gomp_team_state ts;
50   struct gomp_task task;
51 } extern __thread a;
52 
53 int b, c, d, e, f, g, h, i, k, m, o, p, r;
54 
55 void priority_queue_next_task (struct gomp_task *, int, int);
56 int gomp_task_run_pre (struct gomp_task *, struct gomp_task, struct gomp_team);
57 void priority_queue_insert (int, struct gomp_task);
58 void priority_queue_insert2 (int, struct gomp_task, int, int, int);
59 void priority_queue_insert3 (int, struct gomp_task, int, int, int);
60 void gomp_sem_post (int);
61 void free (void *);
62 
63 _Bool s;
64 int
GOMP_taskgroup_end()65 GOMP_taskgroup_end ()
66 {
67   struct gomp_thread *t = &a;
68   struct gomp_team u = *t->ts.team;
69   struct gomp_task *v = &t->task, *w;
70   if (__atomic_load_n (&l.num_children, MEMMODEL_ACQUIRE))
71     while (1)
72       {
73 	if (l.num_children)
74 	  priority_queue_next_task (v, u.task_queue, r);
75 	else if (w)
76 	  free (w);
77 	if (n->kind == GOMP_TASK_WAITING)
78 	  {
79 	    s = gomp_task_run_pre (n, q, u);
80 	    if (__builtin_expect (s, 0))
81 	      {
82 		if (w)
83 		  free (w);
84 		goto finish_cancelled;
85 	      }
86 	    n = 0;
87 	    l.in_taskgroup_wait = 1;
88 	  }
89 	if (w)
90 	  {
91 	    t->task = *n;
92 	    if (__builtin_expect (p, 0))
93 	      if (o)
94 		t->task = *v;
95 	  }
96 	if (n)
97 	  {
98 	    struct gomp_task x = x;
99 	    for (; i; b++)
100 	      {
101 		struct gomp_task y = j;
102 		if (g)
103 		  continue;
104 		priority_queue_insert (PQ_CHILDREN, x);
105 		if (x.taskwait.in_taskwait)
106 		  priority_queue_insert2 (PQ_TASKGROUP, y, e, 0, d);
107 		if (h)
108 		  gomp_sem_post (f);
109 		priority_queue_insert3 (k, y, PRIORITY_INSERT_END, 0, d);
110 		++c;
111 	      }
112 	  }
113       finish_cancelled:
114 	w = (struct gomp_task *) (n - u.task_running_count - v);
115       }
116   v->taskgroup = (struct gomp_taskgroup *) m;
117   return 1;
118 }
119