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();