diff --git a/src/cell.c b/src/cell.c
index b08d9ce8b10b01e2f107ecaae5fb56936a4688e6..d4e8f9ff91490cd3a9dd9f78a3e72b19c55bf1cc 100644
--- a/src/cell.c
+++ b/src/cell.c
@@ -81,6 +81,47 @@ int cell_getsize(struct cell *c) {
   return count;
 }
 
+/**
+ * @brief Pack the data of the given cell and all it's sub-cells.
+ *
+ * @param c The #cell.
+ * @param pc Pointer to an array of packed cells in which the
+ *      cells will be packed.
+ *
+ * @return The number of packed cells.
+ */
+int cell_pack(struct cell *c, struct pcell *pc) {
+
+#ifdef WITH_MPI
+
+  /* Start by packing the data of the current cell. */
+  pc->h_max = c->h_max;
+  pc->ti_end_min = c->ti_end_min;
+  pc->ti_end_max = c->ti_end_max;
+  pc->count = c->count;
+  pc->gcount = c->gcount;
+  pc->scount = c->scount;
+  c->tag = pc->tag = atomic_inc(&cell_next_tag) % cell_max_tag;
+
+  /* Fill in the progeny, depth-first recursion. */
+  int count = 1;
+  for (int k = 0; k < 8; k++)
+    if (c->progeny[k] != NULL) {
+      pc->progeny[k] = count;
+      count += cell_pack(c->progeny[k], &pc[count]);
+    } else
+      pc->progeny[k] = -1;
+
+  /* Return the number of packed cells used. */
+  c->pcell_size = count;
+  return count;
+
+#else
+  error("SWIFT was not compiled with MPI support.");
+  return 0;
+#endif
+}
+
 /**
  * @brief Unpack the data of a given cell and its sub-cells.
  *
@@ -100,6 +141,7 @@ int cell_unpack(struct pcell *pc, struct cell *c, struct space *s) {
   c->ti_end_max = pc->ti_end_max;
   c->count = pc->count;
   c->gcount = pc->gcount;
+  c->scount = pc->scount;
   c->tag = pc->tag;
 
   /* Number of new cells created. */
