コード例 #1
0
static void
major_finish_major_collection (void)
{
#ifndef FIXED_HEAP
	int section_reserve = mono_sgen_get_minor_collection_allowance () / MS_BLOCK_SIZE;

	/*
	 * FIXME: We don't free blocks on 32 bit platforms because it
	 * can lead to address space fragmentation, since we're
	 * allocating blocks in larger contingents.
	 */
	if (sizeof (mword) < 8)
		return;

	while (num_empty_blocks > section_reserve) {
		void *next = *(void**)empty_blocks;
		mono_sgen_free_os_memory (empty_blocks, MS_BLOCK_SIZE);
		empty_blocks = next;
		/*
		 * Needs not be atomic because this is running
		 * single-threaded.
		 */
		--num_empty_blocks;

		++stat_major_blocks_freed;
	}
#endif
}
コード例 #2
0
ファイル: lock-free-alloc.c プロジェクト: Alkarex/mono
static void
free_sb (gpointer sb)
{
	gpointer sb_header = SB_HEADER_FOR_ADDR (sb);
	g_assert ((char*)sb_header + SB_HEADER_SIZE == sb);
	mono_sgen_free_os_memory (sb_header, SB_SIZE);
	//g_print ("free sb %p\n", sb_header);
}
コード例 #3
0
ファイル: sgen-major-copying.c プロジェクト: Sectoid/mono
static void
free_major_section (GCMemSection *section)
{
	DEBUG (3, fprintf (gc_debug_file, "Freed major section %p (%p-%p)\n", section, section->data, section->end_data));
	mono_sgen_free_internal_dynamic (section->scan_starts,
			(section->size + SGEN_SCAN_START_SIZE - 1) / SGEN_SCAN_START_SIZE * sizeof (char*), INTERNAL_MEM_SCAN_STARTS);
	mono_sgen_free_os_memory (section, MAJOR_SECTION_SIZE);

	--num_major_sections;
}
コード例 #4
0
ファイル: lock-free-alloc.c プロジェクト: Andrea/mono
/* size must be a power of 2 */
static void*
mono_sgen_alloc_os_memory_aligned (size_t size, size_t alignment, gboolean activate)
{
	/* Allocate twice the memory to be able to put the block on an aligned address */
	char *mem = mono_sgen_alloc_os_memory (size + alignment, activate);
	char *aligned;

	g_assert (mem);

	aligned = (char*)((gulong)(mem + (alignment - 1)) & ~(alignment - 1));
	g_assert (aligned >= mem && aligned + size <= mem + size + alignment && !((gulong)aligned & (alignment - 1)));

	if (aligned > mem)
		mono_sgen_free_os_memory (mem, aligned - mem);
	if (aligned + size < mem + size + alignment)
		mono_sgen_free_os_memory (aligned + size, (mem + size + alignment) - (aligned + size));

	return aligned;
}
コード例 #5
0
static void
binary_protocol_flush_buffers_rec (BinaryProtocolBuffer *buffer)
{
	if (!buffer)
		return;

	binary_protocol_flush_buffers_rec (buffer->next);

	g_assert (buffer->index > 0);
	fwrite (buffer->buffer, 1, buffer->index, binary_protocol_file);

	mono_sgen_free_os_memory (buffer, sizeof (BinaryProtocolBuffer));
}
コード例 #6
0
ファイル: sgen-internal.c プロジェクト: Sciumo/mono
void
mono_sgen_free_internal_dynamic (void *addr, size_t size, int type)
{
	int index;

	if (!addr)
		return;

	if (size > allocator_sizes [NUM_ALLOCATORS - 1])
		return mono_sgen_free_os_memory (addr, size);

	index = index_for_size (size);

	mono_lock_free_free (addr);
}
コード例 #7
0
ファイル: lock-free-alloc.c プロジェクト: Alkarex/mono
static Descriptor*
desc_alloc (void)
{
	MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
	Descriptor *desc;

	for (;;) {
		gboolean success;

		desc = get_hazardous_pointer ((gpointer * volatile)&desc_avail, hp, 1);
		if (desc) {
			Descriptor *next = desc->next;
			success = (InterlockedCompareExchangePointer ((gpointer * volatile)&desc_avail, next, desc) == desc);
		} else {
			size_t desc_size = sizeof (Descriptor);
			Descriptor *d;
			int i;

			desc = mono_sgen_alloc_os_memory (desc_size * NUM_DESC_BATCH, TRUE);

			/* Organize into linked list. */
			d = desc;
			for (i = 0; i < NUM_DESC_BATCH; ++i) {
				Descriptor *next = (i == (NUM_DESC_BATCH - 1)) ? NULL : (Descriptor*)((char*)desc + ((i + 1) * desc_size));
				d->next = next;
				mono_lock_free_queue_node_init (&d->node, TRUE);
				d = next;
			}

			mono_memory_write_barrier ();

			success = (InterlockedCompareExchangePointer ((gpointer * volatile)&desc_avail, desc->next, NULL) == NULL);

			if (!success)
				mono_sgen_free_os_memory (desc, desc_size * NUM_DESC_BATCH);
		}

		mono_hazard_pointer_clear (hp, 1);

		if (success)
			break;
	}

	g_assert (!desc->in_use);
	desc->in_use = TRUE;

	return desc;
}
コード例 #8
0
static BinaryProtocolBuffer*
binary_protocol_get_buffer (int length)
{
	BinaryProtocolBuffer *buffer, *new_buffer;

 retry:
	buffer = binary_protocol_buffers;
	if (buffer && buffer->index + length <= BINARY_PROTOCOL_BUFFER_SIZE)
		return buffer;

	new_buffer = mono_sgen_alloc_os_memory (sizeof (BinaryProtocolBuffer), TRUE);
	new_buffer->next = buffer;
	new_buffer->index = 0;

	if (InterlockedCompareExchangePointer ((void**)&binary_protocol_buffers, new_buffer, buffer) != buffer) {
		mono_sgen_free_os_memory (new_buffer, sizeof (BinaryProtocolBuffer));
		goto retry;
	}

	return new_buffer;
}
コード例 #9
0
ファイル: sgen-pinned-allocator.c プロジェクト: Andrea/mono
void
mono_sgen_free_pinned (SgenPinnedAllocator *alc, void *addr, size_t size)
{
	LargePinnedMemHeader *mh;

	if (!addr)
		return;

	if (size <= freelist_sizes [SGEN_PINNED_FREELIST_NUM_SLOTS - 1]) {
		int slot = slot_for_size (size);
		free_from_slot (alc, addr, slot);
		return;
	}

	mh = (LargePinnedMemHeader*)((char*)addr - G_STRUCT_OFFSET (LargePinnedMemHeader, data));
	g_assert (mh->magic == LARGE_PINNED_MEM_HEADER_MAGIC);
	g_assert (mh->size == size + sizeof (LargePinnedMemHeader));
	/* FIXME: do a CAS */
	large_pinned_bytes_alloced -= mh->size;
	mono_sgen_free_os_memory (mh, mh->size);
}