diff --git a/src/threadpool.c b/src/threadpool.c
index f6b6380f05a80e30ea791840b7a7a50b189c35e2..524b28215d4687bb48e8f56210c8d9ecbe99ec7b 100644
--- a/src/threadpool.c
+++ b/src/threadpool.c
@@ -45,33 +45,28 @@
  */
 void threadpool_log(struct threadpool *tp, int tid, size_t chunk_size,
                     ticks tic, ticks toc) {
-
-  /* Only one cell logs at a time. */
-  pthread_mutex_lock(&tp->log_mutex);
+  struct mapper_log *log = &tp->logs[tid];
 
   /* Check if we need to re-allocate the log buffer. */
-  if (tp->log_count == tp->log_size) {
-    tp->log_size *= 2;
+  if (log->count == log->size) {
+    log->size *= 2;
     struct mapper_log_entry *new_log;
     if ((new_log = (struct mapper_log_entry *)malloc(
-             sizeof(struct mapper_log_entry) * tp->log_size)) == NULL)
+             sizeof(struct mapper_log_entry) * log->size)) == NULL)
       error("Failed to re-allocate mapper log.");
-    memcpy(new_log, tp->log, sizeof(struct mapper_log_entry) * tp->log_count);
-    free(tp->log);
-    tp->log = new_log;
+    memcpy(new_log, log->log, sizeof(struct mapper_log_entry) * log->count);
+    free(log->log);
+    log->log = new_log;
   }
 
   /* Store the new entry. */
-  struct mapper_log_entry *entry = &tp->log[tp->log_count];
+  struct mapper_log_entry *entry = &log->log[log->count];
   entry->tid = tid;
   entry->chunk_size = chunk_size;
   entry->tic = tic;
   entry->toc = toc;
   entry->map_function = tp->map_function;
