Data Structures | Functions

Memory chunk allocer
[Memory management]

Data Structures

struct  di_mem_chunk
 a mem chunk More...
struct  di_mem_area
 a mem area More...

Functions

di_mem_chunkdi_mem_chunk_new (di_ksize_t atom_size, di_ksize_t area_size) __attribute__((nonnull))
void * di_mem_chunk_alloc (di_mem_chunk *mem_chunk)
void * di_mem_chunk_alloc0 (di_mem_chunk *mem_chunk)
void di_mem_chunk_destroy (di_mem_chunk *mem_chunk)
size_t di_mem_chunk_size (di_mem_chunk *mem_chunk)
static size_t internal_di_mem_chunk_compute_size (size_t size, size_t min_size) __attribute__((nonnull))

Function Documentation

void* di_mem_chunk_alloc ( di_mem_chunk mem_chunk  ) 

Allocate a piece

Parameters:
mem_chunk a di_mem_chunk
Returns:
memory

References di_mem_area::allocated, area_size, atom_size, di_malloc(), di_mem_area::free, di_mem_area::index, di_mem_area::mem, mem_area, mem_areas, di_mem_area::next, num_mem_areas, di_mem_area::prev, and rarea_size.

Referenced by di_mem_chunk_alloc0().

{
  void *mem;

  if ((!mem_chunk->mem_area) || ((mem_chunk->mem_area->index + mem_chunk->atom_size) > mem_chunk->area_size))
  {
    mem_chunk->mem_area = di_malloc (mem_chunk->rarea_size);

    mem_chunk->num_mem_areas += 1;
    mem_chunk->mem_area->next = mem_chunk->mem_areas;
    mem_chunk->mem_area->prev = NULL;

    if (mem_chunk->mem_areas)
      mem_chunk->mem_areas->prev = mem_chunk->mem_area;
    mem_chunk->mem_areas = mem_chunk->mem_area;

    mem_chunk->mem_area->index = 0;
    mem_chunk->mem_area->free = mem_chunk->area_size;
    mem_chunk->mem_area->allocated = 0;
  }

  mem = &mem_chunk->mem_area->mem[mem_chunk->mem_area->index];
  mem_chunk->mem_area->index += mem_chunk->atom_size;
  mem_chunk->mem_area->free -= mem_chunk->atom_size;
  mem_chunk->mem_area->allocated += 1;

  return mem;
}

void* di_mem_chunk_alloc0 ( di_mem_chunk mem_chunk  ) 

Allocate a cleared piece

Parameters:
mem_chunk a di_mem_chunk
Returns:
memory

References atom_size, and di_mem_chunk_alloc().

{
  void *mem;

  mem = di_mem_chunk_alloc (mem_chunk);

  if (mem)
    memset (mem, 0, mem_chunk->atom_size);

  return mem;
}

di_mem_chunk* di_mem_chunk_new ( di_ksize_t  atom_size,
di_ksize_t  area_size 
)

Makes a new Memory-Chunk Allocer

Parameters:
atom_size size of each piece
area_size size of each alloced chunk

References area_size, atom_size, di_new, mem_area, mem_areas, num_marked_areas, num_mem_areas, and rarea_size.

Referenced by di_hash_table_new_full(), di_packages_allocator_alloc(), di_release_alloc(), and internal_di_packages_allocator_alloc().

{
  di_mem_chunk *mem_chunk;

  if (area_size < atom_size)
    return NULL;

  area_size = (area_size + atom_size - 1) / atom_size;
  area_size *= atom_size;

  mem_chunk = di_new (di_mem_chunk, 1);
  mem_chunk->num_mem_areas = 0;
  mem_chunk->num_marked_areas = 0;
  mem_chunk->mem_area = NULL;
  mem_chunk->mem_areas = NULL;
  mem_chunk->atom_size = atom_size;

  if (mem_chunk->atom_size % MEM_ALIGN)
    mem_chunk->atom_size += MEM_ALIGN - (mem_chunk->atom_size % MEM_ALIGN);

  mem_chunk->rarea_size = internal_di_mem_chunk_compute_size (area_size + sizeof (di_mem_area) - MEM_AREA_SIZE, atom_size + sizeof (di_mem_area) - MEM_AREA_SIZE);
  mem_chunk->area_size = mem_chunk->rarea_size - (sizeof (di_mem_area) - MEM_AREA_SIZE);

  return mem_chunk;
}