diff --git a/src/memuse.c b/src/memuse.c
index ad7db5011fc86e3b33dbc896c8dc49f1f78334c8..aeff8ad59590a32a3cd0085f4761adee461ac4e2 100644
--- a/src/memuse.c
+++ b/src/memuse.c
@@ -101,6 +101,10 @@ static volatile size_t memuse_log_count = 0;
 static volatile size_t memuse_old_count = 0;
 static volatile size_t memuse_log_done = 0;
 
+/* Reallocation lock, we must wait for the reallocation to complete before
+ * dumping. */
+static swift_lock_type realloc_lock;
+
 /* Current sum of memory in use. Only used in dumping. */
 static size_t memuse_current = 0;
 
@@ -126,28 +130,44 @@ static void memuse_log_reallocate(size_t ind) {
              sizeof(struct memuse_log_entry) * MEMUSE_INITLOG)) == NULL)
       error("Failed to allocate memuse log.");
 
+    /* Initialize the lock, we need it next time. */
+    lock_init(&realloc_lock);
+
     /* Last action. */
     memuse_log_size = MEMUSE_INITLOG;
 
   } else {
-    struct memuse_log_entry *new_log;
-    if ((new_log = (struct memuse_log_entry *)malloc(
-             sizeof(struct memuse_log_entry) *
-             (memuse_log_size + MEMUSE_INITLOG))) == NULL)
-      error("Failed to re-allocate memuse log.");
-
-    /* Wait for all writes to the old buffer to complete. */
-    while (memuse_log_done < memuse_log_size)
-      ;
-
-    /* Copy to new buffer. */
-    memcpy(new_log, memuse_log,
-           sizeof(struct memuse_log_entry) * memuse_log_size);
-    free(memuse_log);
-    memuse_log = new_log;
-
-    /* Last action, releases waiting threads. */
-    atomic_add(&memuse_log_size, MEMUSE_INITLOG);
+
+    /* We need to lock this section so that any dumps wait for the updated
+     * memory, otherwise we could free the memory while the dump is underway. */
+    if (lock_lock(&realloc_lock) == 0) {
+
+      struct memuse_log_entry *new_log;
+      if ((new_log = (struct memuse_log_entry *)malloc(
+               sizeof(struct memuse_log_entry) *
+               (memuse_log_size + MEMUSE_INITLOG))) == NULL)
+        error("Failed to re-allocate memuse log.");
+
+      /* Wait for all writes to the old buffer to complete. */
+      while (memuse_log_done < memuse_log_size)
+        ;
+
+      /* Copy to new buffer. */
+      memcpy(new_log, memuse_log,
+             sizeof(struct memuse_log_entry) * memuse_log_size);
+
+      /* And carefully flip. */
+      struct memuse_log_entry *tmp = memuse_log;
+      memuse_log = new_log;
+      free(tmp);
+
+      /* Last action, releases waiting threads. */
+      atomic_add(&memuse_log_size, MEMUSE_INITLOG);
+
+      /* OK to dump now. */
+      if (lock_unlock(&realloc_lock) != 0)
+        message("Failed to unlock memuse reallocation lock");
+    }
   }
 }
 
