return index;
}
-/*
- * Removes all NULL pointers from the array. Not thread safe
- */
-void
-sgen_array_list_remove_nulls (SgenArrayList *array)
-{
- guint32 start = 0;
- volatile gpointer *slot;
-
- SGEN_ARRAY_LIST_FOREACH_SLOT (array, slot) {
- if (*slot)
- *sgen_array_list_get_slot (array, start++) = *slot;
- } SGEN_ARRAY_LIST_END_FOREACH_SLOT;
-
- mono_memory_write_barrier ();
- array->next_slot = start;
-}
-
/*
* Does a linear search through the pointer array to find `ptr`. Returns the index if
* found, otherwise (guint32)-1.
return (guint32)-1;
}
+gboolean
+sgen_array_list_default_cas_setter (volatile gpointer *slot, gpointer ptr, int data)
+{
+ if (InterlockedCompareExchangePointer (slot, ptr, NULL) == NULL)
+ return TRUE;
+ return FALSE;
+}
+
+gboolean
+sgen_array_list_default_is_slot_set (volatile gpointer *slot)
+{
+ return *slot != NULL;
+}
+
#endif
guint32 sgen_array_list_alloc_block (SgenArrayList *array, guint32 slots_to_add);
guint32 sgen_array_list_add (SgenArrayList *array, gpointer ptr, int data, gboolean increase_size_before_set);
guint32 sgen_array_list_find (SgenArrayList *array, gpointer ptr);
-void sgen_array_list_remove_nulls (SgenArrayList *array);
+gboolean sgen_array_list_default_cas_setter (volatile gpointer *slot, gpointer ptr, int data);
+gboolean sgen_array_list_default_is_slot_set (volatile gpointer *slot);
+
#endif
#define BLOCK_TAG(bl) ((bl)->has_references ? BLOCK_TAG_HAS_REFERENCES ((bl)) : (bl))
/* all allocated blocks in the system */
-static SgenArrayList allocated_blocks = SGEN_ARRAY_LIST_INIT (NULL, NULL, NULL, INTERNAL_MEM_PIN_QUEUE);
+static SgenArrayList allocated_blocks = SGEN_ARRAY_LIST_INIT (NULL, sgen_array_list_default_is_slot_set, sgen_array_list_default_cas_setter, INTERNAL_MEM_PIN_QUEUE);
/* non-allocated block free-list */
static void *empty_blocks = NULL;
for (j = 0; j < num_block_obj_sizes; ++j)
free_blocks [j] = NULL;
}
-
- sgen_array_list_remove_nulls (&allocated_blocks);
}
static void sweep_finish (void);
ms_free_block (block);
SGEN_ATOMIC_ADD_P (num_major_sections, -1);
+ SGEN_ATOMIC_ADD_P (num_major_sections_freed_in_sweep, 1);
tagged_block = NULL;
}
* cooperate with the sweep thread to finish sweeping, and they will traverse from
* low to high, to avoid constantly colliding on the same blocks.
*/
- for (block_index = num_blocks; block_index-- > 0;) {
- /*
- * The block might have been freed by another thread doing some checking
- * work.
- */
- if (!ensure_block_is_checked_for_sweeping (block_index, TRUE, NULL))
- ++num_major_sections_freed_in_sweep;
+ for (block_index = allocated_blocks.next_slot; block_index-- > 0;) {
+ ensure_block_is_checked_for_sweeping (block_index, TRUE, NULL);
}
while (!try_set_sweep_state (SWEEP_STATE_COMPACTING, SWEEP_STATE_SWEEPING)) {
sweep_start ();
- SGEN_ASSERT (0, num_major_sections == allocated_blocks.next_slot, "We don't know how many blocks we have?");
-
num_major_sections_before_sweep = num_major_sections;
num_major_sections_freed_in_sweep = 0;