/* * initialize allocator a with a custom free_set_size * If the thread is not subscribed to the list of timestamps (used for GC), * additionally subscribe the thread to the list */ void ssmem_alloc_init_fs_size(ssmem_allocator_t* a, size_t size, size_t free_set_size, int id) { ssmem_num_allocators++; ssmem_allocator_list = ssmem_list_node_new((void*) a, ssmem_allocator_list); if (id == 0) { printf("[ALLOC] initializing allocator with fs size: %zu objects\n", free_set_size); } a->mem = (void*) memalign(CACHE_LINE_SIZE, size); assert(a->mem != NULL); a->mem_curr = 0; a->mem_size = size; a->tot_size = size; a->fs_size = free_set_size; a->mem_chunks = ssmem_list_node_new(a->mem, NULL); ssmem_gc_thread_init(a, id); a->free_set_list = ssmem_free_set_new(a->fs_size, NULL); a->free_set_num = 1; a->collected_set_list = NULL; a->collected_set_num = 0; a->available_set_list = NULL; a->released_mem_list = NULL; a->released_num = 0; }
/* * initialize allocator a with a custom free_set_size * If the thread is not subscribed to the list of timestamps (used for GC), * additionally subscribe the thread to the list */ void ssmem_alloc_init_fs_size(ssmem_allocator_t* a, size_t size, size_t free_set_size, int id) { ssmem_num_allocators++; ssmem_allocator_list = ssmem_list_node_new((void*) a, ssmem_allocator_list); if (id == 0) { printf("[ALLOC] initializing allocator with fs size: %zu objects\n", free_set_size); } #if SSMEM_TRANSPARENT_HUGE_PAGES int ret = posix_memalign(&a->mem, CACHE_LINE_SIZE, size); assert(ret == 0); #else a->mem = (void*) memalign(CACHE_LINE_SIZE, size); #endif assert(a->mem != NULL); #if SSMEM_ZERO_MEMORY == 1 memset(a->mem, 0, size); #endif a->mem_curr = 0; a->mem_size = size; a->tot_size = size; a->fs_size = free_set_size; a->mem_chunks = ssmem_list_node_new(a->mem, NULL); ssmem_gc_thread_init(a, id); a->free_set_list = ssmem_free_set_new(a->fs_size, NULL); a->free_set_num = 1; a->collected_set_list = NULL; a->collected_set_num = 0; a->available_set_list = NULL; a->released_mem_list = NULL; a->released_num = 0; }
void* ssmem_alloc(ssmem_allocator_t* a, size_t size) { void* m = NULL; #ifdef TIGHT_ALLOC m = (void*) malloc(size); #else /* 1st try to use from the collected memory */ ssmem_free_set_t* cs = a->collected_set_list; if (cs != NULL) { m = (void*) cs->set[--cs->curr]; PREFETCHW(m); if (cs->curr <= 0) { a->collected_set_list = cs->set_next; a->collected_set_num--; ssmem_free_set_make_avail(a, cs); } } else { if ((a->mem_curr + size) >= a->mem_size) { /* printf("[ALLOC] out of mem, need to allocate\n"); */ a->mem = (void*) memalign(CACHE_LINE_SIZE, a->mem_size); assert(a->mem != NULL); a->mem_curr = 0; a->tot_size += a->mem_size; a->mem_chunks = ssmem_list_node_new(a->mem, a->mem_chunks); } m = a->mem + a->mem_curr; a->mem_curr += size; } #endif #if SSMEM_TS_INCR_ON == SSMEM_TS_INCR_ON_ALLOC || SSMEM_TS_INCR_ON == SSMEM_TS_INCR_ON_BOTH ssmem_ts_next(); #endif return m; }
void* ssmem_alloc(ssmem_allocator_t* a, size_t size) { void* m = NULL; /* 1st try to use from the collected memory */ ssmem_free_set_t* cs = a->collected_set_list; if (cs != NULL) { m = (void*) cs->set[--cs->curr]; PREFETCHW(m); if (cs->curr <= 0) { a->collected_set_list = cs->set_next; a->collected_set_num--; ssmem_free_set_make_avail(a, cs); } } else { if ((a->mem_curr + size) >= a->mem_size) { #if SSMEM_MEM_SIZE_DOUBLE == 1 a->mem_size <<= 1; if (a->mem_size > SSMEM_MEM_SIZE_MAX) { a->mem_size = SSMEM_MEM_SIZE_MAX; } #endif /* printf("[ALLOC] out of mem, need to allocate (chunk = %llu MB)\n", */ /* a->mem_size / (1LL<<20)); */ if (size > a->mem_size) { /* printf("[ALLOC] asking for large mem. chunk\n"); */ while (a->mem_size < size) { if (a->mem_size > SSMEM_MEM_SIZE_MAX) { fprintf(stderr, "[ALLOC] asking for memory chunk larger than max (%llu MB) \n", SSMEM_MEM_SIZE_MAX / (1024 * 1024LL)); assert(a->mem_size <= SSMEM_MEM_SIZE_MAX); } a->mem_size <<= 1; } /* printf("[ALLOC] new mem size chunk is %llu MB\n", a->mem_size / (1024 * 1024LL)); */ } #if SSMEM_TRANSPARENT_HUGE_PAGES int ret = posix_memalign(&a->mem, CACHE_LINE_SIZE, a->mem_size); assert(ret == 0); #else a->mem = (void*) memalign(CACHE_LINE_SIZE, a->mem_size); #endif assert(a->mem != NULL); #if SSMEM_ZERO_MEMORY == 1 memset(a->mem, 0, a->mem_size); #endif a->mem_curr = 0; a->tot_size += a->mem_size; a->mem_chunks = ssmem_list_node_new(a->mem, a->mem_chunks); } m = a->mem + a->mem_curr; a->mem_curr += size; } #if SSMEM_TS_INCR_ON == SSMEM_TS_INCR_ON_ALLOC || SSMEM_TS_INCR_ON == SSMEM_TS_INCR_ON_BOTH ssmem_ts_next(); #endif return m; }