From 04dec54af17f39035a991d1b94baae1e0ce36355 Mon Sep 17 00:00:00 2001
From: Pedro Gonnet <gonnet@google.com>
Date: Mon, 16 May 2016 20:01:57 +0200
Subject: [PATCH] add a root task for all send/recv tasks.

---
 src/engine.c    | 12 ++++++++++++
 src/engine.h    |  3 +++
 src/runner.c    |  2 ++
 src/scheduler.c |  1 -
 src/task.c      |  2 +-
 src/task.h      |  1 +
 6 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/src/engine.c b/src/engine.c
index 7287f47b40..b78956bb9e 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -589,6 +589,9 @@ void engine_addtasks_send(struct engine *e, struct cell *ci, struct cell *cj) {
     struct task *t_rho = scheduler_addtask(s, task_type_send, task_subtype_none,
                                            2 * ci->tag + 1, 0, ci, cj, 0);
 
+    /* The first send should depend on the engine's send_root. */
+    scheduler_addunlock(s, e->send_root, t_xv);
+
     /* The send_rho task depends on the cell's ghost task. */
     scheduler_addunlock(s, ci->super->ghost, t_rho);
 
@@ -633,6 +636,9 @@ void engine_addtasks_recv(struct engine *e, struct cell *c, struct task *t_xv,
                                           2 * c->tag, 0, c, NULL, 0);
     t_rho = c->recv_rho = scheduler_addtask(
         s, task_type_recv, task_subtype_none, 2 * c->tag + 1, 0, c, NULL, 0);
+
+    /* The first recv should depend on the engine's recv_root. */
+    scheduler_addunlock(s, e->recv_root, t_xv);
   }
 
   /* Add dependencies. */
@@ -1414,6 +1420,12 @@ void engine_maketasks(struct engine *e) {
   /* Add the communication tasks if MPI is being used. */
   if ((e->policy & engine_policy_mpi) == engine_policy_mpi) {
 
+    /* Create root tasks for send/recv. */
+    e->send_root = scheduler_addtask(&e->sched, task_type_comm_root,
+                                     task_subtype_none, 0, 0, NULL, NULL, 0);
+    e->recv_root = scheduler_addtask(&e->sched, task_type_comm_root,
+                                     task_subtype_none, 0, 0, NULL, NULL, 0);
+
     /* Loop over the proxies. */
     for (int pid = 0; pid < e->nr_proxies; pid++) {
 
diff --git a/src/engine.h b/src/engine.h
index c8b9d7a46f..9e55deb1dd 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -162,6 +162,9 @@ struct engine {
   struct link *links;
   int nr_links, size_links;
 
+  /* Root task for all send and recv tasks. */
+  struct task *send_root, *recv_root;
+
   /* Are we talkative ? */
   int verbose;
 };
diff --git a/src/runner.c b/src/runner.c
index 25ffc9f2c2..000e4c8b13 100644
--- a/src/runner.c
+++ b/src/runner.c
@@ -1212,6 +1212,8 @@ void *runner_main(void *data) {
           scheduler_do_rewait((struct task *)t->ci, (struct task *)t->cj,
                               t->flags, t->rank);
           break;
+        case task_type_comm_root:
+          break;
         default:
           error("Unknown task type.");
       }
diff --git a/src/scheduler.c b/src/scheduler.c
index d1d343240b..bbacf24610 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -1066,7 +1066,6 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) {
   if (t->implicit) {
     for (int j = 0; j < t->nr_unlock_tasks; j++) {
       struct task *t2 = t->unlock_tasks[j];
-
       if (atomic_dec(&t2->wait) == 1) scheduler_enqueue(s, t2);
     }
   }
diff --git a/src/task.c b/src/task.c
index 5f1475a46e..213da9510a 100644
--- a/src/task.c
+++ b/src/task.c
@@ -46,7 +46,7 @@ const char *taskID_names[task_type_count] = {
     "none",      "sort",       "self",       "pair",    "sub",
     "init",      "ghost",      "drift",      "kick",    "send",
     "recv",      "grav_pp",    "grav_mm",    "grav_up", "grav_down",
-    "part_sort", "gpart_sort", "split_cell", "rewait"};
+    "part_sort", "gpart_sort", "split_cell", "rewait",  "comm_root"};
 
 const char *subtaskID_names[task_type_count] = {"none",  "density",
                                                 "force", "grav"};
diff --git a/src/task.h b/src/task.h
index 9c0ba6087d..5d72f5c61c 100644
--- a/src/task.h
+++ b/src/task.h
@@ -49,6 +49,7 @@ enum task_types {
   task_type_gpart_sort,
   task_type_split_cell,
   task_type_rewait,
+  task_type_comm_root,
   task_type_count
 };
 
-- 
GitLab