Merge pull request #2810 from kumpera/fix_hazard_free
[mono.git] / mono / utils / hazard-pointer.h
index a21c456278096a6177a4dba26c9de033bedbe34f..3cb2c0aeba33817f0aad3b33bdb9c906913e6fb9 100644 (file)
@@ -2,26 +2,43 @@
  * hazard-pointer.h: 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.
  */
 #ifndef __MONO_HAZARD_POINTER_H__
 #define __MONO_HAZARD_POINTER_H__
 
 #include <glib.h>
 #include <mono/utils/mono-compiler.h>
+#include <mono/utils/mono-membar.h>
+
+#define HAZARD_POINTER_COUNT 3
 
 typedef struct {
-       gpointer hazard_pointers [2];
+       gpointer hazard_pointers [HAZARD_POINTER_COUNT];
 } MonoThreadHazardPointers;
 
 typedef void (*MonoHazardousFreeFunc) (gpointer p);
 
-void mono_thread_hazardous_free_or_queue (gpointer p, MonoHazardousFreeFunc free_func) MONO_INTERNAL;
-void mono_thread_hazardous_try_free_all (void) MONO_INTERNAL;
-MonoThreadHazardPointers* mono_hazard_pointer_get (void) MONO_INTERNAL;
-gpointer get_hazardous_pointer (gpointer volatile *pp, MonoThreadHazardPointers *hp, int hazard_index) MONO_INTERNAL;
+typedef enum {
+       HAZARD_FREE_MAY_LOCK,
+       HAZARD_FREE_NO_LOCK,
+} HazardFreeLocking;
+
+typedef enum {
+       HAZARD_FREE_SAFE_CTX,
+       HAZARD_FREE_ASYNC_CTX,
+} HazardFreeContext;
+
+gboolean mono_thread_hazardous_try_free (gpointer p, MonoHazardousFreeFunc free_func);
+void mono_thread_hazardous_queue_free (gpointer p, MonoHazardousFreeFunc free_func);
+
+void mono_thread_hazardous_try_free_all (void);
+void mono_thread_hazardous_try_free_some (void);
+MonoThreadHazardPointers* mono_hazard_pointer_get (void);
+gpointer get_hazardous_pointer (gpointer volatile *pp, MonoThreadHazardPointers *hp, int hazard_index);
 
 #define mono_hazard_pointer_set(hp,i,v)        \
-       do { g_assert ((i) == 0 || (i) == 1); \
+       do { g_assert ((i) >= 0 && (i) < HAZARD_POINTER_COUNT); \
                (hp)->hazard_pointers [(i)] = (v); \
                mono_memory_write_barrier (); \
        } while (0)
@@ -30,14 +47,21 @@ gpointer get_hazardous_pointer (gpointer volatile *pp, MonoThreadHazardPointers
        ((hp)->hazard_pointers [(i)])
 
 #define mono_hazard_pointer_clear(hp,i)        \
-       do { g_assert ((i) == 0 || (i) == 1); \
+       do { g_assert ((i) >= 0 && (i) < HAZARD_POINTER_COUNT); \
+               mono_memory_write_barrier (); \
                (hp)->hazard_pointers [(i)] = NULL; \
        } while (0)
 
 
-void mono_thread_small_id_free (int id) MONO_INTERNAL;
-int mono_thread_small_id_alloc (void) MONO_INTERNAL;
+void mono_thread_small_id_free (int id);
+int mono_thread_small_id_alloc (void);
+
+int mono_hazard_pointer_save_for_signal_handler (void);
+void mono_hazard_pointer_restore_for_signal_handler (int small_id);
+
+typedef void (*MonoHazardFreeQueueSizeCallback)(size_t size);
+void mono_hazard_pointer_install_free_queue_size_callback (MonoHazardFreeQueueSizeCallback cb);
 
-void mono_thread_smr_init (void) MONO_INTERNAL;
-void mono_thread_smr_cleanup (void) MONO_INTERNAL;
+void mono_thread_smr_init (void);
+void mono_thread_smr_cleanup (void);
 #endif /*__MONO_HAZARD_POINTER_H__*/