-  tp->log_count++;
-
-  /* Release the logging mutex. */
-  pthread_mutex_unlock(&tp->log_mutex);
+  log->count++;
 }
 
 void threadpool_dump_log(struct threadpool *tp, const char *filename,
@@ -96,34 +91,39 @@ void threadpool_dump_log(struct threadpool *tp, const char *filename,
   fprintf(fd, "# {'num_threads': %i, 'cpufreq': %lli}\n", tp->num_threads,
           clocks_get_cpufreq());
 
-  /* Loop over the log entries and dump them. */
-  for (int i = 0; i < tp->log_count; i++) {
-
-    struct mapper_log_entry *entry = &tp->log[i];
-
-    /* Look for the function pointer in the buffer. */
-    int nid = 0;
-    while (nid < max_names && names[nid].map_function != entry->map_function)
-      nid++;
-
-    /* If the name was not found, make a new entry. */
-    if (nid == max_names) {
-      for (int j = 1; j < max_names; j++) names[j - 1] = names[j];
-      names[0].map_function = entry->map_function;
-      Dl_info dl_info;
-      dladdr(entry->map_function, &dl_info);
-      names[0].name = dl_info.dli_sname;
-      nid = 0;
+  /* Loop over the per-tid logs and dump them. */
+  for (int k = 0; k < tp->num_threads; k++) {
+    struct mapper_log *log = &tp->logs[k];
+
+    /* Loop over the log entries and dump them. */
+    for (int i = 0; i < log->count; i++) {
+
+      struct mapper_log_entry *entry = &log->log[i];
+
+      /* Look for the function pointer in the buffer. */
+      int nid = 0;
+      while (nid < max_names && names[nid].map_function != entry->map_function)
+        nid++;
+
+      /* If the name was not found, make a new entry. */
+      if (nid == max_names) {
+        for (int j = 1; j < max_names; j++) names[j - 1] = names[j];
+        names[0].map_function = entry->map_function;
+        Dl_info dl_info;
+        dladdr(entry->map_function, &dl_info);
+        names[0].name = dl_info.dli_sname;
+        nid = 0;
+      }
+
+      /* Log a line to the file. */
+      fprintf(fd, "%s %i %i %lli %lli\n", names[nid].name, entry->tid,
+              entry->chunk_size, entry->tic, entry->toc);
     }
 
-    /* Log a line to the file. */
-    fprintf(fd, "%s %i %i %lli %lli\n", names[nid].name, entry->tid,
-            entry->chunk_size, entry->tic, entry->toc);
+    /* Clear the log if requested. */
+    if (reset) log->count = 0;
   }
 
-  /* Clear the log if requested. */
-  if (reset) tp->log_count = 0;
-
   /* Close the file. */
   fclose(fd);
 }
@@ -214,13 +214,16 @@ void threadpool_init(struct threadpool *tp, int num_threads) {
   tp->map_function = NULL;
 
 #ifdef SWIFT_DEBUG_THREADPOOL
-  tp->log_size = threadpool_log_initial_size;
-  tp->log_count = 0;
-  if (pthread_mutex_init(&tp->log_mutex, NULL) != 0)
-    error("Failed to initialize log mutex.");
-  if ((tp->log = (struct mapper_log_entry *)malloc(
-           sizeof(struct mapper_log_entry) * tp->log_size)) == NULL)
-    error("Failed to allocate mapper log.");
+  if ((tp->logs = (struct mapper_log *)malloc(sizeof(struct mapper_log) *
+                                              num_threads)) == NULL)
+    error("Failed to allocate mapper logs.");
+  for (int k = 0; k < num_threads; k++) {
+    tp->logs[k].size = threadpool_log_initial_size;
+    tp->logs[k].count = 0;
+    if ((tp->logs[k].log = (struct mapper_log_entry *)malloc(
+             sizeof(struct mapper_log_entry) * tp->logs[k].size)) == NULL)
+      error("Failed to allocate mapper log.");
+  }
 #endif
 
   /* Allocate the threads. */
@@ -300,7 +303,9 @@ void threadpool_map(struct threadpool *tp, threadpool_map_function map_function,
  * @brief Re-sets the log for this #threadpool.
  */
 #ifdef SWIFT_DEBUG_THREADPOOL
-void threadpool_reset_log(struct threadpool *tp) { tp->log_count = 0; }
+void threadpool_reset_log(struct threadpool *tp) {
+  for (int k = 0; k < tp->num_threads; k++) tp->logs[k].count = 0;
+}
 #endif
 
 /**
@@ -309,6 +314,9 @@ void threadpool_reset_log(struct threadpool *tp) { tp->log_count = 0; }
 void threadpool_clean(struct threadpool *tp) {
   free(tp->threads);
 #ifdef SWIFT_DEBUG_THREADPOOL
-  free(tp->log);
+  for (int k = 0; k < tp->num_threads; k++) {
+    free(tp->logs[k].log);
+  }
+  free(tp->logs);
 #endif
 }
diff --git a/src/threadpool.h b/src/threadpool.h
index 9a4076d9ad844785d4fdfc5fa801b12fccd8ff56..e3bd6ba5bf5157f8e0a6a852849cc9f21400da7b 100644
--- a/src/threadpool.h
+++ b/src/threadpool.h
@@ -52,6 +52,17 @@ struct mapper_log_entry {
   ticks tic, toc;
 };
 
+struct mapper_log {
+  /* Log of threadpool mapper calls. */
+  struct mapper_log_entry *log;
+
+  /* Size of the allocated log. */
+  int size;
+
+  /* Number of entries in the log. */
+  int count;
+};
+
 /* Data of a threadpool. */
 struct threadpool {
 
@@ -75,17 +86,7 @@ struct threadpool {
   volatile int num_threads_waiting, num_threads_running;
 
 #ifdef SWIFT_DEBUG_THREADPOOL
-  /* Log of threadpool mapper calls. */
-  struct mapper_log_entry *log;
-
-  /* Size of the allocated log. */
-  int log_size;
-
-  /* Number of entries in the log. */
-  int log_count;
-
-  /* Mutex for log access/reallocation. */
-  pthread_mutex_t log_mutex;
+  struct mapper_log *logs;
 #endif
 };