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; }
static Descriptor* desc_alloc (MonoMemAccountType type) { MonoThreadHazardPointers *hp = mono_hazard_pointer_get (); Descriptor *desc; for (;;) { gboolean success; desc = (Descriptor *) mono_get_hazardous_pointer ((volatile gpointer *)&desc_avail, hp, 1); if (desc) { Descriptor *next = desc->next; success = (mono_atomic_cas_ptr ((volatile gpointer *)&desc_avail, next, desc) == desc); } else { size_t desc_size = sizeof (Descriptor); Descriptor *d; int i; desc = (Descriptor *) mono_valloc (NULL, desc_size * NUM_DESC_BATCH, prot_flags_for_activate (TRUE), type); g_assertf (desc, "Failed to allocate memory for the lock free allocator"); /* 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 = (mono_atomic_cas_ptr ((volatile gpointer *)&desc_avail, desc->next, NULL) == NULL); if (!success) mono_vfree (desc, desc_size * NUM_DESC_BATCH, type); } mono_hazard_pointer_clear (hp, 1); if (success) break; } g_assert (!desc->in_use); desc->in_use = TRUE; return desc; }
/* size must be a power of 2 */ void* sgen_alloc_os_memory_aligned (size_t size, mword alignment, SgenAllocFlags flags, const char *assert_description) { void *ptr; g_assert (!(flags & ~(SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE))); ptr = mono_valloc_aligned (size, alignment, prot_flags_for_activate (flags & SGEN_ALLOC_ACTIVATE)); sgen_assert_memory_alloc (ptr, size, assert_description); if (ptr) { SGEN_ATOMIC_ADD_P (total_alloc, size); total_alloc_max = MAX (total_alloc_max, total_alloc); } return ptr; }
static Descriptor* desc_alloc (void) { MonoThreadHazardPointers *hp = mono_hazard_pointer_get (); Descriptor *desc; for (;;) { gboolean success; desc = (Descriptor *) 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 = (Descriptor *) mono_valloc (0, desc_size * NUM_DESC_BATCH, prot_flags_for_activate (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_vfree (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; }
/* * Allocate a big chunk of memory from the OS (usually 64KB to several megabytes). * This must not require any lock. */ void* sgen_alloc_os_memory (size_t size, SgenAllocFlags flags, const char *assert_description) { void *ptr; g_assert (!(flags & ~(SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE))); ptr = mono_valloc (0, size, prot_flags_for_activate (flags & SGEN_ALLOC_ACTIVATE)); sgen_assert_memory_alloc (ptr, size, assert_description); if (ptr) { SGEN_ATOMIC_ADD_P (total_alloc, size); if (flags & SGEN_ALLOC_HEAP) MONO_GC_HEAP_ALLOC ((mword)ptr, size); } return ptr; }
/* size must be a power of 2 */ static void* mono_sgen_alloc_os_memory_aligned (size_t size, size_t alignment, gboolean activate) { return mono_valloc_aligned (size, alignment, prot_flags_for_activate (activate)); }
static void* mono_sgen_alloc_os_memory (size_t size, int activate) { return mono_valloc (0, size, prot_flags_for_activate (activate)); }