From a99f589a93b8e83cafab7689a1baed1cfb08e7ef Mon Sep 17 00:00:00 2001
From: Pedro Gonnet <gonnet@google.com>
Date: Mon, 15 Apr 2019 22:54:56 +0200
Subject: [PATCH] replace the cell's mpi.hydro.recv_xv task pointer with the
 new linked recv pointers.

---
 src/cell.c             | 16 ++++++++++------
 src/cell.h             |  5 +----
 src/engine_maketasks.c |  2 +-
 src/engine_marktasks.c |  8 ++++----
 src/scheduler.h        | 23 +++++++++++++++++++++++
 src/space.c            |  4 ++--
 6 files changed, 41 insertions(+), 17 deletions(-)

diff --git a/src/cell.c b/src/cell.c
index 9d192caf87..1036110d0c 100644
--- a/src/cell.c
+++ b/src/cell.c
@@ -207,7 +207,9 @@ int cell_link_foreign_parts(struct cell *c, struct part *parts) {
 #endif
 
   /* Do we have a hydro task at this level? */
-  if (c->mpi.hydro.recv_xv != NULL) {
+  struct link *l = c->mpi.recv;
+  while (l != NULL && l->t->subtype != task_subtype_xv) l = l->next;
+  if (l != NULL) {
 
     /* Recursively attach the parts */
     const int counts = cell_link_parts(c, parts);
@@ -303,7 +305,9 @@ int cell_count_parts_for_tasks(const struct cell *c) {
 #endif
 
   /* Do we have a hydro task at this level? */
-  if (c->mpi.hydro.recv_xv != NULL) {
+  struct link *l = c->mpi.recv;
+  while (l != NULL && l->t->subtype != task_subtype_xv) l = l->next;
+  if (l != NULL) {
     return c->hydro.count;
   }
 
@@ -3259,7 +3263,7 @@ int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) {
 
         /* If the local cell is active, receive data from the foreign cell. */
         if (cj_active) {
-          scheduler_activate(s, ci->mpi.hydro.recv_xv);
+          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_xv);
           if (ci_active) {
             scheduler_activate(s, ci->mpi.hydro.recv_rho);
 
@@ -3309,7 +3313,7 @@ int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) {
 
         /* If the local cell is active, receive data from the foreign cell. */
         if (ci_active) {
-          scheduler_activate(s, cj->mpi.hydro.recv_xv);
+          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_xv);
           if (cj_active) {
             scheduler_activate(s, cj->mpi.hydro.recv_rho);
 
@@ -3658,7 +3662,7 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s) {
       if (ci_nodeID != nodeID) {
 
         if (cj_active) {
-          scheduler_activate(s, ci->mpi.hydro.recv_xv);
+          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_xv);
           scheduler_activate(s, ci->mpi.hydro.recv_rho);
 
           /* If the local cell is active, more stuff will be needed. */
@@ -3690,7 +3694,7 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s) {
 
         /* If the local cell is active, receive data from the foreign cell. */
         if (ci_active) {
-          scheduler_activate(s, cj->mpi.hydro.recv_xv);
+          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_xv);
           scheduler_activate(s, cj->mpi.hydro.recv_rho);
 
           /* If the local cell is active, more stuff will be needed. */
diff --git a/src/cell.h b/src/cell.h
index b5263acb2e..c1bc2d7ed1 100644
--- a/src/cell.h
+++ b/src/cell.h
@@ -576,14 +576,11 @@ struct cell {
       /* Single list of all send tasks associated with this cell. */
       struct link *send;
 
-      /* Single list of all recv tasks associated with this cel. */
+      /* Single list of all recv tasks associated with this cell. */
       struct link *recv;
     };
 
     struct {
-      /* Task receiving hydro data (positions). */
-      struct task *recv_xv;
-
       /* Task receiving hydro data (density). */
       struct task *recv_rho;
 
diff --git a/src/engine_maketasks.c b/src/engine_maketasks.c
index 7cfa13a5c7..b1fb70fb94 100644
--- a/src/engine_maketasks.c
+++ b/src/engine_maketasks.c
@@ -328,7 +328,7 @@ void engine_addtasks_recv_hydro(struct engine *e, struct cell *c,
                              c->mpi.tag, 0, c, NULL);
   }
 
-  c->mpi.hydro.recv_xv = t_xv;
+  engine_addlink(e, &c->mpi.recv, t_xv);
   c->mpi.hydro.recv_rho = t_rho;
   c->mpi.hydro.recv_gradient = t_gradient;
   c->mpi.hydro.recv_ti = t_ti;
diff --git a/src/engine_marktasks.c b/src/engine_marktasks.c
index 4d689ab0e6..f6a70e9926 100644
--- a/src/engine_marktasks.c
+++ b/src/engine_marktasks.c
@@ -362,7 +362,7 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
 
           /* If the local cell is active, receive data from the foreign cell. */
           if (cj_active_hydro) {
-            scheduler_activate(s, ci->mpi.hydro.recv_xv);
+            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_xv);
             if (ci_active_hydro) {
               scheduler_activate(s, ci->mpi.hydro.recv_rho);
 #ifdef EXTRA_HYDRO_LOOP
@@ -406,7 +406,7 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
           /* If the local cell is active, receive data from the foreign cell. */
           if (ci_active_hydro) {
 
-            scheduler_activate(s, cj->mpi.hydro.recv_xv);
+            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_xv);
             if (cj_active_hydro) {
               scheduler_activate(s, cj->mpi.hydro.recv_rho);
 #ifdef EXTRA_HYDRO_LOOP
@@ -462,7 +462,7 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
         if (ci_nodeID != nodeID) {
 
           if (cj_active_stars) {
-            scheduler_activate(s, ci->mpi.hydro.recv_xv);
+            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_xv);
             scheduler_activate(s, ci->mpi.hydro.recv_rho);
 
             /* If the local cell is active, more stuff will be needed. */
@@ -496,7 +496,7 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
 
           /* If the local cell is active, receive data from the foreign cell. */
           if (ci_active_stars) {
-            scheduler_activate(s, cj->mpi.hydro.recv_xv);
+            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_xv);
             scheduler_activate(s, cj->mpi.hydro.recv_rho);
 
             /* If the local cell is active, more stuff will be needed. */
diff --git a/src/scheduler.h b/src/scheduler.h
index e4c03b831e..95d6c4760b 100644
--- a/src/scheduler.h
+++ b/src/scheduler.h
@@ -152,6 +152,29 @@ scheduler_activate_send(struct scheduler *s, struct link *link,
   return l;
 }
 
+/**
+ * @brief Search and add an MPI recv task to the list of active tasks.
+ *
+ * @param s The #scheduler.
+ * @param link The first element in the linked list of links for the task of
+ * interest.
+ * @param subtype the task subtype to activate.
+ *
+ * @return The #link to the MPI recv task.
+ */
+__attribute__((always_inline)) INLINE static struct link *
+scheduler_activate_recv(struct scheduler *s, struct link *link,
+                        enum task_subtypes subtype) {
+  struct link *l = NULL;
+  for (l = link; l != NULL && l->t->subtype != subtype; l = l->next)
+    ;
+  if (l == NULL) {
+    error("Missing link to recv task.");
+  }
+  scheduler_activate(s, l->t);
+  return l;
+}
+
 /* Function prototypes. */
 void scheduler_clear_active(struct scheduler *s);
 void scheduler_init(struct scheduler *s, struct space *space, int nr_tasks,
diff --git a/src/space.c b/src/space.c
index 185d9e5951..cb63e86bd0 100644
--- a/src/space.c
+++ b/src/space.c
@@ -268,7 +268,7 @@ void space_rebuild_recycle_mapper(void *map_data, int num_elements,
 #if WITH_MPI
     c->mpi.tag = -1;
 
-    c->mpi.hydro.recv_xv = NULL;
+    c->mpi.recv = NULL;
     c->mpi.hydro.recv_rho = NULL;
     c->mpi.hydro.recv_gradient = NULL;
     c->mpi.hydro.recv_ti = NULL;
@@ -577,7 +577,7 @@ void space_regrid(struct space *s, int verbose) {
           c->grav.ti_old_multipole = ti_current;
 #ifdef WITH_MPI
           c->mpi.tag = -1;
-          c->mpi.hydro.recv_xv = NULL;
+          c->mpi.recv = NULL;
           c->mpi.hydro.recv_rho = NULL;
           c->mpi.hydro.recv_gradient = NULL;
           c->mpi.send = NULL;
-- 
GitLab