From 14ae3e3dec7866e74f2990dca417eac44da41058 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 21 Jun 2018 18:17:33 -0400 Subject: [PATCH] eina_thread_queue: use normal mempools for block allocation there's no need to reimplement mempools here when we already have a great mempool api this makes the code slightly more readable Differential Revision: https://phab.enlightenment.org/D6353 --- src/lib/eina/eina_thread_queue.c | 106 +++++++++++-------------------- 1 file changed, 37 insertions(+), 69 deletions(-) diff --git a/src/lib/eina/eina_thread_queue.c b/src/lib/eina/eina_thread_queue.c index 531800dac7..b095be6c2f 100644 --- a/src/lib/eina/eina_thread_queue.c +++ b/src/lib/eina/eina_thread_queue.c @@ -74,9 +74,7 @@ struct _Eina_Thread_Queue_Msg_Block // avoid reallocation via malloc/free etc. to avoid free memory pages and // pressure on the malloc subsystem static int _eina_thread_queue_log_dom = -1; -static int _eina_thread_queue_block_pool_count = 0; static Eina_Spinlock _eina_thread_queue_block_pool_lock; -static Eina_Thread_Queue_Msg_Block *_eina_thread_queue_block_pool = NULL; #ifdef ERR # undef ERR @@ -88,51 +86,40 @@ static Eina_Thread_Queue_Msg_Block *_eina_thread_queue_block_pool = NULL; #endif #define DBG(...) EINA_LOG_DOM_DBG(_eina_thread_queue_log_dom, __VA_ARGS__) +static Eina_Hash *mempools; + // api's to get message blocks from the pool or put them back in static Eina_Thread_Queue_Msg_Block * _eina_thread_queue_msg_block_new(int size) { Eina_Thread_Queue_Msg_Block *blk; + Eina_Mempool *mp; + size_t mp_size = sizeof(Eina_Thread_Queue_Msg_Block) - sizeof(Eina_Thread_Queue_Msg) + size; eina_spinlock_take(&(_eina_thread_queue_block_pool_lock)); - if (_eina_thread_queue_block_pool) + mp = eina_hash_find(mempools, &size); + if (!mp) { - blk = _eina_thread_queue_block_pool; - if (blk->size >= size) - { - blk->first = 0; - blk->last = 0; - blk->ref = 0; - blk->full = 0; - _eina_thread_queue_block_pool = blk->next; - blk->next = NULL; - _eina_thread_queue_block_pool_count--; - eina_spinlock_release(&(_eina_thread_queue_block_pool_lock)); - return blk; - } - blk = NULL; + const char *choice = getenv("EINA_MEMPOOL"); + if ((!choice) || (!choice[0])) + choice = "chained_mempool"; + mp = eina_mempool_add(choice, "Eina_Thread_Queue_Msg_Block", NULL, mp_size, 16); + eina_hash_add(mempools, &size, mp); } eina_spinlock_release(&(_eina_thread_queue_block_pool_lock)); - blk = malloc(sizeof(Eina_Thread_Queue_Msg_Block) - - sizeof(Eina_Thread_Queue_Msg) + - size); + blk = eina_mempool_calloc(mp, mp_size); if (!blk) { ERR("Thread queue block buffer of size %i allocation failed", size); return NULL; } - blk->next = NULL; #ifndef ATOMIC eina_spinlock_new(&(blk->lock_ref)); eina_spinlock_new(&(blk->lock_first)); #endif eina_lock_new(&(blk->lock_non_0_ref)); blk->size = size; - blk->first = 0; - blk->last = 0; - blk->ref = 0; - blk->full = 0; return blk; } @@ -156,23 +143,23 @@ _eina_thread_queue_msg_block_real_free(Eina_Thread_Queue_Msg_Block *blk) static void _eina_thread_queue_msg_block_free(Eina_Thread_Queue_Msg_Block *blk) { - if (blk->size == MIN_SIZE) - { - eina_spinlock_take(&(_eina_thread_queue_block_pool_lock)); - if (_eina_thread_queue_block_pool_count < 20) - { - _eina_thread_queue_block_pool_count++; - blk->next = _eina_thread_queue_block_pool; - _eina_thread_queue_block_pool = blk; - eina_spinlock_release(&(_eina_thread_queue_block_pool_lock)); - } - else - { - eina_spinlock_release(&(_eina_thread_queue_block_pool_lock)); - _eina_thread_queue_msg_block_real_free(blk); - } - } - else _eina_thread_queue_msg_block_real_free(blk); + Eina_Mempool *mp; + + eina_spinlock_take(&(_eina_thread_queue_block_pool_lock)); + mp = eina_hash_find(mempools, &blk->size); + eina_spinlock_release(&(_eina_thread_queue_block_pool_lock)); + eina_lock_take(&(blk->lock_non_0_ref)); + eina_lock_release(&(blk->lock_non_0_ref)); + eina_lock_free(&(blk->lock_non_0_ref)); +#ifndef ATOMIC + eina_spinlock_take(&(blk->lock_ref)); + eina_spinlock_release(&(blk->lock_ref)); + eina_spinlock_free(&(blk->lock_ref)); + eina_spinlock_take(&(blk->lock_first)); + eina_spinlock_release(&(blk->lock_first)); + eina_spinlock_free(&(blk->lock_first)); +#endif + eina_mempool_free(mp, blk); } static Eina_Bool @@ -184,21 +171,6 @@ _eina_thread_queue_msg_block_pool_init(void) static void _eina_thread_queue_msg_block_pool_shutdown(void) { - eina_spinlock_take(&(_eina_thread_queue_block_pool_lock)); - while (_eina_thread_queue_block_pool) - { - Eina_Thread_Queue_Msg_Block *blk, *blknext; - - for (;;) - { - blk = _eina_thread_queue_block_pool; - if (!blk) break; - blknext = blk->next; - _eina_thread_queue_msg_block_real_free(blk); - _eina_thread_queue_block_pool = blknext; - } - } - eina_spinlock_release(&(_eina_thread_queue_block_pool_lock)); eina_spinlock_free(&_eina_thread_queue_block_pool_lock); } @@ -231,19 +203,15 @@ _eina_thread_queue_msg_alloc(Eina_Thread_Queue *thq, int size, Eina_Thread_Queue size = ((size + 7) >> 3) << 3; if (!thq->data) { - if (size < MIN_SIZE) - thq->data = _eina_thread_queue_msg_block_new(MIN_SIZE); - else - thq->data = _eina_thread_queue_msg_block_new(size); + size = MAX(size, MIN_SIZE); + thq->data = _eina_thread_queue_msg_block_new(size); thq->last = thq->data; } blk = thq->last; if (blk->full) { - if (size < MIN_SIZE) - blk->next = _eina_thread_queue_msg_block_new(MIN_SIZE); - else - blk->next = _eina_thread_queue_msg_block_new(size); + size = MAX(size, MIN_SIZE); + blk->next = _eina_thread_queue_msg_block_new(size); blk = blk->next; thq->last = blk; } @@ -255,10 +223,8 @@ _eina_thread_queue_msg_alloc(Eina_Thread_Queue *thq, int size, Eina_Thread_Queue } else { - if (size < MIN_SIZE) - blk->next = _eina_thread_queue_msg_block_new(MIN_SIZE); - else - blk->next = _eina_thread_queue_msg_block_new(size); + size = MAX(size, MIN_SIZE); + blk->next = _eina_thread_queue_msg_block_new(size); blk = blk->next; thq->last = blk; blk->last += size; @@ -386,6 +352,7 @@ eina_thread_queue_init(void) ERR("Cannot init thread queue block pool spinlock"); return EINA_FALSE; } + mempools = eina_hash_int32_new((Eina_Free_Cb)eina_mempool_free); return EINA_TRUE; } @@ -394,6 +361,7 @@ eina_thread_queue_shutdown(void) { _eina_thread_queue_msg_block_pool_shutdown(); eina_log_domain_unregister(_eina_thread_queue_log_dom); + eina_hash_free(mempools); return EINA_TRUE; }