From 22e1941050d6a60874edecc129695012840471d5 Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Wed, 26 Nov 2014 20:21:40 +0300 Subject: [PATCH] Moving pools that received request on allocation / free to beginning of pools' list; extracting long path from mem_pools_alloc. --- src/liballocator/mem-pool.c | 23 +++++++++- src/liballocator/mem-pool.h | 1 + src/liballocator/mem-poolman.c | 84 ++++++++++++++++++++++++---------- 3 files changed, 83 insertions(+), 25 deletions(-) diff --git a/src/liballocator/mem-pool.c b/src/liballocator/mem-pool.c index 1087c7fca..ca36d3930 100644 --- a/src/liballocator/mem-pool.c +++ b/src/liballocator/mem-pool.c @@ -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); diff --git a/src/liballocator/mem-pool.h b/src/liballocator/mem-pool.h index d65d52e57..9a33a8b60 100644 --- a/src/liballocator/mem-pool.h +++ b/src/liballocator/mem-pool.h @@ -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); /** * @} diff --git a/src/liballocator/mem-poolman.c b/src/liballocator/mem-poolman.c index eb34e1bf0..df7eefefa 100644 --- a/src/liballocator/mem-poolman.c +++ b/src/liballocator/mem-poolman.c @@ -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