fms_void *fms_mem_alloc(fms_mem_pool *const mem_pool, const fms_s32 size) { fms_void *ptr = NULL; //FMS_EQUAL_RETURN_VALUE(size <= 0, FMS_TRUE, NULL); if (size <= FMS_PAGE_SIZE - 1) { fms_list *pos = NULL; fms_mem_block *tmp_block = NULL; pos = &mem_pool->current_block->list; while (fms_list_is_loop(&mem_pool->head_block, pos)) { tmp_block = fms_list_data(pos, fms_mem_block, list); ptr = fms_align_ptr(tmp_block->cur, FMS_MEM_POOL_ALIGN_MENT); if ((size_t)(tmp_block->end - (fms_s8 *)ptr) >= size) { tmp_block->cur = (fms_s8 *)ptr + size; return ptr; } pos = fms_list_next(pos); } return mem_block_alloc(mem_pool, size); } return mem_large_alloc(mem_pool, size); }
void data_stack_init(void) { if (data_stack_frame > 0) { /* already initialized (we did auto-initialization in t_malloc/t_push) */ return; } data_stack_frame = 1; outofmem_area.block.size = outofmem_area.block.left = sizeof(outofmem_area) - sizeof(outofmem_area.block); current_block = mem_block_alloc(INITIAL_STACK_SIZE); current_block->left = current_block->size; current_block->next = NULL; current_frame_block = NULL; unused_frame_blocks = NULL; frame_pos = BLOCK_FRAME_COUNT-1; last_buffer_block = NULL; last_buffer_size = 0; (void)t_push(); }
static void *mem_file_write(struct mem_file *mf, const void *data, size_t size, int flags) { void *wrbase = NULL; while (size > 0) { size_t space, csize; struct mem_block *mb = mf->tail; if (!mb || !mem_block_can_write(mb, size, flags)) { mb = mem_block_alloc(mf, max(MEMFILE_BLOCK_SIZE, size)); if (!mf->tail) mf->head = mb; else mf->tail->next = mb; mf->tail = mb; } space = mb->top - mb->wptr; csize = min(size, space); wrbase = mem_block_write(mb, data, csize); mf->size += csize; size -= csize; data = (const char *) data + csize; } return wrbase; }
static void *t_malloc_real(size_t size, bool permanent) { struct stack_block *block; void *ret; size_t alloc_size; #ifdef DEBUG bool warn = FALSE; #endif if (unlikely(size == 0 || size > SSIZE_T_MAX)) i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size); if (unlikely(data_stack_frame == 0)) { /* kludgy, but allow this before initialization */ data_stack_init(); } /* allocate only aligned amount of memory so alignment comes always properly */ #ifndef DEBUG alloc_size = MEM_ALIGN(size); #else alloc_size = MEM_ALIGN(sizeof(size)) + MEM_ALIGN(size + SENTRY_COUNT); #endif data_stack_last_buffer_reset(TRUE); /* used for t_try_realloc() */ current_frame_block->last_alloc_size[frame_pos] = alloc_size; if (current_block->left >= alloc_size) { /* enough space in current block, use it */ ret = STACK_BLOCK_DATA(current_block) + (current_block->size - current_block->left); if (current_block->left - alloc_size < current_block->lowwater) { current_block->lowwater = current_block->left - alloc_size; } if (permanent) current_block->left -= alloc_size; } else { /* current block is full, see if we can use the unused_block */ if (unused_block != NULL && unused_block->size >= alloc_size) { block = unused_block; unused_block = NULL; } else { block = mem_block_alloc(alloc_size); #ifdef DEBUG warn = TRUE; #endif } block->left = block->size; if (block->left - alloc_size < block->lowwater) block->lowwater = block->left - alloc_size; if (permanent) block->left -= alloc_size; block->next = NULL; current_block->next = block; current_block = block; ret = STACK_BLOCK_DATA(current_block); #ifdef DEBUG if (warn && getenv("DEBUG_SILENT") == NULL) { /* warn after allocation, so if i_warning() wants to allocate more memory we don't go to infinite loop */ i_warning("Growing data stack with: %"PRIuSIZE_T, block->size); } #endif } #ifdef DEBUG memcpy(ret, &size, sizeof(size)); ret = PTR_OFFSET(ret, MEM_ALIGN(sizeof(size))); /* make sure the sentry contains CLEAR_CHRs. it might not if we had used t_buffer_get(). */ memset(PTR_OFFSET(ret, size), CLEAR_CHR, MEM_ALIGN(size + SENTRY_COUNT) - size); #endif return ret; }