Moving pools that received request on allocation / free to beginning of pools' list; extracting long path from mem_pools_alloc.

This commit is contained in:
Ruben Ayrapetyan
2014-11-26 20:21:40 +03:00
parent c21e186f2c
commit 22e1941050
3 changed files with 83 additions and 25 deletions
+21 -2
View File
@@ -39,6 +39,26 @@ static void mem_check_pool (mem_pool_state_t *pool_p);
#define MEM_POOL_CHUNK_ADDRESS(pool_header_p, chunk_index) ((uint8_t*) (MEM_POOL_SPACE_START(pool_p) + \
MEM_POOL_CHUNK_SIZE * chunk_index))
/**
* Is the chunk is inside of the pool?
*
* @return true / false
*/
bool __attribute_const__
mem_pool_is_chunk_inside (mem_pool_state_t *pool_p, /**< pool */
uint8_t *chunk_p) /**< chunk */
{
if (chunk_p >= (uint8_t*) pool_p && chunk_p < (uint8_t*) pool_p + MEM_POOL_SIZE)
{
JERRY_ASSERT (chunk_p >= MEM_POOL_SPACE_START(pool_p)
&& chunk_p <= MEM_POOL_SPACE_START(pool_p) + MEM_POOL_CHUNKS_NUMBER * MEM_POOL_CHUNK_SIZE);
return true;
}
return false;
} /* mem_pool_is_chunk_inside */
/**
* Initialization of memory pool.
*
@@ -116,8 +136,7 @@ mem_pool_free_chunk (mem_pool_state_t *pool_p, /**< pool */
uint8_t *chunk_p) /**< chunk pointer */
{
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) + MEM_POOL_CHUNKS_NUMBER * MEM_POOL_CHUNK_SIZE);
JERRY_ASSERT(mem_pool_is_chunk_inside (pool_p, chunk_p));
JERRY_ASSERT(((uintptr_t) chunk_p - (uintptr_t) MEM_POOL_SPACE_START(pool_p)) % MEM_POOL_CHUNK_SIZE == 0);
mem_check_pool (pool_p);
+1
View File
@@ -71,6 +71,7 @@ typedef struct __attribute__ ((aligned (MEM_ALIGNMENT))) mem_pool_state_t
extern void mem_pool_init (mem_pool_state_t *pool_p, size_t pool_size);
extern uint8_t* mem_pool_alloc_chunk (mem_pool_state_t *pool_p);
extern void mem_pool_free_chunk (mem_pool_state_t *pool_p, uint8_t *chunk_p);
extern bool __attribute_const__ mem_pool_is_chunk_inside (mem_pool_state_t *pool_p, uint8_t *chunk_p);
/**
* @}
+61 -23
View File
@@ -91,13 +91,13 @@ mem_pools_finalize (void)
} /* mem_pools_finalize */
/**
* Allocate a chunk of specified size
* Long path for mem_pools_alloc
*
* @return pointer to allocated chunk, if allocation was successful,
* or NULL - if not enough memory.
* @return true - if there is a free chunk in mem_pools,
* false - otherwise (not enough memory).
*/
uint8_t*
mem_pools_alloc (void)
static bool __noinline
mem_pools_alloc_longpath (void)
{
/**
* If there are no free chunks, allocate new pool.
@@ -131,21 +131,52 @@ mem_pools_alloc (void)
MEM_POOLS_STAT_ALLOC_POOL ();
}
/**
* Now there is definitely at least one pool of specified type with at least one free chunk.
*
* Search for the pool.
*/
mem_pool_state_t *pool_state = mem_pools;
while (pool_state->first_free_chunk == MEM_POOL_CHUNKS_NUMBER)
else
{
pool_state = mem_decompress_pointer (pool_state->next_pool_cp);
/**
* There is definitely at least one pool of specified type with at least one free chunk.
*
* Search for the pool.
*/
mem_pool_state_t *pool_state = mem_pools, *prev_pool_state_p = NULL;
JERRY_ASSERT(pool_state != NULL);
while (pool_state->first_free_chunk == MEM_POOL_CHUNKS_NUMBER)
{
prev_pool_state_p = pool_state;
pool_state = mem_decompress_pointer (pool_state->next_pool_cp);
JERRY_ASSERT(pool_state != NULL);
}
JERRY_ASSERT (prev_pool_state_p != NULL && pool_state != mem_pools);
prev_pool_state_p->next_pool_cp = pool_state->next_pool_cp;
pool_state->next_pool_cp = (uint16_t) mem_compress_pointer (mem_pools);
mem_pools = pool_state;
}
return true;
} /* mem_pools_alloc_longpath */
/**
* Allocate a chunk of specified size
*
* @return pointer to allocated chunk, if allocation was successful,
* or NULL - if not enough memory.
*/
uint8_t*
mem_pools_alloc (void)
{
if (mem_pools == NULL || mem_pools->first_free_chunk == MEM_POOL_CHUNKS_NUMBER)
{
if (!mem_pools_alloc_longpath ())
{
return NULL;
}
}
JERRY_ASSERT (mem_pools != NULL && mem_pools->first_free_chunk != MEM_POOL_CHUNKS_NUMBER);
/**
* And allocate chunk within it.
*/
@@ -153,7 +184,7 @@ mem_pools_alloc (void)
MEM_POOLS_STAT_ALLOC_CHUNK ();
return mem_pool_alloc_chunk (pool_state);
return mem_pool_alloc_chunk (mem_pools);
} /* mem_pools_alloc */
/**
@@ -162,15 +193,14 @@ mem_pools_alloc (void)
void
mem_pools_free (uint8_t *chunk_p) /**< pointer to the chunk */
{
mem_pool_state_t *pool_state = mem_pools, *prev_pool_state = NULL;
mem_pool_state_t *pool_state = mem_pools, *prev_pool_state_p = NULL;
/**
* Search for the pool containing specified chunk.
*/
while (!(chunk_p >= MEM_POOL_SPACE_START(pool_state)
&& chunk_p <= MEM_POOL_SPACE_START(pool_state) + MEM_POOL_CHUNKS_NUMBER * MEM_POOL_CHUNK_SIZE))
while (!mem_pool_is_chunk_inside (pool_state, chunk_p))
{
prev_pool_state = pool_state;
prev_pool_state_p = pool_state;
pool_state = mem_decompress_pointer (pool_state->next_pool_cp);
JERRY_ASSERT(pool_state != NULL);
@@ -189,9 +219,9 @@ mem_pools_free (uint8_t *chunk_p) /**< pointer to the chunk */
*/
if (pool_state->free_chunks_number == MEM_POOL_CHUNKS_NUMBER)
{
if (prev_pool_state != NULL)
if (prev_pool_state_p != NULL)
{
prev_pool_state->next_pool_cp = pool_state->next_pool_cp;
prev_pool_state_p->next_pool_cp = pool_state->next_pool_cp;
}
else
{
@@ -211,6 +241,14 @@ mem_pools_free (uint8_t *chunk_p) /**< pointer to the chunk */
MEM_POOLS_STAT_FREE_POOL ();
}
else if (mem_pools != pool_state)
{
JERRY_ASSERT (prev_pool_state_p != NULL);
prev_pool_state_p->next_pool_cp = pool_state->next_pool_cp;
pool_state->next_pool_cp = (uint16_t) mem_compress_pointer (mem_pools);
mem_pools = pool_state;
}
} /* mem_pools_free */
#ifdef MEM_STATS