X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fgc.c;h=921898a444205a0219307176555414c0c18597fc;hb=e666a5ee28575d714d29ec8f9fb009e383f73acf;hp=19a81a82b55d44823a7d3b10d0c64a94c1f5b7fc;hpb=436328d91d590e68ccc87127920ba7cc6262fa0c;p=mono.git diff --git a/mono/metadata/gc.c b/mono/metadata/gc.c index 19a81a82b55..921898a4442 100644 --- a/mono/metadata/gc.c +++ b/mono/metadata/gc.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include /* for mono_delegate_free_ftnptr () */ @@ -58,10 +59,10 @@ static gboolean gc_disabled = FALSE; static gboolean finalizing_root_domain = FALSE; -#define mono_finalizer_lock() EnterCriticalSection (&finalizer_mutex) -#define mono_finalizer_unlock() LeaveCriticalSection (&finalizer_mutex) -static CRITICAL_SECTION finalizer_mutex; -static CRITICAL_SECTION reference_queue_mutex; +#define mono_finalizer_lock() mono_mutex_lock (&finalizer_mutex) +#define mono_finalizer_unlock() mono_mutex_unlock (&finalizer_mutex) +static mono_mutex_t finalizer_mutex; +static mono_mutex_t reference_queue_mutex; static GSList *domains_to_finalize= NULL; static MonoMList *threads_to_finalize = NULL; @@ -501,10 +502,10 @@ ves_icall_System_GC_get_ephemeron_tombstone (void) return mono_domain_get ()->ephemeron_tombstone; } -#define mono_allocator_lock() EnterCriticalSection (&allocator_section) -#define mono_allocator_unlock() LeaveCriticalSection (&allocator_section) -static CRITICAL_SECTION allocator_section; -static CRITICAL_SECTION handle_section; +#define mono_allocator_lock() mono_mutex_lock (&allocator_section) +#define mono_allocator_unlock() mono_mutex_unlock (&allocator_section) +static mono_mutex_t allocator_section; +static mono_mutex_t handle_section; typedef enum { HANDLE_WEAK, @@ -604,8 +605,8 @@ static HandleData gc_handles [] = { {NULL, NULL, 0, HANDLE_PINNED, 0} }; -#define lock_handles(handles) EnterCriticalSection (&handle_section) -#define unlock_handles(handles) LeaveCriticalSection (&handle_section) +#define lock_handles(handles) mono_mutex_lock (&handle_section) +#define unlock_handles(handles) mono_mutex_unlock (&handle_section) static int find_first_unset (guint32 bitmap) @@ -1061,6 +1062,8 @@ finalize_domain_objects (DomainFinalizationReq *req) static guint32 finalizer_thread (gpointer unused) { + gboolean wait = TRUE; + while (!finished) { /* Wait to be notified that there's at least one * finaliser to run @@ -1068,12 +1071,15 @@ finalizer_thread (gpointer unused) 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 (); @@ -1105,7 +1111,16 @@ finalizer_thread (gpointer unused) 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); @@ -1125,20 +1140,20 @@ mono_gc_init_finalizer_thread (void) void mono_gc_init (void) { - InitializeCriticalSection (&handle_section); - InitializeCriticalSection (&allocator_section); + mono_mutex_init_recursive (&handle_section); + mono_mutex_init_recursive (&allocator_section); - InitializeCriticalSection (&finalizer_mutex); - InitializeCriticalSection (&reference_queue_mutex); + mono_mutex_init_recursive (&finalizer_mutex); + mono_mutex_init_recursive (&reference_queue_mutex); MONO_GC_REGISTER_ROOT_FIXED (gc_handles [HANDLE_NORMAL].entries); MONO_GC_REGISTER_ROOT_FIXED (gc_handles [HANDLE_PINNED].entries); - mono_counters_register ("Created object count", MONO_COUNTER_GC | MONO_COUNTER_LONG, &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_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); + mono_counters_register ("Minor GC collections", MONO_COUNTER_GC | MONO_COUNTER_UINT, &gc_stats.minor_gc_count); + mono_counters_register ("Major GC collections", MONO_COUNTER_GC | MONO_COUNTER_UINT, &gc_stats.major_gc_count); + mono_counters_register ("Minor GC time", MONO_COUNTER_GC | MONO_COUNTER_ULONG | MONO_COUNTER_TIME, &gc_stats.minor_gc_time); + mono_counters_register ("Major GC time", MONO_COUNTER_GC | MONO_COUNTER_ULONG | MONO_COUNTER_TIME, &gc_stats.major_gc_time); + mono_counters_register ("Major GC time concurrent", MONO_COUNTER_GC | MONO_COUNTER_ULONG | MONO_COUNTER_TIME, &gc_stats.major_gc_time_concurrent); mono_gc_base_init (); @@ -1173,6 +1188,8 @@ mono_gc_cleanup (void) 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 */ @@ -1195,21 +1212,18 @@ mono_gc_cleanup (void) * 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 */ ret = WaitForSingleObjectEx (gc_thread->handle, INFINITE, TRUE); g_assert (ret == WAIT_OBJECT_0); - mono_thread_join ((gpointer)gc_thread->tid); + mono_thread_join (MONO_UINT_TO_NATIVE_THREAD_ID (gc_thread->tid)); } } gc_thread = NULL; @@ -1220,10 +1234,10 @@ mono_gc_cleanup (void) mono_reference_queue_cleanup (); - DeleteCriticalSection (&handle_section); - DeleteCriticalSection (&allocator_section); - DeleteCriticalSection (&finalizer_mutex); - DeleteCriticalSection (&reference_queue_mutex); + mono_mutex_destroy (&handle_section); + mono_mutex_destroy (&allocator_section); + mono_mutex_destroy (&finalizer_mutex); + mono_mutex_destroy (&reference_queue_mutex); } #else @@ -1236,7 +1250,7 @@ mono_gc_finalize_notify (void) void mono_gc_init (void) { - InitializeCriticalSection (&handle_section); + mono_mutex_init_recursive (&handle_section); } void mono_gc_cleanup (void) @@ -1295,11 +1309,11 @@ mono_gc_get_mach_exception_thread (void) * 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; @@ -1334,18 +1348,18 @@ mono_gc_parse_environment_string_extract_number (const char *str, glong *out) 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; } @@ -1416,7 +1430,7 @@ reference_queue_proccess_all (void) reference_queue_proccess (queue); restart: - EnterCriticalSection (&reference_queue_mutex); + mono_mutex_lock (&reference_queue_mutex); for (iter = &ref_queues; *iter;) { queue = *iter; if (!queue->should_be_deleted) { @@ -1424,14 +1438,14 @@ restart: continue; } if (queue->queue) { - LeaveCriticalSection (&reference_queue_mutex); + mono_mutex_unlock (&reference_queue_mutex); reference_queue_proccess (queue); goto restart; } *iter = queue->next; g_free (queue); } - LeaveCriticalSection (&reference_queue_mutex); + mono_mutex_unlock (&reference_queue_mutex); } static void @@ -1489,10 +1503,10 @@ mono_gc_reference_queue_new (mono_reference_queue_callback callback) MonoReferenceQueue *res = g_new0 (MonoReferenceQueue, 1); res->callback = callback; - EnterCriticalSection (&reference_queue_mutex); + mono_mutex_lock (&reference_queue_mutex); res->next = ref_queues; ref_queues = res; - LeaveCriticalSection (&reference_queue_mutex); + mono_mutex_unlock (&reference_queue_mutex); return res; }