Add z14 support and extend z13 support
[mono.git] / mono / utils / mono-conc-hashtable.c
index 58cf945facf0a0136f920c2f94d72622df4c7ea9..bfb94b7af9e7b024f475deb0e5907afbb85f38bf 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * mono-conc-hashtable.h: A mostly concurrent hashtable
+/**
+ * \file
+ * A mostly concurrent hashtable
  *
  * Author:
  *     Rodrigo Kumpera (kumpera@gmail.com)
@@ -56,7 +57,7 @@ conc_table_free (gpointer ptr)
 static void
 conc_table_lf_free (conc_table *table)
 {
-       mono_thread_hazardous_free_or_queue (table, conc_table_free, HAZARD_FREE_MAY_LOCK, HAZARD_FREE_SAFE_CTX);
+       mono_thread_hazardous_try_free (table, conc_table_free);
 }
 
 
@@ -114,7 +115,7 @@ mono_conc_hashtable_new (GHashFunc hash_func, GEqualFunc key_equal_func)
 {
        MonoConcurrentHashTable *res = g_new0 (MonoConcurrentHashTable, 1);
        res->hash_func = hash_func ? hash_func : g_direct_hash;
-       res->equal_func = key_equal_func ? key_equal_func : g_direct_equal;
+       res->equal_func = key_equal_func;
        // res->equal_func = g_direct_equal;
        res->table = conc_table_new (INITIAL_SIZE);
        res->element_count = 0;
@@ -164,7 +165,7 @@ mono_conc_hashtable_lookup (MonoConcurrentHashTable *hash_table, gpointer key)
        hp = mono_hazard_pointer_get ();
 
 retry:
-       table = (conc_table *)get_hazardous_pointer ((gpointer volatile*)&hash_table->table, hp, 0);
+       table = (conc_table *)mono_get_hazardous_pointer ((gpointer volatile*)&hash_table->table, hp, 0);
        table_mask = table->table_size - 1;
        kvs = table->kvs;
        i = hash & table_mask;
@@ -214,10 +215,8 @@ retry:
 
 /**
  * mono_conc_hashtable_remove:
- *
  * Remove a value from the hashtable. Requires external locking
- *
- * @Returns the old value if key is already present or null
+ * \returns the old value if \p key is already present or NULL
  */
 gpointer
 mono_conc_hashtable_remove (MonoConcurrentHashTable *hash_table, gpointer key)
@@ -246,6 +245,7 @@ mono_conc_hashtable_remove (MonoConcurrentHashTable *hash_table, gpointer key)
                                kvs [i].value = NULL;
                                mono_memory_barrier ();
                                kvs [i].key = TOMBSTONE;
+                               --hash_table->element_count;
 
                                if (hash_table->key_destroy_func != NULL)
                                        (*hash_table->key_destroy_func) (key);
@@ -283,9 +283,8 @@ mono_conc_hashtable_remove (MonoConcurrentHashTable *hash_table, gpointer key)
 }
 /**
  * mono_conc_hashtable_insert:
- * 
  * Insert a value into the hashtable. Requires external locking.
- * @Returns the old value if key is already present or null
+ * \returns the old value if \p key is already present or NULL
  */
 gpointer
 mono_conc_hashtable_insert (MonoConcurrentHashTable *hash_table, gpointer key, gpointer value)
@@ -345,8 +344,7 @@ mono_conc_hashtable_insert (MonoConcurrentHashTable *hash_table, gpointer key, g
 
 /**
  * mono_conc_hashtable_foreach:
- *
- * Calls @func for each value in the hashtable. Requires external locking.
+ * Calls \p func for each value in the hashtable. Requires external locking.
  */
 void
 mono_conc_hashtable_foreach (MonoConcurrentHashTable *hash_table, GHFunc func, gpointer userdata)
@@ -361,3 +359,28 @@ mono_conc_hashtable_foreach (MonoConcurrentHashTable *hash_table, GHFunc func, g
                }
        }
 }
+
+/**
+ * mono_conc_hashtable_foreach_steal:
+ *
+ * Calls @func for each entry in the hashtable, if @func returns true, remove from the hashtable. Requires external locking.
+ * Same semantics as g_hash_table_foreach_steal.
+ */
+void
+mono_conc_hashtable_foreach_steal (MonoConcurrentHashTable *hash_table, GHRFunc func, gpointer userdata)
+{
+       int i;
+       conc_table *table = (conc_table*)hash_table->table;
+       key_value_pair *kvs = table->kvs;
+
+       for (i = 0; i < table->table_size; ++i) {
+               if (kvs [i].key && kvs [i].key != TOMBSTONE) {
+                       if (func (kvs [i].key, kvs [i].value, userdata)) {
+                               kvs [i].value = NULL;
+                               mono_memory_barrier ();
+                               kvs [i].key = TOMBSTONE;
+                               --hash_table->element_count;
+                       }
+               }
+       }
+}