Static definition of pool's area size and number of chunks in a pool; alignment of mem_block_header_t and mem_pool_state_t to MEM_ALIGNMENT.

This commit is contained in:
Ruben Ayrapetyan 2014-11-26 18:49:00 +03:00
parent 9a0081b856
commit c21e186f2c
7 changed files with 57 additions and 56 deletions

View File

@ -29,7 +29,7 @@
/**
* Log2 of maximum number of chunks in a pool
*/
#define CONFIG_MEM_POOL_MAX_CHUNKS_NUMBER_LOG 16
#define CONFIG_MEM_POOL_MAX_CHUNKS_NUMBER_LOG 8
/**
* Size of pool chunk

View File

@ -90,7 +90,7 @@ JERRY_STATIC_ASSERT (sizeof (mem_heap_offset_t) * JERRY_BITSINBYTE >= MEM_HEAP_O
/**
* Description of heap memory block layout
*/
typedef struct mem_block_header_t
typedef struct __attribute__ ((aligned (MEM_ALIGNMENT))) mem_block_header_t
{
uint16_t magic_num; /**< magic number (mem_magic_num_of_block_t):
MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK for allocated block
@ -800,7 +800,7 @@ mem_heap_free_block (uint8_t *ptr) /**< pointer to beginning of data space of th
*
* @return recommended allocation size
*/
size_t
size_t __attribute_pure__
mem_heap_recommend_allocation_size (size_t minimum_allocation_size) /**< minimum allocation size */
{
size_t minimum_allocation_size_with_block_header = minimum_allocation_size + sizeof (mem_block_header_t);

View File

@ -44,7 +44,7 @@ extern void mem_heap_finalize (void);
extern uint8_t* mem_heap_alloc_block (size_t size_in_bytes, mem_heap_alloc_term_t alloc_term);
extern bool mem_heap_try_resize_block (uint8_t *ptr, size_t size_in_bytes);
extern void mem_heap_free_block (uint8_t *ptr);
extern size_t mem_heap_recommend_allocation_size (size_t minimum_allocation_size);
extern size_t __attribute_pure__ mem_heap_recommend_allocation_size (size_t minimum_allocation_size);
extern void mem_heap_print (bool dump_block_headers, bool dump_block_data, bool dump_stats);
#ifdef MEM_STATS

View File

@ -56,17 +56,16 @@ mem_pool_init (mem_pool_state_t *pool_p, /**< pool */
JERRY_STATIC_ASSERT(MEM_POOL_MAX_CHUNKS_NUMBER_LOG <= sizeof (mem_pool_chunk_index_t) * JERRY_BITSINBYTE);
JERRY_ASSERT(sizeof (mem_pool_chunk_index_t) <= MEM_POOL_CHUNK_SIZE);
const size_t pool_space_size = pool_size - sizeof (mem_pool_state_t);
const size_t chunks_number = pool_space_size / MEM_POOL_CHUNK_SIZE;
JERRY_ASSERT (MEM_POOL_SIZE == sizeof (mem_pool_state_t) + MEM_POOL_CHUNKS_NUMBER * MEM_POOL_CHUNK_SIZE);
JERRY_ASSERT (MEM_POOL_CHUNKS_NUMBER >= CONFIG_MEM_LEAST_CHUNK_NUMBER_IN_POOL);
JERRY_ASSERT(((mem_pool_chunk_index_t) chunks_number) == chunks_number);
pool_p->chunks_number = (mem_pool_chunk_index_t) chunks_number;
JERRY_ASSERT (pool_size == MEM_POOL_SIZE);
/*
* All chunks are free right after initialization
*/
pool_p->free_chunks_number = pool_p->chunks_number;
pool_p->free_chunks_number = (mem_pool_chunk_index_t) MEM_POOL_CHUNKS_NUMBER;
JERRY_ASSERT (pool_p->free_chunks_number == MEM_POOL_CHUNKS_NUMBER);
/*
* Chunk with zero index is first free chunk in the pool now
@ -74,7 +73,7 @@ mem_pool_init (mem_pool_state_t *pool_p, /**< pool */
pool_p->first_free_chunk = 0;
for (mem_pool_chunk_index_t chunk_index = 0;
chunk_index < chunks_number;
chunk_index < MEM_POOL_CHUNKS_NUMBER;
chunk_index++)
{
mem_pool_chunk_index_t *next_free_chunk_index_p = (mem_pool_chunk_index_t*) MEM_POOL_CHUNK_ADDRESS(pool_p,
@ -94,14 +93,8 @@ mem_pool_alloc_chunk (mem_pool_state_t *pool_p) /**< pool */
{
mem_check_pool (pool_p);
if (unlikely (pool_p->free_chunks_number == 0))
{
JERRY_ASSERT(pool_p->first_free_chunk == pool_p->chunks_number);
return NULL;
}
JERRY_ASSERT(pool_p->first_free_chunk < pool_p->chunks_number);
JERRY_ASSERT (pool_p->free_chunks_number != 0);
JERRY_ASSERT (pool_p->first_free_chunk < MEM_POOL_CHUNKS_NUMBER);
mem_pool_chunk_index_t chunk_index = pool_p->first_free_chunk;
uint8_t *chunk_p = MEM_POOL_CHUNK_ADDRESS(pool_p, chunk_index);
@ -122,9 +115,9 @@ void
mem_pool_free_chunk (mem_pool_state_t *pool_p, /**< pool */
uint8_t *chunk_p) /**< chunk pointer */
{
JERRY_ASSERT(pool_p->free_chunks_number < pool_p->chunks_number);
JERRY_ASSERT(pool_p->free_chunks_number < MEM_POOL_CHUNKS_NUMBER);
JERRY_ASSERT(chunk_p >= MEM_POOL_SPACE_START(pool_p)
&& chunk_p <= MEM_POOL_SPACE_START(pool_p) + pool_p->chunks_number * MEM_POOL_CHUNK_SIZE);
&& chunk_p <= MEM_POOL_SPACE_START(pool_p) + MEM_POOL_CHUNKS_NUMBER * MEM_POOL_CHUNK_SIZE);
JERRY_ASSERT(((uintptr_t) chunk_p - (uintptr_t) MEM_POOL_SPACE_START(pool_p)) % MEM_POOL_CHUNK_SIZE == 0);
mem_check_pool (pool_p);
@ -149,13 +142,12 @@ static void
mem_check_pool (mem_pool_state_t __unused *pool_p) /**< pool (unused #ifdef JERRY_NDEBUG) */
{
#ifndef JERRY_NDEBUG
JERRY_ASSERT(pool_p->chunks_number != 0);
JERRY_ASSERT(pool_p->free_chunks_number <= pool_p->chunks_number);
JERRY_ASSERT(pool_p->free_chunks_number <= MEM_POOL_CHUNKS_NUMBER);
size_t met_free_chunks_number = 0;
mem_pool_chunk_index_t chunk_index = pool_p->first_free_chunk;
while (chunk_index != pool_p->chunks_number)
while (chunk_index != MEM_POOL_CHUNKS_NUMBER)
{
uint8_t *chunk_p = MEM_POOL_CHUNK_ADDRESS(pool_p, chunk_index);
mem_pool_chunk_index_t *next_free_chunk_index_p = (mem_pool_chunk_index_t*) chunk_p;

View File

@ -21,11 +21,28 @@
#define JERRY_MEM_POOL_H
#include "mem-config.h"
#include "mem-heap.h"
/** \addtogroup pool Memory pool
* @{
*/
/**
* Size of a pool (header + chunks)
*/
#define MEM_POOL_SIZE \
((size_t) JERRY_MIN (sizeof (mem_pool_state_t) + (1ull << MEM_POOL_MAX_CHUNKS_NUMBER_LOG) * MEM_POOL_CHUNK_SIZE, \
JERRY_ALIGNDOWN (mem_heap_recommend_allocation_size (sizeof (mem_pool_state_t) + \
CONFIG_MEM_LEAST_CHUNK_NUMBER_IN_POOL * \
MEM_POOL_CHUNK_SIZE) \
- sizeof (mem_pool_state_t), \
MEM_POOL_CHUNK_SIZE)) + sizeof (mem_pool_state_t))
/**
* Number of chunks in a pool
*/
#define MEM_POOL_CHUNKS_NUMBER ((MEM_POOL_SIZE - sizeof (mem_pool_state_t)) / MEM_POOL_CHUNK_SIZE)
/**
* Get pool's space size
*/
@ -34,21 +51,19 @@
/**
* Index of chunk in a pool
*/
typedef uint16_t mem_pool_chunk_index_t;
typedef uint8_t mem_pool_chunk_index_t;
/**
* State of a memory pool
*/
typedef struct mem_pool_state_t
typedef struct __attribute__ ((aligned (MEM_ALIGNMENT))) mem_pool_state_t
{
/** Number of chunks (mem_pool_chunk_index_t) */
unsigned int chunks_number : MEM_POOL_MAX_CHUNKS_NUMBER_LOG;
/** Number of free chunks (mem_pool_chunk_index_t) */
unsigned int free_chunks_number : MEM_POOL_MAX_CHUNKS_NUMBER_LOG;
/** Offset of first free chunk from the beginning of the pool (mem_pool_chunk_index_t) */
unsigned int first_free_chunk : MEM_POOL_MAX_CHUNKS_NUMBER_LOG;
/** Number of free chunks (mem_pool_chunk_index_t) */
unsigned int free_chunks_number : MEM_POOL_MAX_CHUNKS_NUMBER_LOG;
/** Pointer to the next pool with same chunk size */
unsigned int next_pool_cp : MEM_HEAP_OFFSET_LOG;
} mem_pool_state_t;

View File

@ -104,13 +104,7 @@ mem_pools_alloc (void)
*/
if (mem_free_chunks_number == 0)
{
/**
* Space, at least for header and eight chunks.
*/
size_t pool_chunks_area_size = CONFIG_MEM_LEAST_CHUNK_NUMBER_IN_POOL * MEM_POOL_CHUNK_SIZE;
size_t pool_size = mem_heap_recommend_allocation_size (sizeof (mem_pool_state_t) + pool_chunks_area_size);
mem_pool_state_t *pool_state = (mem_pool_state_t*) mem_heap_alloc_block (pool_size, MEM_HEAP_ALLOC_LONG_TERM);
mem_pool_state_t *pool_state = (mem_pool_state_t*) mem_heap_alloc_block (MEM_POOL_SIZE, MEM_HEAP_ALLOC_LONG_TERM);
if (pool_state == NULL)
{
@ -120,7 +114,7 @@ mem_pools_alloc (void)
return NULL;
}
mem_pool_init (pool_state, pool_size);
mem_pool_init (pool_state, MEM_POOL_SIZE);
if (mem_pools == NULL)
{
@ -133,7 +127,7 @@ mem_pools_alloc (void)
mem_pools = pool_state;
mem_free_chunks_number += pool_state->chunks_number;
mem_free_chunks_number += MEM_POOL_CHUNKS_NUMBER;
MEM_POOLS_STAT_ALLOC_POOL ();
}
@ -145,7 +139,7 @@ mem_pools_alloc (void)
*/
mem_pool_state_t *pool_state = mem_pools;
while (pool_state->first_free_chunk == pool_state->chunks_number)
while (pool_state->first_free_chunk == MEM_POOL_CHUNKS_NUMBER)
{
pool_state = mem_decompress_pointer (pool_state->next_pool_cp);
@ -174,7 +168,7 @@ mem_pools_free (uint8_t *chunk_p) /**< pointer to the chunk */
* Search for the pool containing specified chunk.
*/
while (!(chunk_p >= MEM_POOL_SPACE_START(pool_state)
&& chunk_p <= MEM_POOL_SPACE_START(pool_state) + pool_state->chunks_number * MEM_POOL_CHUNK_SIZE))
&& chunk_p <= MEM_POOL_SPACE_START(pool_state) + MEM_POOL_CHUNKS_NUMBER * MEM_POOL_CHUNK_SIZE))
{
prev_pool_state = pool_state;
pool_state = mem_decompress_pointer (pool_state->next_pool_cp);
@ -193,7 +187,7 @@ mem_pools_free (uint8_t *chunk_p) /**< pointer to the chunk */
/**
* If all chunks of the pool are free, free the pool itself.
*/
if (pool_state->free_chunks_number == pool_state->chunks_number)
if (pool_state->free_chunks_number == MEM_POOL_CHUNKS_NUMBER)
{
if (prev_pool_state != NULL)
{
@ -211,7 +205,7 @@ mem_pools_free (uint8_t *chunk_p) /**< pointer to the chunk */
}
}
mem_free_chunks_number -= pool_state->chunks_number;
mem_free_chunks_number -= MEM_POOL_CHUNKS_NUMBER;
mem_heap_free_block ((uint8_t*)pool_state);

View File

@ -26,9 +26,6 @@ extern long int time (long int *__timer);
extern int printf (__const char *__restrict __format, ...);
extern void *memset (void *__s, int __c, size_t __n);
// Pool area size is 8K
const size_t test_pool_area_size = 8 * 1024;
// Iterations count
const uint32_t test_iters = 64;
@ -46,24 +43,27 @@ main( int __unused argc,
for ( uint32_t i = 0; i < test_iters; i++ )
{
uint8_t test_pool[test_pool_area_size] __attribute__((aligned(MEM_ALIGNMENT)));
uint8_t test_pool[MEM_POOL_SIZE] __attribute__((aligned(MEM_ALIGNMENT)));
mem_pool_state_t* pool_p = (mem_pool_state_t*) test_pool;
mem_pool_init( pool_p, sizeof (test_pool));
mem_pool_init( pool_p, MEM_POOL_SIZE);
const size_t subiters = ( (size_t) rand() % test_max_sub_iters ) + 1;
uint8_t* ptrs[subiters];
for ( size_t j = 0; j < subiters; j++ )
{
ptrs[j] = mem_pool_alloc_chunk( pool_p);
// TODO: Enable check with condition that j <= minimum count of chunks that fit in the pool
// JERRY_ASSERT(ptrs[j] != NULL);
if ( ptrs[j] != NULL )
if (pool_p->free_chunks_number != 0)
{
memset(ptrs[j], 0, MEM_POOL_CHUNK_SIZE);
ptrs[j] = mem_pool_alloc_chunk( pool_p);
memset(ptrs[j], 0, MEM_POOL_CHUNK_SIZE);
}
else
{
JERRY_ASSERT (j >= MEM_POOL_CHUNKS_NUMBER);
ptrs[j] = NULL;
}
}