diff --git a/src/cell.h b/src/cell.h
index 10454a9abb1a12730aa6d7af5406c4d543f1136c..3ae9617e821ded4ad80a5cfa7a2bd5dd3e726516 100644
--- a/src/cell.h
+++ b/src/cell.h
@@ -96,7 +96,7 @@ struct cell {
     int sortsize;
     
     /* The tasks computing this cell's density. */
-    struct task *density[27], *force[27];
+    struct task *density[8*27], *force[8*27];
     int nr_density, nr_force;
     
     /* The ghost task to link density to interactions. */
diff --git a/src/engine.c b/src/engine.c
index 920545dfa7c20d032e4ea927bee6a73704d94d50..f0fab9fa04cc59dd90d8f1691613177d08b820d3 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -463,6 +463,7 @@ void engine_repartition ( struct engine *e ) {
 void engine_addtasks_send ( struct engine *e , struct cell *ci , struct cell *cj ) {
 
     int k;
+    struct scheduler *s = &e->sched;
 
     /* Check if any of the density tasks are for the target node. */
     for ( k = 0 ; k < ci->nr_density ; k++ )
@@ -478,13 +479,13 @@ void engine_addtasks_send ( struct engine *e , struct cell *ci , struct cell *cj
         struct task *t_rho = scheduler_addtask( &e->sched , task_type_send_rho , task_subtype_none , 2*ci->tag + 1 , 0 , ci , cj , 0 );
 
         /* The send_rho task depends on the cell's ghost task. */
-        task_addunlock( ci->ghost , t_rho );
+        scheduler_addunlock( s , ci->ghost , t_rho );
 
         /* The send_rho task should unlock the super-cell's kick2 task. */
-        task_addunlock( t_rho , ci->super->kick2 );
+        scheduler_addunlock( s , t_rho , ci->super->kick2 );
 
         /* The send_xv task should unlock the super-cell's ghost task. */
-        task_addunlock( t_xv , ci->super->ghost );
+        scheduler_addunlock( s , t_xv , ci->super->ghost );
 
         }
         
@@ -509,6 +510,7 @@ void engine_addtasks_send ( struct engine *e , struct cell *ci , struct cell *cj
 void engine_addtasks_recv ( struct engine *e , struct cell *c , struct task *t_xv , struct task *t_rho ) {
 
     int k;
+    struct scheduler *s = &e->sched;
 
     /* Do we need to construct a recv task? */
     if ( t_xv != NULL || c->nr_density > 0 ) {
@@ -520,8 +522,8 @@ void engine_addtasks_recv ( struct engine *e , struct cell *c , struct task *t_x
         /* If there has been a higher-up recv task, then these tasks
            are implicit and depend on the higher-up task. */
         if ( t_xv != NULL ) {
-            task_addunlock( c->parent->recv_xv , c->recv_xv );
-            task_addunlock( c->parent->recv_rho , c->recv_rho );
+            scheduler_addunlock( s , c->parent->recv_xv , c->recv_xv );
+            scheduler_addunlock( s , c->parent->recv_rho , c->recv_rho );
             c->recv_xv->implicit = 1;
             c->recv_rho->implicit = 1;
             }
@@ -532,13 +534,13 @@ void engine_addtasks_recv ( struct engine *e , struct cell *c , struct task *t_x
         
         /* Add dependencies if there are density/force tasks. */
         for ( k = 0 ; k < c->nr_density ; k++ ) {
-            task_addunlock( c->recv_xv , c->density[k] );
-            task_addunlock( c->density[k] , t_rho );
+            scheduler_addunlock( s , c->recv_xv , c->density[k] );
+            scheduler_addunlock( s , c->density[k] , t_rho );
             }
         for ( k = 0 ; k < c->nr_force ; k++ )
-            task_addunlock( c->recv_rho , c->force[k] );
+            scheduler_addunlock( s , c->recv_rho , c->force[k] );
         if ( c->sorts != NULL )
-            task_addunlock( c->recv_xv , c->sorts );
+            scheduler_addunlock( s , c->recv_xv , c->sorts );
             
         }
         
@@ -850,7 +852,7 @@ void engine_maketasks ( struct engine *e ) {
             for ( j = 0 ; j < 8 ; j++ )
                 if ( t->ci->progeny[j] != NULL && t->ci->progeny[j]->sorts != NULL ) {
                     t->ci->progeny[j]->sorts->skip = 0;
-                    task_addunlock( t->ci->progeny[j]->sorts , t );
+                    scheduler_addunlock( sched , t->ci->progeny[j]->sorts , t );
                     }
         if ( t->type == task_type_self ) {
             atomic_inc( &t->ci->nr_tasks );
@@ -900,10 +902,10 @@ void engine_maketasks ( struct engine *e ) {
         
         /* Self-interaction? */
         if ( t->type == task_type_self && t->subtype == task_subtype_density ) {
-            task_addunlock( t , t->ci->super->ghost );
+            scheduler_addunlock( sched , t , t->ci->super->ghost );
             t2 = scheduler_addtask( sched , task_type_self , task_subtype_force , 0 , 0 , t->ci , NULL , 0 );
-            task_addunlock( t->ci->ghost , t2 );
-            task_addunlock( t2 , t->ci->super->kick2 );
+            scheduler_addunlock( sched , t->ci->ghost , t2 );
+            scheduler_addunlock( sched , t2 , t->ci->super->kick2 );
             t->ci->force[ atomic_inc( &t->ci->nr_force ) ] = t2;
             }
             
@@ -911,15 +913,15 @@ void engine_maketasks ( struct engine *e ) {
         else if ( t->type == task_type_pair && t->subtype == task_subtype_density ) {
             t2 = scheduler_addtask( sched , task_type_pair , task_subtype_force , 0 , 0 , t->ci , t->cj , 0 );
             if ( t->ci->nodeID == e->nodeID ) {
-                task_addunlock( t->ci->ghost , t2 );
-                task_addunlock( t , t->ci->super->ghost );
-                task_addunlock( t2 , t->ci->super->kick2 );
+                scheduler_addunlock( sched , t->ci->ghost , t2 );
+                scheduler_addunlock( sched , t , t->ci->super->ghost );
+                scheduler_addunlock( sched , t2 , t->ci->super->kick2 );
                 }
             if ( t->cj->nodeID == e->nodeID ) {
-                task_addunlock( t->cj->ghost , t2 );
+                scheduler_addunlock( sched , t->cj->ghost , t2 );
                 if ( t->ci->super != t->cj->super ) {
-                    task_addunlock( t , t->cj->super->ghost );
-                    task_addunlock( t2 , t->cj->super->kick2 );
+                    scheduler_addunlock( sched , t , t->cj->super->ghost );
+                    scheduler_addunlock( sched , t2 , t->cj->super->kick2 );
                     }
                 }
             t->ci->force[ atomic_inc( &t->ci->nr_force ) ] = t2;
@@ -930,15 +932,15 @@ void engine_maketasks ( struct engine *e ) {
         else if ( t->type == task_type_sub && t->subtype == task_subtype_density ) {
             t2 = scheduler_addtask( sched , task_type_sub , task_subtype_force , t->flags , 0 , t->ci , t->cj , 0 );
             if ( t->ci->nodeID == e->nodeID ) {
-                task_addunlock( t , t->ci->super->ghost );
-                task_addunlock( t->ci->ghost , t2 );
-                task_addunlock( t2 , t->ci->super->kick2 );
+                scheduler_addunlock( sched , t , t->ci->super->ghost );
+                scheduler_addunlock( sched , t->ci->ghost , t2 );
+                scheduler_addunlock( sched , t2 , t->ci->super->kick2 );
                 }
             if ( t->cj != NULL && t->cj->nodeID == e->nodeID ) {
-                task_addunlock( t->cj->ghost , t2 );
+                scheduler_addunlock( sched , t->cj->ghost , t2 );
                 if ( t->ci->super != t->cj->super ) {
-                    task_addunlock( t , t->cj->super->ghost );
-                    task_addunlock( t2 , t->cj->super->kick2 );
+                    scheduler_addunlock( sched , t , t->cj->super->ghost );
+                    scheduler_addunlock( sched , t2 , t->cj->super->kick2 );
                     }
                 }
             t->ci->force[ atomic_inc( &t->ci->nr_force ) ] = t2;
@@ -1219,7 +1221,8 @@ void engine_prepare ( struct engine *e ) {
                              (1 << task_type_send_xv) |
                              (1 << task_type_recv_xv) |
                              (1 << task_type_send_rho) |
-                             (1 << task_type_recv_rho) );
+                             (1 << task_type_recv_rho) |
+                             (1 << task_type_link) );
     // message( "scheduler_start took %.3f ms." , (double)(getticks() - tic2)/CPU_TPS*1000 );
     
     TIMER_TOC( timer_prepare );
@@ -1493,7 +1496,7 @@ void engine_step ( struct engine *e ) {
     /* First kick. */
     if ( e->step == 0 || !( e->policy & engine_policy_fixdt ) ) {
         TIMER_TIC
-        scheduler_start( &e->sched , (1 << task_type_kick1) );
+        scheduler_start( &e->sched , (1 << task_type_kick1) | (1 << task_type_link) );
         engine_launch( e , ( e->nr_threads > 8 ) ? 8 : e->nr_threads );
         TIMER_TOC( timer_kick1 );
         }
diff --git a/src/scheduler.c b/src/scheduler.c
index 64084571d7db1d16c4d373cfb522405759bb8d33..bda22f07346d8a7adf00045e65bee9533daf3947 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -50,6 +50,53 @@
 #include "scheduler.h"
 
 
+/**
+ * @brief Add an unlock_task to the given task.
+ *
+ * @param s The #scheduler.
+ * @param ta The unlocking #task.
+ * @param tb The #task that will be unlocked.
+ */
+ 
+void scheduler_addunlock ( struct scheduler *s , struct task *ta , struct task *tb ) {
+
+    /* Main loop. */
+    while ( 1 ) {
+
+        /* Follow the links. */
+        while ( ta->link != NULL )
+            ta = ta->link;
+
+        /* Get the index of the next free task. */
+        int ind = atomic_inc( &ta->nr_unlock_tasks );
+
+        /* Is there room in this task? */
+        if ( ind < task_maxunlock ) {
+            ta->unlock_tasks[ ind ] = tb;
+            break;
+            }
+
+        /* Otherwise, generate a link task. */
+        else {
+        
+            /* Only one thread should have to do this. */
+            if ( ind == task_maxunlock ) {
+                ta->link = scheduler_addtask( s , task_type_link , task_subtype_none , ta->flags , 0 , NULL , NULL , 0 );
+                ta->link->implicit = 1;
+                ta->unlock_tasks[ ind ] = ta->link;
+                }
+
+            /* Otherwise, reduce the count. */
+            else
+                atomic_dec( &ta->nr_unlock_tasks );
+
+            }
+            
+        }
+
+    }
+    
+
 /**
  * @brief Mapping function to append a ghost task to each cell.
  *
@@ -84,7 +131,7 @@ void scheduler_map_mkghosts ( struct cell *c , void *data ) {
     if (c->parent == NULL || c->parent->count >= space_subsize ) {
         c->kick1 = scheduler_addtask( s , task_type_kick1 , task_subtype_none , 0 , 0 , c , NULL , 0 );
         if ( c->parent != NULL )
-            task_addunlock( c->kick1 , c->parent->kick1 );
+            scheduler_addunlock( s , c->kick1 , c->parent->kick1 );
         }
     
     /* Append a kick2 task if we are local and the active super cell. */
@@ -94,7 +141,7 @@ void scheduler_map_mkghosts ( struct cell *c , void *data ) {
     /* If we are not the super cell ourselves, make our ghost depend
        on our parent cell. */
     if ( c->ghost != NULL && c->super != c ) {
-        task_addunlock( c->parent->ghost , c->ghost );
+        scheduler_addunlock( s , c->parent->ghost , c->ghost );
         c->ghost->implicit = 1;
         }
         
@@ -128,7 +175,7 @@ void scheduler_map_mkghosts_nokick1 ( struct cell *c , void *data ) {
     /* If we are not the super cell ourselves, make our ghost depend
        on our parent cell. */
     if ( c->super != c ) {
-        task_addunlock( c->parent->ghost , c->ghost );
+        scheduler_addunlock( s , c->parent->ghost , c->ghost );
         c->ghost->implicit = 1;
         }
         
@@ -149,7 +196,7 @@ void scheduler_map_mkkick1 ( struct cell *c , void *data ) {
     /* Append a kick1 task and make sure the parent depends on it. */
     c->kick1 = scheduler_addtask( s , task_type_kick1 , task_subtype_none , 0 , 0 , c , NULL , 0 );
     if ( c->parent != NULL )
-        task_addunlock( c->kick1 , c->parent->kick1 );
+        scheduler_addunlock( s , c->kick1 , c->parent->kick1 );
         
     /* Set a bogus super cell. */
     for ( finger = c ; finger->parent != NULL ; finger = finger->parent );
@@ -199,11 +246,11 @@ void scheduler_splittasks ( struct scheduler *s ) {
             }
         
         /* Empty task? */
-        if ( t->ci == NULL || ( t->type == task_type_pair && t->cj == NULL ) ) {
+        /* if ( t->ci == NULL || ( t->type == task_type_pair && t->cj == NULL ) ) {
             t->type = task_type_none;
             t->skip = 1;
             continue;
-            }
+            } */
             
         /* Non-local kick task? */
         if ( (t->type == task_type_kick1 || t->type == task_type_kick2 ) &&
@@ -454,7 +501,7 @@ void scheduler_splittasks ( struct scheduler *s ) {
                 else
                     ci->sorts->flags |= (1 << sid);
                 // lock_unlock_blind( &ci->lock );
-                task_addunlock( ci->sorts , t );
+                scheduler_addunlock( s , ci->sorts , t );
                 
                 /* Create the sort for cj. */
                 // lock_lock( &cj->lock );
@@ -463,7 +510,7 @@ void scheduler_splittasks ( struct scheduler *s ) {
                 else
                     cj->sorts->flags |= (1 << sid);
                 // lock_unlock_blind( &cj->lock );
-                task_addunlock( cj->sorts , t );
+                scheduler_addunlock( s , cj->sorts , t );
                 
                 }
                 
@@ -511,6 +558,7 @@ struct task *scheduler_addtask ( struct scheduler *s , int type , int subtype ,
     t->tic = 0;
     t->toc = 0;
     t->nr_unlock_tasks = 0;
+    t->link = NULL;
     
     /* Init the lock. */
     lock_init( &t->lock );
@@ -613,6 +661,9 @@ void scheduler_reset ( struct scheduler *s , int size ) {
             
         }
         
+    /* Reset the task data. */
+    bzero( s->tasks , sizeof(struct task) * size );
+        
     /* Reset the counters. */
     s->size = size;
     s->nr_tasks = 0;
diff --git a/src/scheduler.h b/src/scheduler.h
index e7f4f3df98e058f667c9c793b1e2672c891e21a4..3032c2c97ee8a60d511f495712a45e92deef87cc 100644
--- a/src/scheduler.h
+++ b/src/scheduler.h
@@ -86,3 +86,4 @@ void scheduler_map_mkghosts_nokick1 ( struct cell *c , void *data );
 void scheduler_map_mkkick1 ( struct cell *c , void *data );
 struct task *scheduler_done ( struct scheduler *s , struct task *t );
 struct task *scheduler_unlock ( struct scheduler *s , struct task *t );
+void scheduler_addunlock ( struct scheduler *s , struct task *ta , struct task *tb );
diff --git a/src/space.h b/src/space.h
index 1768ecefbc86e517236813d33248d8310bdf5fa4..e840cfb6ee2e628115a8219c2a026ab25ecf41a1 100644
--- a/src/space.h
+++ b/src/space.h
@@ -25,7 +25,7 @@
 #define space_cellallocchunk            1000
 #define space_splitratio                0.875f
 #define space_splitsize_default         400
-#define space_maxsize_default           3000
+#define space_maxsize_default           2000
 #define space_subsize_default           5000
 #define space_stretch                   1.10f
 #define space_maxreldx                  0.25f
diff --git a/src/task.c b/src/task.c
index 12161a8b60286a453041303a35fcf476f9f50915..a8d2f125734833fbd9e788ccfd8ff393e3b64613 100644
--- a/src/task.c
+++ b/src/task.c
@@ -50,7 +50,7 @@
 const char *taskID_names[task_type_count] = {   
     "none" , "sort" , "self" , "pair" , "sub" , "ghost" , 
     "kick1" , "kick2" , "send_xv" , "recv_xv" , "send_rho" ,
-    "recv_rho" };
+    "recv_rho" , "link" };
 
 
 /**
@@ -222,6 +222,8 @@ void task_rmunlock_blind ( struct task *ta , struct task *tb ) {
  
 void task_addunlock ( struct task *ta , struct task *tb ) {
 
+    error( "Use sched_addunlock instead." );
+
     /* Add the lock atomically. */
     ta->unlock_tasks[ atomic_inc( &ta->nr_unlock_tasks ) ] = tb;
 
diff --git a/src/task.h b/src/task.h
index c616f22a49fe5abfa6ca8c236256f2a232c04d19..300ce57b3293135554ccb4eeccf3a5af5c7134db 100644
--- a/src/task.h
+++ b/src/task.h
@@ -20,7 +20,7 @@
 
 /* Some constants. */
 #define task_maxwait                    3
-#define task_maxunlock                  64
+#define task_maxunlock                  31
 
 
 /* The different task types. */
@@ -37,6 +37,7 @@ enum task_types {
     task_type_recv_xv,
     task_type_send_rho,
     task_type_recv_rho,
+    task_type_link,
     task_type_count
     };
     
@@ -72,7 +73,8 @@ struct task {
     ticks tic, toc;
     
     int nr_unlock_tasks;
-    struct task *unlock_tasks[ task_maxunlock ];
+    struct task *unlock_tasks[ task_maxunlock + 1 ];
+    struct task *link;
 
     };