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
This commit is contained in:
Mike Blumenkrantz 2018-06-21 18:17:33 -04:00
parent 198016d503
commit 14ae3e3dec
1 changed files with 37 additions and 69 deletions

View File

@ -74,9 +74,7 @@ struct _Eina_Thread_Queue_Msg_Block
// avoid reallocation via malloc/free etc. to avoid free memory pages and // avoid reallocation via malloc/free etc. to avoid free memory pages and
// pressure on the malloc subsystem // pressure on the malloc subsystem
static int _eina_thread_queue_log_dom = -1; 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_Spinlock _eina_thread_queue_block_pool_lock;
static Eina_Thread_Queue_Msg_Block *_eina_thread_queue_block_pool = NULL;
#ifdef ERR #ifdef ERR
# undef ERR # undef ERR
@ -88,51 +86,40 @@ static Eina_Thread_Queue_Msg_Block *_eina_thread_queue_block_pool = NULL;
#endif #endif
#define DBG(...) EINA_LOG_DOM_DBG(_eina_thread_queue_log_dom, __VA_ARGS__) #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 // api's to get message blocks from the pool or put them back in
static Eina_Thread_Queue_Msg_Block * static Eina_Thread_Queue_Msg_Block *
_eina_thread_queue_msg_block_new(int size) _eina_thread_queue_msg_block_new(int size)
{ {
Eina_Thread_Queue_Msg_Block *blk; 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)); 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; const char *choice = getenv("EINA_MEMPOOL");
if (blk->size >= size) if ((!choice) || (!choice[0]))
{ choice = "chained_mempool";
blk->first = 0; mp = eina_mempool_add(choice, "Eina_Thread_Queue_Msg_Block", NULL, mp_size, 16);
blk->last = 0; eina_hash_add(mempools, &size, mp);
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;
} }
eina_spinlock_release(&(_eina_thread_queue_block_pool_lock)); eina_spinlock_release(&(_eina_thread_queue_block_pool_lock));
blk = malloc(sizeof(Eina_Thread_Queue_Msg_Block) - blk = eina_mempool_calloc(mp, mp_size);
sizeof(Eina_Thread_Queue_Msg) +
size);
if (!blk) if (!blk)
{ {
ERR("Thread queue block buffer of size %i allocation failed", size); ERR("Thread queue block buffer of size %i allocation failed", size);
return NULL; return NULL;
} }
blk->next = NULL;
#ifndef ATOMIC #ifndef ATOMIC
eina_spinlock_new(&(blk->lock_ref)); eina_spinlock_new(&(blk->lock_ref));
eina_spinlock_new(&(blk->lock_first)); eina_spinlock_new(&(blk->lock_first));
#endif #endif
eina_lock_new(&(blk->lock_non_0_ref)); eina_lock_new(&(blk->lock_non_0_ref));
blk->size = size; blk->size = size;
blk->first = 0;
blk->last = 0;
blk->ref = 0;
blk->full = 0;
return blk; return blk;
} }
@ -156,23 +143,23 @@ _eina_thread_queue_msg_block_real_free(Eina_Thread_Queue_Msg_Block *blk)
static void static void
_eina_thread_queue_msg_block_free(Eina_Thread_Queue_Msg_Block *blk) _eina_thread_queue_msg_block_free(Eina_Thread_Queue_Msg_Block *blk)
{ {
if (blk->size == MIN_SIZE) Eina_Mempool *mp;
{
eina_spinlock_take(&(_eina_thread_queue_block_pool_lock)); eina_spinlock_take(&(_eina_thread_queue_block_pool_lock));
if (_eina_thread_queue_block_pool_count < 20) mp = eina_hash_find(mempools, &blk->size);
{ eina_spinlock_release(&(_eina_thread_queue_block_pool_lock));
_eina_thread_queue_block_pool_count++; eina_lock_take(&(blk->lock_non_0_ref));
blk->next = _eina_thread_queue_block_pool; eina_lock_release(&(blk->lock_non_0_ref));
_eina_thread_queue_block_pool = blk; eina_lock_free(&(blk->lock_non_0_ref));
eina_spinlock_release(&(_eina_thread_queue_block_pool_lock)); #ifndef ATOMIC
} eina_spinlock_take(&(blk->lock_ref));
else eina_spinlock_release(&(blk->lock_ref));
{ eina_spinlock_free(&(blk->lock_ref));
eina_spinlock_release(&(_eina_thread_queue_block_pool_lock)); eina_spinlock_take(&(blk->lock_first));
_eina_thread_queue_msg_block_real_free(blk); eina_spinlock_release(&(blk->lock_first));
} eina_spinlock_free(&(blk->lock_first));
} #endif
else _eina_thread_queue_msg_block_real_free(blk); eina_mempool_free(mp, blk);
} }
static Eina_Bool static Eina_Bool
@ -184,21 +171,6 @@ _eina_thread_queue_msg_block_pool_init(void)
static void static void
_eina_thread_queue_msg_block_pool_shutdown(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); 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; size = ((size + 7) >> 3) << 3;
if (!thq->data) if (!thq->data)
{ {
if (size < MIN_SIZE) size = MAX(size, MIN_SIZE);
thq->data = _eina_thread_queue_msg_block_new(MIN_SIZE); thq->data = _eina_thread_queue_msg_block_new(size);
else
thq->data = _eina_thread_queue_msg_block_new(size);
thq->last = thq->data; thq->last = thq->data;
} }
blk = thq->last; blk = thq->last;
if (blk->full) if (blk->full)
{ {
if (size < MIN_SIZE) size = MAX(size, MIN_SIZE);
blk->next = _eina_thread_queue_msg_block_new(MIN_SIZE); blk->next = _eina_thread_queue_msg_block_new(size);
else
blk->next = _eina_thread_queue_msg_block_new(size);
blk = blk->next; blk = blk->next;
thq->last = blk; thq->last = blk;
} }
@ -255,10 +223,8 @@ _eina_thread_queue_msg_alloc(Eina_Thread_Queue *thq, int size, Eina_Thread_Queue
} }
else else
{ {
if (size < MIN_SIZE) size = MAX(size, MIN_SIZE);
blk->next = _eina_thread_queue_msg_block_new(MIN_SIZE); blk->next = _eina_thread_queue_msg_block_new(size);
else
blk->next = _eina_thread_queue_msg_block_new(size);
blk = blk->next; blk = blk->next;
thq->last = blk; thq->last = blk;
blk->last += size; blk->last += size;
@ -386,6 +352,7 @@ eina_thread_queue_init(void)
ERR("Cannot init thread queue block pool spinlock"); ERR("Cannot init thread queue block pool spinlock");
return EINA_FALSE; return EINA_FALSE;
} }
mempools = eina_hash_int32_new((Eina_Free_Cb)eina_mempool_free);
return EINA_TRUE; return EINA_TRUE;
} }
@ -394,6 +361,7 @@ eina_thread_queue_shutdown(void)
{ {
_eina_thread_queue_msg_block_pool_shutdown(); _eina_thread_queue_msg_block_pool_shutdown();
eina_log_domain_unregister(_eina_thread_queue_log_dom); eina_log_domain_unregister(_eina_thread_queue_log_dom);
eina_hash_free(mempools);
return EINA_TRUE; return EINA_TRUE;
} }