+/*
+This is the number of entries allowed in the hazard free queue before
+we explicitly cycle the finalizer thread to trigger pumping the queue.
+
+It was picked empirically by running the corlib test suite in a stress
+scenario where all hazard entries are queued.
+
+In this extreme scenario we double the number of times we cycle the finalizer
+thread compared to just GC calls.
+
+Entries are usually in the order of 100's of bytes each, so we're limiting
+floating garbage to be in the order of a dozen kb.
+*/
+static gboolean finalizer_thread_pulsed;
+#define HAZARD_QUEUE_OVERFLOW_SIZE 20
+
+static void
+hazard_free_queue_is_too_big (size_t size)
+{
+ if (size < HAZARD_QUEUE_OVERFLOW_SIZE)
+ return;
+
+ if (finalizer_thread_pulsed || InterlockedCompareExchange (&finalizer_thread_pulsed, TRUE, FALSE))
+ return;
+
+ mono_gc_finalize_notify ();
+}
+
+static void
+hazard_free_queue_pump (void)
+{
+ mono_thread_hazardous_try_free_all ();
+ finalizer_thread_pulsed = FALSE;
+}
+