@@ -204,201 +224,221 @@ void memuse_log_dump(const char *filename) {
   if (memuse_rnode_root_init) {
     memuse_rnode_root =
         (struct memuse_rnode *)calloc(1, sizeof(struct memuse_rnode));
+    memuse_rnode_root->value = -1;
     memuse_rnode_root_init = 0;
   }
 
-  /* Stop any new logs from being processed while we are dumping.
-   * Remember to not abort with error() in this section, that is recursive
-   * with the exit handler. */
-  size_t log_count = memuse_log_count;
-  size_t old_count = memuse_old_count;
-
-  /* Open the output file. */
-  FILE *fd;
-  if ((fd = fopen(filename, "w")) == NULL) {
-    message("Failed to create memuse log file '%s', logs not dumped.",
-            filename);
-    return;
-  }
+  /* Stop any reallocations while we are reading the memory. */
+  if (lock_lock(&realloc_lock) == 0) {
+
+    /* Stop any new logs from being processed while we are dumping.
+     * Remember to not abort with error() in this section, that is recursive
+     * with the exit handler. */
+    size_t log_count = memuse_log_count;
+    size_t old_count = memuse_old_count;
+
+    /* Open the output file. */
+    FILE *fd;
+    if ((fd = fopen(filename, "w")) == NULL) {
+      message("Failed to create memuse log file '%s', logs not dumped.",
+              filename);
+      return;
+    }
 
-  /* Write a header. */
-  fprintf(fd, "# dtic step label size sum\n");
+    /* Write a header. */
+    fprintf(fd, "# dtic step label size sum\n");
 
-  size_t memuse_maxmem = memuse_current;
-  for (size_t k = old_count; k < log_count; k++) {
+    size_t memuse_maxmem = memuse_current;
+    for (size_t k = old_count; k < log_count; k++) {
 
-    /* Check if this address has already been recorded. */
-    struct memuse_rnode *child = memuse_rnode_find_child(
-        memuse_rnode_root, 0, memuse_log[k].vptr, sizeof(uintptr_t));
+      /* Check if this address has already been recorded. */
+      struct memuse_rnode *child = memuse_rnode_find_child(
+          memuse_rnode_root, 0, memuse_log[k].vptr, sizeof(uintptr_t));
 
-    if (child != NULL && child->ptr != NULL) {
+      if (child != NULL && child->value != -1) {
 
-      /* Found the allocation, this should be the free. */
-      if (memuse_log[k].allocated) {
+        /* Found the allocation, this should be the free. */
+        if (memuse_log[k].allocated) {
 
-        /* Allocated twice, this is an error, but we cannot abort as that will
-         * attempt another memory dump, so just complain. */
+          /* Allocated twice, this is an error, but we cannot abort as that will
+           * attempt another memory dump, so just complain. */
 #if SWIFT_DEBUG_CHECKS
-        message("Allocated the same address twice (%s: %zd)",
-                memuse_log[k].label, memuse_log[k].size);
+          message("Allocated the same address twice (%s: %zd)",
+                  memuse_log[k].label, memuse_log[k].size);
 #endif
-        continue;
-      }
+          continue;
+        }
 
-      /* Free, update the size to remove the allocation. */
-      struct memuse_log_entry *oldlog = (struct memuse_log_entry *)child->ptr;
-      memuse_log[k].size = -oldlog->size;
+        /* Free, update the size to remove the allocation. */
+        int64_t allocindex = child->value;
+        child->value = -1;
+        memuse_log[k].size = -memuse_log[allocindex].size;
 
-      /* And deactivate this key. */
-      child->ptr = NULL;
+        /* And deactivate this key. */
+        memuse_log[allocindex].ptr = NULL;
 
-      /* And mark this as matched. */
-      memuse_log[k].active = 0;
-      oldlog->active = 0;
+        /* And mark this as matched. */
+        memuse_log[k].active = 0;
+        memuse_log[allocindex].active = 0;
 
-    } else if (child == NULL && memuse_log[k].allocated) {
+      } else if (child == NULL && memuse_log[k].allocated) {
 
-      /* Not found, so new allocation which we store the log against the
-       * address. */
-      memuse_rnode_insert_child(memuse_rnode_root, 0, memuse_log[k].vptr,
-                                sizeof(uintptr_t), &memuse_log[k]);
+        /* Not found, so new allocation which we store the log against the
+         * log index. */
+        memuse_rnode_insert_child(memuse_rnode_root, 0, memuse_log[k].vptr,
+                                  sizeof(uintptr_t), k);
 
-    } else if (child == NULL && !memuse_log[k].allocated) {
+      } else if (child == NULL && !memuse_log[k].allocated) {
 
-      /* Unmatched free, OK if NULL. */
+        /* Unmatched free, OK if NULL. */
 #if SWIFT_DEBUG_CHECKS
-      if (memuse_log[k].ptr != NULL) {
-        message("Unmatched non-NULL free: %s", memuse_log[k].label);
-      }
+        if (memuse_log[k].ptr != NULL) {
+          message("Unmatched non-NULL free: %s", memuse_log[k].label);
+        }
 #endif
-      continue;
-    } else if (memuse_log[k].allocated) {
+        continue;
+      } else if (memuse_log[k].allocated) {
 
-      /* Must be previously released allocation with same address, so we
-       * store. */
-      memuse_rnode_insert_child(memuse_rnode_root, 0, memuse_log[k].vptr,
-                                sizeof(uintptr_t), &memuse_log[k]);
+        /* Must be previously released allocation with same address, so we
+         * store the index. */
+        memuse_rnode_insert_child(memuse_rnode_root, 0, memuse_log[k].vptr,
+                                  sizeof(uintptr_t), k);
 
-    } else {
-      /* Should not happen ... */
-      message("weird memory log record for label '%s' skipped",
-              memuse_log[k].label);
-      continue;
-    }
+      } else {
+        /* Should not happen ... */
+        message("weird memory log record for label '%s' skipped",
+                memuse_log[k].label);
+        continue;
+      }
 
-    /* Keep maximum and rolling sum. */
-    memuse_current += memuse_log[k].size;
-    if (memuse_current > memuse_maxmem) memuse_maxmem = memuse_current;
+      /* Keep maximum and rolling sum. */
+      memuse_current += memuse_log[k].size;
+      if (memuse_current > memuse_maxmem) memuse_maxmem = memuse_current;
 
-    /* And output. */
-    fprintf(fd, "%lld %d %s %zd %zd\n", memuse_log[k].dtic, memuse_log[k].step,
-            memuse_log[k].label, memuse_log[k].size, memuse_current);
-  }
+      /* And output. */
+      fprintf(fd, "%lld %d %s %zd %zd\n", memuse_log[k].dtic,
+              memuse_log[k].step, memuse_log[k].label, memuse_log[k].size,
+              memuse_current);
+    }
 
 #ifdef MEMUSE_RNODE_DUMP
-  /* Debug dump of tree. */
-  // memuse_rnode_dump(0, memuse_rnode_root, 0);
+    /* Debug dump of tree. */
+    // memuse_rnode_dump(0, memuse_rnode_root, 0);
 #endif
 
-  /* Now we find all the still active nodes and gather their sizes against the
-   * labels. */
-  struct memuse_rnode *activernodes =
-      (struct memuse_rnode *)calloc(1, sizeof(struct memuse_rnode));
-  size_t newcount = 0;
-  struct memuse_rnode *labellednodes =
-      (struct memuse_rnode *)calloc(1, sizeof(struct memuse_rnode));
-  size_t *lindices = (size_t *)calloc(log_count, sizeof(size_t));
-  size_t lcount = 0;
-  for (size_t k = 0; k < log_count; k++) {
-
-    /* Only allocations are stored also is it active? */
-    if (memuse_log[k].allocated && memuse_log[k].active) {
-
-      /* Look for this label in our tree. */
-      struct memuse_rnode *labelchild = memuse_rnode_find_child(
-          labellednodes, 0, (uint8_t *)memuse_log[k].label,
-          strlen(memuse_log[k].label));
-      struct memuse_labelled_item *item = NULL;
-      if (labelchild == NULL || labelchild->ptr == NULL) {
-
-        /* New, so create an instance to keep the count. */
-        item = (struct memuse_labelled_item *)calloc(
-            1, sizeof(struct memuse_labelled_item));
-        item->sum = 0;
-        item->count = 0;
-        memuse_rnode_insert_child(labellednodes, 0,
-                                  (uint8_t *)memuse_log[k].label,
-                                  strlen(memuse_log[k].label), item);
-
-        /* Keep for indexing next time. */
-        lindices[lcount] = newcount;
-        lcount++;
-      } else {
-        item = (struct memuse_labelled_item *)labelchild->ptr;
+    /* Now we find all the still active nodes and gather their sizes against the
+     * labels. */
+    struct memuse_rnode *activernodes =
+        (struct memuse_rnode *)calloc(1, sizeof(struct memuse_rnode));
+    activernodes->value = -1;
+    size_t newcount = 0;
+    struct memuse_rnode *labelledrnodes =
+        (struct memuse_rnode *)calloc(1, sizeof(struct memuse_rnode));
+    labelledrnodes->value = -1;
+    size_t *lindices = (size_t *)calloc(log_count, sizeof(size_t));
+    size_t lcount = 0;
+    for (size_t k = 0; k < log_count; k++) {
+
+      /* Only allocations are stored also is it active? */
+      if (memuse_log[k].allocated && memuse_log[k].active) {
+
+        /* Look for this label in our tree. */
+        struct memuse_rnode *labelchild = memuse_rnode_find_child(
+            labelledrnodes, 0, (uint8_t *)memuse_log[k].label,
+            strlen(memuse_log[k].label));
+        struct memuse_labelled_item *item = NULL;
+        if (labelchild == NULL || labelchild->value == -1) {
+
+          /* New, so create an instance to keep the count. */
+          item = (struct memuse_labelled_item *)calloc(
+              1, sizeof(struct memuse_labelled_item));
+          item->sum = 0;
+          item->count = 0;
+          memuse_rnode_insert_child(labelledrnodes, 0,
+                                    (uint8_t *)memuse_log[k].label,
+                                    strlen(memuse_log[k].label), (int64_t)item);
+
+          /* Keep for indexing next time. */
+          lindices[lcount] = newcount;
+          lcount++;
+        } else {
+          item = (struct memuse_labelled_item *)labelchild->value;
+        }
+
+        /* And increment sum. */
+        item->sum += memuse_log[k].size;
+        item->count++;
+
+        /* Keep index in new log entry tree. Move to head. */
+        memcpy(&memuse_log[newcount], &memuse_log[k],
+               sizeof(struct memuse_log_entry));
+        memuse_rnode_insert_child(activernodes, 0, memuse_log[newcount].vptr,
+                                  sizeof(uintptr_t), newcount);
+        newcount++;
       }
+    }
 
-      /* And increment sum. */
-      item->sum += memuse_log[k].size;
-      item->count++;
+    /* And move all active logs to a clean new tree for next time. */
+    memuse_log_count = newcount;
+    memuse_old_count = newcount;
+    memuse_rnode_cleanup(memuse_rnode_root);
+    free(memuse_rnode_root);
+    memuse_rnode_root = activernodes;
 
-      /* Keep this in new log entry tree. Move to head. */
-      memcpy(&memuse_log[newcount], &memuse_log[k],
-             sizeof(struct memuse_log_entry));
-      memuse_rnode_insert_child(activernodes, 0, memuse_log[newcount].vptr,
-                                sizeof(uintptr_t), &memuse_log[newcount]);
-      newcount++;
+    /* Now dump the labelled counts. */
+    fprintf(fd, "# Memory use by label:\n");
+    fprintf(fd, "##  %30s %16s %16s\n", "label", "MB", "numactive");
+    fprintf(fd, "##\n");
+
+    size_t total_mem = 0;
+    for (size_t k = 0; k < lcount; k++) {
+      size_t ind = lindices[k];
+
+      /* Find this entry. */
+      struct memuse_rnode *labelchild = memuse_rnode_find_child(
+          labelledrnodes, 0, (uint8_t *)memuse_log[ind].label,
+          strlen(memuse_log[ind].label));
+      struct memuse_labelled_item *item =
+          (struct memuse_labelled_item *)labelchild->value;
+      fprintf(fd, "## %30s %16.3f %16zd\n", memuse_log[ind].label,
+              item->sum / MEGABYTE, item->count);
+      total_mem += item->sum;
+
+      /* Don't need this again. */
+      free(item);
     }
-  }
 
-  /* And move all active logs to a clean new tree for next time. */
-  memuse_log_count = newcount;
-  memuse_old_count = newcount;
-  memuse_rnode_cleanup(memuse_rnode_root);
-  free(memuse_rnode_root);
-  memuse_rnode_root = activernodes;
-
-  /* Now dump the labelled counts. */
-  fprintf(fd, "# Memory use by label:\n");
-  fprintf(fd, "##  %30s %16s %16s\n", "label", "MB", "numactive");
-  fprintf(fd, "##\n");
-
-  size_t total_mem = 0;
-  for (size_t k = 0; k < lcount; k++) {
-    size_t ind = lindices[k];
-
-    /* Find this entry. */
-    struct memuse_rnode *labelchild = memuse_rnode_find_child(
-        labellednodes, 0, (uint8_t *)memuse_log[ind].label,
-        strlen(memuse_log[ind].label));
-    struct memuse_labelled_item *item =
-        (struct memuse_labelled_item *)labelchild->ptr;
-    fprintf(fd, "## %30s %16.3f %16zd\n", memuse_log[ind].label,
-            item->sum / MEGABYTE, item->count);
-    total_mem += item->sum;
-
-    /* Don't need this again. */
-    free(item);
+    /* Add the memory consumption of the mem logger itself */
+    fprintf(fd, "## %30s %16.3f %16zd\n", "memuse_log",
+            memuse_log_size * sizeof(struct memuse_log_entry) / MEGABYTE, 1L);
+    total_mem += memuse_log_size * sizeof(struct memuse_log_entry);
+
+    fprintf(fd, "##\n");
+    fprintf(fd, "# Total memory still in use : %.3f (MB)\n",
+            total_mem / MEGABYTE);
+    fprintf(fd, "# Peak memory usage         : %.3f (MB)\n",
+            memuse_maxmem / MEGABYTE);
+    fprintf(fd, "#\n");
+    fprintf(fd, "# Memory use by process (all/system): %s\n",
+            memuse_process(1));
+    fprintf(fd, "# cpufreq: %lld\n", clocks_get_cpufreq());
+
+    /* Clean up tree. */
+    memuse_rnode_cleanup(labelledrnodes);
+    free(labelledrnodes);
+    free(lindices);
+
+    /* Close the file. */
+    fflush(fd);
+    fclose(fd);
+
+    // message("took %.3f %s.", clocks_from_ticks(getticks() - tic),
+    //        clocks_getunit());
+
+    /* All accesses of the logs done, so we can release the lock. */
+    if (lock_unlock(&realloc_lock) != 0)
+      message("Failed to unlock memuse reallocation lock");
   }
-  fprintf(fd, "##\n");
-  fprintf(fd, "# Total memory still in use : %.3f (MB)\n",
-          total_mem / MEGABYTE);
-  fprintf(fd, "# Peak memory usage         : %.3f (MB)\n",
-          memuse_maxmem / MEGABYTE);
-  fprintf(fd, "#\n");
-  fprintf(fd, "# Memory use by process (all/system): %s\n", memuse_process(1));
-  fprintf(fd, "# cpufreq: %lld\n", clocks_get_cpufreq());
-
-  /* Clean up tree. */
-  memuse_rnode_cleanup(labellednodes);
-  free(labellednodes);
-  free(lindices);
-
-  /* Close the file. */
-  fflush(fd);
-  fclose(fd);
-
-  // message("took %.3f %s.", clocks_from_ticks(getticks() - tic),
-  //        clocks_getunit());
 }
 
 /**
diff --git a/src/memuse_rnodes.c b/src/memuse_rnodes.c
index 55798c619aab5637cf445fd1dba62a272624983b..bf73ba26079bfe586f5bf85d6a4862f868dcd6c1 100644
--- a/src/memuse_rnodes.c
+++ b/src/memuse_rnodes.c
@@ -147,10 +147,12 @@ static struct memuse_rnode *memuse_rnode_lookup(const struct memuse_rnode *node,
  * @param depth the depth of the parent node.
  * @param key the full key of the eventual leaf node.
  * @param keylen the numbers of bytes in the full key.
- * @param value pointer that will be stored as the value of the leaf node.
+ * @param value a value to be stored at the leaf node. Note -1 is used as the
+ *        NULL value, so storing signed values needs care and we limit the
+ *        range of unsigned values.
  */
 void memuse_rnode_insert_child(struct memuse_rnode *node, uint8_t depth,
-                               uint8_t *key, uint8_t keylen, void *value) {
+                               uint8_t *key, uint8_t keylen, int64_t value) {
 
   /* Check if keypart this already exists at this level and add new child if
    * not. */
@@ -158,6 +160,7 @@ void memuse_rnode_insert_child(struct memuse_rnode *node, uint8_t depth,
   struct memuse_rnode *child = memuse_rnode_lookup(node, keypart);
   if (child == NULL) {
     child = (struct memuse_rnode *)calloc(1, sizeof(struct memuse_rnode));
+    child->value = -1;
     child->keypart = keypart;
     memuse_rnode_add_child(node, child);
   }
@@ -171,7 +174,7 @@ void memuse_rnode_insert_child(struct memuse_rnode *node, uint8_t depth,
     if (child->ptr != NULL)
       message("Overwriting rnode value: %p with %p", child->ptr, value);
 #endif
-    child->ptr = value;
+    child->value = value;
     return;
   }
 
@@ -258,9 +261,9 @@ void memuse_rnode_dump(int depth, struct memuse_rnode *node, int full) {
   //    }
   //}
 
-  if (node->ptr != NULL || full) {
-    printf("dump @ depth: %d keypart: %d key: %p value: %p\n", depth,
-           node->keypart, keyparts.ptr, node->ptr);
+  if ((node->value != -1) || full) {
+    printf("dump @ depth: %d keypart: %d key: %p value: %" PRId64 "\n", depth,
+           node->keypart, keyparts.ptr, node->value);
   }
 
   /* Recurse to all children. */
diff --git a/src/memuse_rnodes.h b/src/memuse_rnodes.h
index 41f24a98ad60396aec06d3170d478834428007ce..e38ae65a127a70c6b2f78f1e68826d8b667d8cf2 100644
--- a/src/memuse_rnodes.h
+++ b/src/memuse_rnodes.h
@@ -23,6 +23,7 @@
 #include "../config.h"
 
 /* Includes. */
+#include <inttypes.h>
 #include <stdlib.h>
 
 /* A radix node, this has a single byte key and a pointer to some related
@@ -32,8 +33,8 @@ struct memuse_rnode {
   /* Byte key of this node. */
   uint8_t keypart;
 
-  /* Value of this node, if set. */
-  void *ptr;
+  /* Value of this node, if set. Note we keep -1 for NULL. */
+  int64_t value;
 
   /* Sorted pointers to children of this node. */
   struct memuse_rnode **children;
@@ -42,7 +43,7 @@ struct memuse_rnode {
 
 void memuse_rnode_dump(int depth, struct memuse_rnode *node, int full);
 void memuse_rnode_insert_child(struct memuse_rnode *node, uint8_t depth,
-                               uint8_t *key, uint8_t keylen, void *value);
+                               uint8_t *key, uint8_t keylen, int64_t value);
 struct memuse_rnode *memuse_rnode_find_child(struct memuse_rnode *node,
                                              uint8_t depth, uint8_t *key,
                                              uint8_t keylen);