Merge pull request #2810 from kumpera/fix_hazard_free
[mono.git] / mono / utils / hazard-pointer.c
index 394fd8697ee3b7ec3162bffd09bf34514211287f..efe6b649b3039450cbdc176f0373cd55754a69be 100644 (file)
@@ -2,6 +2,7 @@
  * hazard-pointer.c: Hazard pointer related code.
  *
  * (C) Copyright 2011 Novell, Inc
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
 #include <config.h>
@@ -42,6 +43,7 @@ typedef struct {
 
 static volatile int hazard_table_size = 0;
 static MonoThreadHazardPointers * volatile hazard_table = NULL;
+static MonoHazardFreeQueueSizeCallback queue_size_cb;
 
 /*
  * Each entry is either 0 or 1, indicating whether that overflow small
@@ -305,31 +307,6 @@ try_free_delayed_free_item (HazardFreeContext context)
        return TRUE;
 }
 
-void
-mono_thread_hazardous_free_or_queue (gpointer p, MonoHazardousFreeFunc free_func,
-                                     HazardFreeLocking locking, HazardFreeContext context)
-{
-       int i;
-
-       /* First try to free a few entries in the delayed free
-          table. */
-       for (i = 0; i < 3; ++i)
-               try_free_delayed_free_item (context);
-
-       /* Now see if the pointer we're freeing is hazardous.  If it
-          isn't, free it.  Otherwise put it in the delay list. */
-       if ((context == HAZARD_FREE_ASYNC_CTX && locking == HAZARD_FREE_MAY_LOCK) ||
-           is_pointer_hazardous (p)) {
-               DelayedFreeItem item = { p, free_func, locking };
-
-               ++hazardous_pointer_count;
-
-               mono_lock_free_array_queue_push (&delayed_free_queue, &item);
-       } else {
-               free_func (p);
-       }
-}
-
 /**
  * mono_thread_hazardous_try_free:
  * @p: the pointer to free
@@ -373,12 +350,22 @@ mono_thread_hazardous_queue_free (gpointer p, MonoHazardousFreeFunc free_func)
 {
        DelayedFreeItem item = { p, free_func, HAZARD_FREE_MAY_LOCK };
 
-       ++hazardous_pointer_count;
+       InterlockedIncrement (&hazardous_pointer_count);
 
        mono_lock_free_array_queue_push (&delayed_free_queue, &item);
+
+       guint32 queue_size = delayed_free_queue.num_used_entries;
+       if (queue_size && queue_size_cb)
+               queue_size_cb (queue_size);
 }
 
 
+void
+mono_hazard_pointer_install_free_queue_size_callback (MonoHazardFreeQueueSizeCallback cb)
+{
+       queue_size_cb = cb;
+}
+
 void
 mono_thread_hazardous_try_free_all (void)
 {