static void free_sb (gpointer sb, size_t block_size) { gpointer sb_header = sb_header_for_addr (sb, block_size); g_assert ((char*)sb_header + LOCK_FREE_ALLOC_SB_HEADER_SIZE == sb); mono_vfree (sb_header, block_size); //g_print ("free sb %p\n", sb_header); }
void mono_lock_free_free (gpointer ptr, size_t block_size) { Anchor old_anchor, new_anchor; Descriptor *desc; gpointer sb; MonoLockFreeAllocator *heap = NULL; desc = *(Descriptor**) sb_header_for_addr (ptr, block_size); g_assert (block_size == desc->block_size); sb = desc->sb; do { new_anchor = old_anchor = *(volatile Anchor*)&desc->anchor.value; *(unsigned int*)ptr = old_anchor.data.avail; new_anchor.data.avail = ((char*)ptr - (char*)sb) / desc->slot_size; g_assert (new_anchor.data.avail < LOCK_FREE_ALLOC_SB_USABLE_SIZE (block_size) / desc->slot_size); if (old_anchor.data.state == STATE_FULL) new_anchor.data.state = STATE_PARTIAL; if (++new_anchor.data.count == desc->max_count) { heap = desc->heap; new_anchor.data.state = STATE_EMPTY; } } while (!set_anchor (desc, old_anchor, new_anchor)); if (new_anchor.data.state == STATE_EMPTY) { g_assert (old_anchor.data.state != STATE_EMPTY); if (InterlockedCompareExchangePointer ((gpointer * volatile)&heap->active, NULL, desc) == desc) { /* We own it, so we free it. */ desc_retire (desc); } else { /* * Somebody else must free it, so we do some * freeing for others. */ list_remove_empty_desc (heap->sc); } } else if (old_anchor.data.state == STATE_FULL) { /* * Nobody owned it, now we do, so we need to give it * back. */ g_assert (new_anchor.data.state == STATE_PARTIAL); if (InterlockedCompareExchangePointer ((gpointer * volatile)&desc->heap->active, desc, NULL) != NULL) heap_put_partial (desc); } }
static gpointer alloc_sb (Descriptor *desc) { static int pagesize = -1; gpointer sb_header; if (pagesize == -1) pagesize = mono_pagesize (); sb_header = desc->block_size == pagesize ? mono_valloc (0, desc->block_size, prot_flags_for_activate (TRUE)) : mono_valloc_aligned (desc->block_size, desc->block_size, prot_flags_for_activate (TRUE)); g_assert (sb_header == sb_header_for_addr (sb_header, desc->block_size)); *(Descriptor**)sb_header = desc; //g_print ("sb %p for %p\n", sb_header, desc); return (char*)sb_header + LOCK_FREE_ALLOC_SB_HEADER_SIZE; }
static gpointer alloc_sb (Descriptor *desc) { static int pagesize = -1; gpointer sb_header; if (pagesize == -1) pagesize = mono_pagesize (); sb_header = desc->block_size == pagesize ? mono_valloc (NULL, desc->block_size, prot_flags_for_activate (TRUE), desc->heap->account_type) : mono_valloc_aligned (desc->block_size, desc->block_size, prot_flags_for_activate (TRUE), desc->heap->account_type); g_assertf (sb_header, "Failed to allocate memory for the lock free allocator"); g_assert (sb_header == sb_header_for_addr (sb_header, desc->block_size)); *(Descriptor**)sb_header = desc; //g_print ("sb %p for %p\n", sb_header, desc); return (char*)sb_header + LOCK_FREE_ALLOC_SB_HEADER_SIZE; }