diff --git a/src/engine.c b/src/engine.c
index 91e69aaba5ece90dd36f41895fae4fc88cb8d327..7b2d490570b3102ef252ae450f51df1b1429823f 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -1152,65 +1152,62 @@ void engine_make_hydroloop_tasks(struct engine *e) {
  *
  * @param e The #engine.
  */
-void engine_count_and_link_tasks(struct engine *e) {
+void engine_count_and_link_tasks_mapper(void *map_data, void *extra_data) {
 
+  struct engine *e = (struct engine *)extra_data;
+  struct task *t = (struct task *)map_data;
   struct scheduler *sched = &e->sched;
-  const int nr_tasks = sched->nr_tasks;
-
-  for (int k = 0; k < nr_tasks; k++) {
 
-    /* Get the current task. */
-    struct task *t = &sched->tasks[k];
-    if (t->skip) continue;
-
-    /* Link sort tasks together. */
-    if (t->type == task_type_sort && t->ci->split)
-      for (int j = 0; j < 8; j++)
-        if (t->ci->progeny[j] != NULL && t->ci->progeny[j]->sorts != NULL) {
-          t->ci->progeny[j]->sorts->skip = 0;
-          scheduler_addunlock(sched, t->ci->progeny[j]->sorts, t);
-        }
+  if (t->skip) return;
 
-    /* Link density tasks to cells. */
-    if (t->type == task_type_self) {
-      atomic_inc(&t->ci->nr_tasks);
-      if (t->subtype == task_subtype_density) {
-        t->ci->density = engine_addlink(e, t->ci->density, t);
-        atomic_inc(&t->ci->nr_density);
+  /* Link sort tasks together. */
+  if (t->type == task_type_sort && t->ci->split)
+    for (int j = 0; j < 8; j++)
+      if (t->ci->progeny[j] != NULL && t->ci->progeny[j]->sorts != NULL) {
+        t->ci->progeny[j]->sorts->skip = 0;
+        scheduler_addunlock(sched, t->ci->progeny[j]->sorts, t);
       }
-    } else if (t->type == task_type_pair) {
-      atomic_inc(&t->ci->nr_tasks);
-      atomic_inc(&t->cj->nr_tasks);
-      if (t->subtype == task_subtype_density) {
-        t->ci->density = engine_addlink(e, t->ci->density, t);
-        atomic_inc(&t->ci->nr_density);
+
+  /* Link density tasks to cells. */
+  /* TODO(pedro): Instead of locking the cell, re-write engine_addlink to
+     directly modify the second argument using the __atomic_exchange_n
+     intrinsic. */
+  if (t->type == task_type_self) {
+    atomic_inc(&t->ci->nr_tasks);
+    if (t->subtype == task_subtype_density) {
+      lock_lock(&t->ci->lock);
+      t->ci->density = engine_addlink(e, t->ci->density, t);
+      atomic_inc(&t->ci->nr_density);
+      lock_unlock_blind(&t->ci->lock);
+    }
+  } else if (t->type == task_type_pair) {
+    atomic_inc(&t->ci->nr_tasks);
+    atomic_inc(&t->cj->nr_tasks);
+    if (t->subtype == task_subtype_density) {
+      lock_lock(&t->ci->lock);
+      t->ci->density = engine_addlink(e, t->ci->density, t);
+      atomic_inc(&t->ci->nr_density);
+      lock_unlock_blind(&t->ci->lock);
+      lock_lock(&t->cj->lock);
+      t->cj->density = engine_addlink(e, t->cj->density, t);
+      atomic_inc(&t->cj->nr_density);
+      lock_unlock_blind(&t->cj->lock);
+    }
+  } else if (t->type == task_type_sub) {
+    atomic_inc(&t->ci->nr_tasks);
+    if (t->cj != NULL) atomic_inc(&t->cj->nr_tasks);
+    if (t->subtype == task_subtype_density) {
+      lock_lock(&t->ci->lock);
+      t->ci->density = engine_addlink(e, t->ci->density, t);
+      atomic_inc(&t->ci->nr_density);
+      lock_unlock_blind(&t->ci->lock);
+      if (t->cj != NULL) {
+        lock_lock(&t->cj->lock);
         t->cj->density = engine_addlink(e, t->cj->density, t);
         atomic_inc(&t->cj->nr_density);
-      }
-    } else if (t->type == task_type_sub) {
-      atomic_inc(&t->ci->nr_tasks);
-      if (t->cj != NULL) atomic_inc(&t->cj->nr_tasks);
-      if (t->subtype == task_subtype_density) {
-        t->ci->density = engine_addlink(e, t->ci->density, t);
-        atomic_inc(&t->ci->nr_density);
-        if (t->cj != NULL) {
-          t->cj->density = engine_addlink(e, t->cj->density, t);
-          atomic_inc(&t->cj->nr_density);
-        }
+        lock_unlock_blind(&t->cj->lock);
       }
     }
-
-    /* /\* Link gravity multipole tasks to the up/down tasks. *\/ */
-    /* if (t->type == task_type_grav_mm || */
-    /*     (t->type == task_type_sub && t->subtype == task_subtype_grav)) { */
-    /*   atomic_inc(&t->ci->nr_tasks); */
-    /*   scheduler_addunlock(sched, t->ci->grav_up, t); */
-    /*   scheduler_addunlock(sched, t, t->ci->grav_down); */
-    /*   if (t->cj != NULL && t->ci->grav_up != t->cj->grav_up) { */
-    /*     scheduler_addunlock(sched, t->cj->grav_up, t); */
-    /*     scheduler_addunlock(sched, t, t->cj->grav_down); */
-    /*   } */
-    /* } */
   }
 }
 
@@ -1249,7 +1246,8 @@ static inline void engine_make_hydro_loops_dependencies(struct scheduler *sched,
  *
  * @param e The #engine.
  */
-void engine_make_extra_hydroloop_tasks_mapper(void *map_data, void *extra_data) {
+void engine_make_extra_hydroloop_tasks_mapper(void *map_data,
+                                              void *extra_data) {
 
   struct engine *e = (struct engine *)extra_data;
   struct scheduler *sched = &e->sched;
@@ -1446,7 +1444,8 @@ void engine_maketasks(struct engine *e) {
   /* Count the number of tasks associated with each cell and
      store the density tasks in each cell, and make each sort
      depend on the sorts of its progeny. */
-  engine_count_and_link_tasks(e);
+  threadpool_map(&e->threadpool, engine_count_and_link_tasks_mapper,
+                 sched->tasks, sched->nr_tasks, sizeof(struct task), e);
 
   /* Append hierarchical tasks to each cells */
   for (int k = 0; k < nr_cells; k++)
@@ -1456,7 +1455,7 @@ void engine_maketasks(struct engine *e) {
      Each force task depends on the cell ghosts and unlocks the kick task
      of its super-cell. */
   threadpool_map(&e->threadpool, engine_make_extra_hydroloop_tasks_mapper,
-    sched->tasks, sched->nr_tasks, sizeof(struct task), e);
+                 sched->tasks, sched->nr_tasks, sizeof(struct task), e);
   // engine_make_extra_hydroloop_tasks(e);
 
   /* Add the communication tasks if MPI is being used. */