diff --git a/src/engine.c b/src/engine.c index 7287f47b40b06a691c778a5f8d3b6c0f04721564..b78956bb9ea976cfcc55a1454320ce9901801397 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 c8b9d7a46f8c788237e3b9ba7cb9d7d0a6e1370d..9e55deb1dd39a43f7f2eb6a771430a0dcfc5a746 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 25ffc9f2c2b9fff4596d680ef505e714c7595c07..000e4c8b136bcb3bc1184104c0a0bf617243108d 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 d1d343240b37f5afd5f41fecacf106b0e85f726f..bbacf24610f3803b0d7ac0d945b820f283116d8b 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 5f1475a46e4626e1f51db673d73fd84f86e6edb6..213da9510a28bd6bfea348510e373ef7bdd7d531 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 9c0ba6087d772d7362a98bc40a838c6fa3713166..5d72f5c61c85408e6b38e78351e661decba7dba6 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 };