Exemple #1
0
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);
}
Exemple #2
0
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);
	}
}
Exemple #3
0
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;
}
Exemple #4
0
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;
}