This is deadlock prone as the GC lock is a leaf lock while the domain
lock required to free a JI is not.
There are plenty of places where we alloc memory while holding the
domain lock, so we cannot do it the other way.
* ######################################################################
*/
LOCK_DECLARE (gc_mutex);
+gboolean sgen_try_free_some_memory;
#define SCAN_START_SIZE SGEN_SCAN_START_SIZE
void
sgen_gc_unlock (void)
{
- UNLOCK_GC;
+ gboolean try_free = sgen_try_free_some_memory;
+ sgen_try_free_some_memory = FALSE;
+ mono_mutex_unlock (&gc_mutex);
+ MONO_GC_UNLOCKED ();
+ if (try_free)
+ mono_thread_hazardous_try_free_some ();
}
void
MONO_GC_LOCKED (); \
} while (0)
#define TRYLOCK_GC (mono_mutex_trylock (&gc_mutex) == 0)
-#define UNLOCK_GC do { \
- mono_mutex_unlock (&gc_mutex); \
- MONO_GC_UNLOCKED (); \
- } while (0)
+#define UNLOCK_GC do { sgen_gc_unlock (); } while (0)
extern LOCK_DECLARE (sgen_interruption_mutex);
extern int default_nursery_size;
extern guint32 tlab_size;
extern NurseryClearPolicy nursery_clear_policy;
+extern gboolean sgen_try_free_some_memory;
extern LOCK_DECLARE (gc_mutex);
*/
release_gc_locks ();
- mono_thread_hazardous_try_free_some ();
+ sgen_try_free_some_memory = TRUE;
sgen_bridge_processing_finish (generation);