mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
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:
parent
9a0081b856
commit
c21e186f2c
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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,25 +43,28 @@ 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++ )
|
||||
{
|
||||
if (pool_p->free_chunks_number != 0)
|
||||
{
|
||||
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 )
|
||||
{
|
||||
memset(ptrs[j], 0, MEM_POOL_CHUNK_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (j >= MEM_POOL_CHUNKS_NUMBER);
|
||||
|
||||
ptrs[j] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// mem_heap_print( true);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user