@@ -111,6 +153,7 @@ int cell_unpack(struct pcell *pc, struct cell *c, struct space *s) {
       struct cell *temp = space_getcell(s);
       temp->count = 0;
       temp->gcount = 0;
+      temp->scount = 0;
       temp->loc[0] = c->loc[0];
       temp->loc[1] = c->loc[1];
       temp->loc[2] = c->loc[2];
@@ -191,46 +234,6 @@ int cell_link_gparts(struct cell *c, struct gpart *gparts) {
   return c->gcount;
 }
 
-/**
- * @brief Pack the data of the given cell and all it's sub-cells.
- *
- * @param c The #cell.
- * @param pc Pointer to an array of packed cells in which the
- *      cells will be packed.
- *
- * @return The number of packed cells.
- */
-int cell_pack(struct cell *c, struct pcell *pc) {
-
-#ifdef WITH_MPI
-
-  /* Start by packing the data of the current cell. */
-  pc->h_max = c->h_max;
-  pc->ti_end_min = c->ti_end_min;
-  pc->ti_end_max = c->ti_end_max;
-  pc->count = c->count;
-  pc->gcount = c->gcount;
-  c->tag = pc->tag = atomic_inc(&cell_next_tag) % cell_max_tag;
-
-  /* Fill in the progeny, depth-first recursion. */
-  int count = 1;
-  for (int k = 0; k < 8; k++)
-    if (c->progeny[k] != NULL) {
-      pc->progeny[k] = count;
-      count += cell_pack(c->progeny[k], &pc[count]);
-    } else
-      pc->progeny[k] = -1;
-
-  /* Return the number of packed cells used. */
-  c->pcell_size = count;
-  return count;
-
-#else
-  error("SWIFT was not compiled with MPI support.");
-  return 0;
-#endif
-}
-
 /**
  * @brief Pack the time information of the given cell and all it's sub-cells.
  *
@@ -421,6 +424,70 @@ int cell_glocktree(struct cell *c) {
   }
 }
 
+/**
+ * @brief Lock a cell for access to its array of #spart and hold its parents.
+ *
+ * @param c The #cell.
+ * @return 0 on success, 1 on failure
+ */
+int cell_slocktree(struct cell *c) {
+
+  TIMER_TIC
+
+  /* First of all, try to lock this cell. */
+  if (c->shold || lock_trylock(&c->slock) != 0) {
+    TIMER_TOC(timer_locktree);
+    return 1;
+  }
+
+  /* Did somebody hold this cell in the meantime? */
+  if (c->shold) {
+
+    /* Unlock this cell. */
+    if (lock_unlock(&c->slock) != 0) error("Failed to unlock cell.");
+
+    /* Admit defeat. */
+    TIMER_TOC(timer_locktree);
+    return 1;
+  }
+
+  /* Climb up the tree and lock/hold/unlock. */
+  struct cell *finger;
+  for (finger = c->parent; finger != NULL; finger = finger->parent) {
+
+    /* Lock this cell. */
+    if (lock_trylock(&finger->slock) != 0) break;
+
+    /* Increment the hold. */
+    atomic_inc(&finger->shold);
+
+    /* Unlock the cell. */
+    if (lock_unlock(&finger->slock) != 0) error("Failed to unlock cell.");
+  }
+
+  /* If we reached the top of the tree, we're done. */
+  if (finger == NULL) {
+    TIMER_TOC(timer_locktree);
+    return 0;
+  }
+
+  /* Otherwise, we hit a snag. */
+  else {
+
+    /* Undo the holds up to finger. */
+    for (struct cell *finger2 = c->parent; finger2 != finger;
+         finger2 = finger2->parent)
+      atomic_dec(&finger2->shold);
+
+    /* Unlock this cell. */
+    if (lock_unlock(&c->slock) != 0) error("Failed to unlock cell.");
+
+    /* Admit defeat. */
+    TIMER_TOC(timer_locktree);
+    return 1;
+  }
+}
+
 /**
  * @brief Unlock a cell's parents for access to #part array.
  *
@@ -459,6 +526,25 @@ void cell_gunlocktree(struct cell *c) {
   TIMER_TOC(timer_locktree);
 }
 
+/**
+ * @brief Unlock a cell's parents for access to #spart array.
+ *
+ * @param c The #cell.
+ */
+void cell_sunlocktree(struct cell *c) {
+
+  TIMER_TIC
+
+  /* First of all, try to unlock this cell. */
+  if (lock_unlock(&c->slock) != 0) error("Failed to unlock cell.");
+
+  /* Climb up the tree and unhold the parents. */
+  for (struct cell *finger = c->parent; finger != NULL; finger = finger->parent)
+    atomic_dec(&finger->shold);
+
+  TIMER_TOC(timer_locktree);
+}
+
 /**
  * @brief Sort the parts into eight bins along the given pivots.
  *
diff --git a/src/cell.h b/src/cell.h
index 984ef4bc20cf07285b136461815cd0851c12291a..bda0c218975c4b7f534fc50338bfdd2997afc6be 100644
--- a/src/cell.h
+++ b/src/cell.h
@@ -76,7 +76,7 @@ struct pcell {
   int ti_end_min, ti_end_max;
 
   /* Number of particles in this cell. */
-  int count, gcount;
+  int count, gcount, scount;
 
   /* tag used for MPI communication. */
   int tag;
@@ -117,6 +117,9 @@ struct cell {
   /*! Pointer to the #gpart data. */
   struct gpart *gparts;
 
+  /*! Pointer to the #spart data. */
+  struct gpart *sparts;
+
   /*! Pointer for the sorted indices. */
   struct entry *sort;
 
@@ -229,6 +232,9 @@ struct cell {
   /*! Nr of #gpart in this cell. */
   int gcount;
 
+  /*! Nr of #spart in this cell. */
+  int scount;
+
   /*! The size of the sort array */
   int sortsize;
 
@@ -241,6 +247,9 @@ struct cell {
   /*! Spin lock for various uses (#gpart case). */
   swift_lock_type glock;
 
+  /*! Spin lock for various uses (#spart case). */
+  swift_lock_type slock;
+
   /*! ID of the previous owner, e.g. runner. */
   int owner;
 
@@ -250,6 +259,9 @@ struct cell {
   /*! Number of #gpart updated in this cell. */
   int g_updated;
 
+  /*! Number of #spart updated in this cell. */
+  int s_updated;
+
   /*! ID of the node this cell lives on. */
   int nodeID;
 
@@ -259,6 +271,9 @@ struct cell {
   /*! Is the #gpart data of this cell being used in a sub-cell? */
   int ghold;
 
+  /*! Is the #spart data of this cell being used in a sub-cell? */
+  int shold;
+
   /*! Number of tasks that are associated with this cell. */
   short int nr_tasks;
 
@@ -285,6 +300,8 @@ int cell_locktree(struct cell *c);
 void cell_unlocktree(struct cell *c);
 int cell_glocktree(struct cell *c);
 void cell_gunlocktree(struct cell *c);
+int cell_slocktree(struct cell *c);
+void cell_sunlocktree(struct cell *c);
 int cell_pack(struct cell *c, struct pcell *pc);
 int cell_unpack(struct pcell *pc, struct cell *c, struct space *s);
 int cell_pack_ti_ends(struct cell *c, int *ti_ends);