forked from enlightenment/efl
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:
parent
198016d503
commit
14ae3e3dec
|
@ -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_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));
|
eina_spinlock_release(&(_eina_thread_queue_block_pool_lock));
|
||||||
}
|
eina_lock_take(&(blk->lock_non_0_ref));
|
||||||
else
|
eina_lock_release(&(blk->lock_non_0_ref));
|
||||||
{
|
eina_lock_free(&(blk->lock_non_0_ref));
|
||||||
eina_spinlock_release(&(_eina_thread_queue_block_pool_lock));
|
#ifndef ATOMIC
|
||||||
_eina_thread_queue_msg_block_real_free(blk);
|
eina_spinlock_take(&(blk->lock_ref));
|
||||||
}
|
eina_spinlock_release(&(blk->lock_ref));
|
||||||
}
|
eina_spinlock_free(&(blk->lock_ref));
|
||||||
else _eina_thread_queue_msg_block_real_free(blk);
|
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
|
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,18 +203,14 @@ _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);
|
|
||||||
else
|
|
||||||
thq->data = _eina_thread_queue_msg_block_new(size);
|
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);
|
|
||||||
else
|
|
||||||
blk->next = _eina_thread_queue_msg_block_new(size);
|
blk->next = _eina_thread_queue_msg_block_new(size);
|
||||||
blk = blk->next;
|
blk = blk->next;
|
||||||
thq->last = blk;
|
thq->last = blk;
|
||||||
|
@ -255,9 +223,7 @@ _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);
|
|
||||||
else
|
|
||||||
blk->next = _eina_thread_queue_msg_block_new(size);
|
blk->next = _eina_thread_queue_msg_block_new(size);
|
||||||
blk = blk->next;
|
blk = blk->next;
|
||||||
thq->last = blk;
|
thq->last = blk;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue