#include <mono/metadata/threadpool.h>
#include <mono/metadata/threadpool-internals.h>
#include <mono/metadata/threads-types.h>
+#include <mono/metadata/sgen-conf.h>
#include <mono/utils/mono-logger-internal.h>
#include <mono/metadata/gc-internal.h>
#include <mono/metadata/marshal.h> /* for mono_delegate_free_ftnptr () */
gpointer *entries;
entries = mono_gc_alloc_fixed (sizeof (gpointer) * new_size, make_root_descr_all_refs (new_size, handles->type == HANDLE_PINNED));
- mono_gc_memmove (entries, handles->entries, sizeof (gpointer) * handles->size);
+ mono_gc_memmove_aligned (entries, handles->entries, sizeof (gpointer) * handles->size);
mono_gc_free_fixed (handles->entries);
handles->entries = entries;
static guint32
finalizer_thread (gpointer unused)
{
+ gboolean wait = TRUE;
+
while (!finished) {
/* Wait to be notified that there's at least one
* finaliser to run
g_assert (mono_domain_get () == mono_get_root_domain ());
+ if (wait) {
/* An alertable wait is required so this thread can be suspended on windows */
#ifdef MONO_HAS_SEMAPHORES
- MONO_SEM_WAIT_ALERTABLE (&finalizer_sem, TRUE);
+ MONO_SEM_WAIT_ALERTABLE (&finalizer_sem, TRUE);
#else
- WaitForSingleObjectEx (finalizer_event, INFINITE, TRUE);
+ WaitForSingleObjectEx (finalizer_event, INFINITE, TRUE);
#endif
+ }
+ wait = TRUE;
mono_threads_perform_thread_dump ();
reference_queue_proccess_all ();
- SetEvent (pending_done_event);
+#ifdef MONO_HAS_SEMAPHORES
+ /* Avoid posting the pending done event until there are pending finalizers */
+ if (MONO_SEM_TIMEDWAIT (&finalizer_sem, 0) == 0)
+ /* Don't wait again at the start of the loop */
+ wait = FALSE;
+ else
+ SetEvent (pending_done_event);
+#else
+ SetEvent (pending_done_event);
+#endif
}
SetEvent (shutdown_event);
mono_counters_register ("Created object count", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &mono_stats.new_object_count);
mono_counters_register ("Minor GC collections", MONO_COUNTER_GC | MONO_COUNTER_INT, &gc_stats.minor_gc_count);
mono_counters_register ("Major GC collections", MONO_COUNTER_GC | MONO_COUNTER_INT, &gc_stats.major_gc_count);
- mono_counters_register ("Minor GC time", MONO_COUNTER_GC | MONO_COUNTER_TIME_INTERVAL, &gc_stats.minor_gc_time_usecs);
- mono_counters_register ("Major GC time", MONO_COUNTER_GC | MONO_COUNTER_TIME_INTERVAL, &gc_stats.major_gc_time_usecs);
+ mono_counters_register ("Minor GC time", MONO_COUNTER_GC | MONO_COUNTER_LONG | MONO_COUNTER_TIME, &gc_stats.minor_gc_time_usecs);
+ mono_counters_register ("Major GC time", MONO_COUNTER_GC | MONO_COUNTER_LONG | MONO_COUNTER_TIME, &gc_stats.major_gc_time_usecs);
+#ifdef HEAVY_STATISTICS
+ mono_counters_register ("Gray Queue alloc section", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &gc_stats.gray_queue_section_alloc);
+ mono_counters_register ("Gray Queue free section", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &gc_stats.gray_queue_section_free);
+ mono_counters_register ("Gray Queue enqueue fast path", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &gc_stats.gray_queue_enqueue_fast_path);
+ mono_counters_register ("Gray Queue dequeue fast path", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &gc_stats.gray_queue_dequeue_fast_path);
+ mono_counters_register ("Gray Queue enqueue slow path", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &gc_stats.gray_queue_enqueue_slow_path);
+ mono_counters_register ("Gray Queue dequeue slow path", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &gc_stats.gray_queue_dequeue_slow_path);
+#endif
mono_gc_base_init ();
ResetEvent (shutdown_event);
finished = TRUE;
if (mono_thread_internal_current () != gc_thread) {
+ gboolean timed_out = FALSE;
+
mono_gc_finalize_notify ();
/* Finishing the finalizer thread, so wait a little bit... */
/* MS seems to wait for about 2 seconds */
* state the finalizer thread depends on will vanish.
*/
g_warning ("Shutting down finalizer thread timed out.");
- } else {
- /*
- * FIXME: On unix, when the above wait returns, the thread
- * might still be running io-layer code, or pthreads code.
- */
- Sleep (100);
+ timed_out = TRUE;
}
- } else {
+ }
+
+ if (!timed_out) {
int ret;
/* Wait for the thread to actually exit */
* Returns true if passing was successful
*/
gboolean
-mono_gc_parse_environment_string_extract_number (const char *str, glong *out)
+mono_gc_parse_environment_string_extract_number (const char *str, size_t *out)
{
char *endptr;
int len = strlen (str), shift = 0;
- glong val;
+ size_t val;
gboolean is_suffix = FALSE;
char suffix;
return FALSE;
if (is_suffix) {
- gulong unshifted;
+ size_t unshifted;
if (val < 0) /* negative numbers cannot be suffixed */
return FALSE;
if (*(endptr + 1)) /* Invalid string. */
return FALSE;
- unshifted = (gulong)val;
+ unshifted = (size_t)val;
val <<= shift;
if (val < 0) /* overflow */
return FALSE;
- if (((gulong)val >> shift) != unshifted) /* value too large */
+ if (((size_t)val >> shift) != unshifted) /* value too large */
return FALSE;
}