diff --git a/src/gc.c b/src/gc.c
index 40103f81027835c9a99e67f3563f327532c6f10a..0526b40304a9773a4b1a6cd933d7dae918ee6b5a 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -4580,6 +4580,8 @@ PMOD_EXPORT TYPE_FIELD real_visit_svalues (struct svalue *s, size_t num,
 
 #define MC_WQ_START_SIZE 1024
 
+static IMUTEX_T mc_mutex;
+
 PMOD_EXPORT int mc_pass;
 PMOD_EXPORT size_t mc_counted_bytes;
 
@@ -4691,6 +4693,18 @@ struct mc_marker
 
 PTR_HASH_ALLOC_FILL_PAGES (mc_marker, 2)
 
+static void start_mc(void)
+{
+  LOCK_IMUTEX(&mc_mutex);
+  init_mc_marker_hash();
+}
+
+static void stop_mc(void)
+{
+  exit_mc_marker_hash();
+  UNLOCK_IMUTEX(&mc_mutex);
+}
+
 static struct mc_marker *my_make_mc_marker (void *thing,
 					    visit_thing_fn *visit_fn,
 					    void *extra)
@@ -5622,7 +5636,7 @@ void f_count_memory (INT32 args)
       Pike_sp[-args].u.integer;
   }
 
-  init_mc_marker_hash();
+  start_mc();
 
   if (TYPEOF(pike_cycle_depth_str) == PIKE_T_FREE) {
     SET_SVAL_TYPE(pike_cycle_depth_str, T_STRING);
@@ -5632,7 +5646,7 @@ void f_count_memory (INT32 args)
   assert (mc_work_queue == NULL);
   mc_work_queue = malloc (MC_WQ_START_SIZE * sizeof (mc_work_queue[0]));
   if (!mc_work_queue) {
-    exit_mc_marker_hash();
+    stop_mc();
     SIMPLE_OUT_OF_MEMORY_ERROR ("Pike.count_memory",
 				MC_WQ_START_SIZE * sizeof (mc_work_queue[0]));
   }
@@ -5657,9 +5671,9 @@ void f_count_memory (INT32 args)
 	continue;
 
       else if (!REFCOUNTED_TYPE(TYPEOF(*s))) {
-	exit_mc_marker_hash();
 	free (mc_work_queue + 1);
 	mc_work_queue = NULL;
+	stop_mc();
 	SIMPLE_ARG_TYPE_ERROR (
 	  "count_memory", i + args + 1,
 	  "array|multiset|mapping|object|program|string|type|int");
@@ -5669,9 +5683,9 @@ void f_count_memory (INT32 args)
 	if (TYPEOF(*s) == T_FUNCTION) {
 	  struct svalue s2;
 	  if (!(s2.u.program = program_from_function (s))) {
-	    exit_mc_marker_hash();
 	    free (mc_work_queue + 1);
 	    mc_work_queue = NULL;
+	    stop_mc();
 	    SIMPLE_ARG_TYPE_ERROR (
 	      "count_memory", i + args + 1,
 	      "array|multiset|mapping|object|program|string|type|int");
@@ -5693,9 +5707,9 @@ void f_count_memory (INT32 args)
 	  if (!mc_block_pike_cycle_depth && TYPEOF(*s) == T_OBJECT) {
 	    int cycle_depth = mc_cycle_depth_from_obj (s->u.object);
 	    if (TYPEOF(throw_value) != PIKE_T_FREE) {
-	      exit_mc_marker_hash();
 	      free (mc_work_queue + 1);
 	      mc_work_queue = NULL;
+	      stop_mc();
 	      throw_severity = THROW_ERROR;
 	      pike_throw();
 	    }
@@ -5822,9 +5836,9 @@ void f_count_memory (INT32 args)
       }
 
       if (TYPEOF(throw_value) != PIKE_T_FREE) {
-	exit_mc_marker_hash();
 	free (mc_work_queue + 1);
 	mc_work_queue = NULL;
+	stop_mc();
 	throw_severity = THROW_ERROR;
 	pike_throw();
       }
@@ -6069,11 +6083,11 @@ void f_count_memory (INT32 args)
 	remove_mc_marker (mc_marker_hash_table[e]->thing);
   }
 #endif
-  exit_mc_marker_hash();
 
   assert (mc_wq_used == 1);
   free (mc_work_queue + 1);
   mc_work_queue = NULL;
+  stop_mc();
 
   pop_n_elems (args);
   push_ulongest (return_count ? count_internal : mc_counted_bytes);
@@ -6178,7 +6192,7 @@ void f_identify_cycle(INT32 args)
     SET_SVAL_TYPE(*s, T_OBJECT);
   }
 
-  init_mc_marker_hash();
+  start_mc();
 
   if (TYPEOF(pike_cycle_depth_str) == PIKE_T_FREE) {
     SET_SVAL_TYPE(pike_cycle_depth_str, T_STRING);
@@ -6188,7 +6202,7 @@ void f_identify_cycle(INT32 args)
   assert (mc_work_queue == NULL);
   mc_work_queue = malloc (MC_WQ_START_SIZE * sizeof (mc_work_queue[0]));
   if (!mc_work_queue) {
-    exit_mc_marker_hash();
+    stop_mc();
     SIMPLE_OUT_OF_MEMORY_ERROR ("Pike.count_memory",
 				MC_WQ_START_SIZE * sizeof (mc_work_queue[0]));
   }
@@ -6229,8 +6243,9 @@ void f_identify_cycle(INT32 args)
   mc_ref_from = (void *) (ptrdiff_t) -1;
 #endif
 
-  exit_mc_marker_hash();
-  free (mc_work_queue + 1);
+  /* NB: 1-based indexing in mc_work_queue. */
+  mc_work_queue++;
+  free(mc_work_queue);
   mc_work_queue = NULL;
 
   visit_enter = NULL;
@@ -6257,6 +6272,8 @@ void f_identify_cycle(INT32 args)
 
   free_mapping(identify_loop_reverse);
 
+  stop_mc();
+
   if (!k) {
     push_undefined();
   } else {
@@ -6267,3 +6284,13 @@ void f_identify_cycle(INT32 args)
     f_reverse(1);
   }
 }
+
+void init_mc(void)
+{
+  init_interleave_mutex(&mc_mutex);
+}
+
+void exit_mc(void)
+{
+  exit_interleave_mutex(&mc_mutex);
+}
diff --git a/src/gc.h b/src/gc.h
index 2e3ef562b1c23b7831e27473433dbcd5129d2944..5009affbad3b4215784624fcb33d8711dc491f7d 100644
--- a/src/gc.h
+++ b/src/gc.h
@@ -753,4 +753,7 @@ PMOD_EXPORT extern int mc_pass;
 PMOD_EXPORT extern size_t mc_counted_bytes;
 PMOD_EXPORT int mc_count_bytes (void *thing);
 
+void init_mc(void);
+void exit_mc(void);
+
 #endif
diff --git a/src/module.c b/src/module.c
index d5f3a0dc3e22fe87a4f27caea53547414bdbc7bf..6bf276f96bbef701db58c5832396c3393ad4f290 100644
--- a/src/module.c
+++ b/src/module.c
@@ -70,6 +70,9 @@ static void init_builtin_modules(void)
 
   init_cpp();
 
+  TRACE((stderr, "Init memory counter...\n"));
+  init_mc();
+
   TRACE((stderr, "Init backend...\n"));
 
   init_backend();
@@ -145,6 +148,7 @@ static void exit_builtin_modules(void)
   cleanup_compiler();
   cleanup_error();
   exit_backend();
+  exit_mc();
   cleanup_gc();
   cleanup_pike_types();