From 461b6ed1f85cc036e608aec1df94c5b971b2ee53 Mon Sep 17 00:00:00 2001 From: Omri Mor Date: Thu, 4 Jun 2020 19:52:34 -0500 Subject: [PATCH] pool: don't try to steal from own thread steal id = (rand (mod n-1)) + id + 1 (mod n) Current implementation has a lot of repeated calls to lc_pool_get_local that the compiler doesn't seem to fully get rid of. Maybe marking it with __attribute__((pure)) will help? Need to re-read docs to ensure we don't violate its constraints. --- include/lc/pool.h | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/include/lc/pool.h b/include/lc/pool.h index ae9d9040..6e4560ea 100644 --- a/include/lc/pool.h +++ b/include/lc/pool.h @@ -90,14 +90,21 @@ LC_INLINE int32_t lc_pool_get_local(struct lc_pool* pool) return pid; } -LC_INLINE void* lc_pool_get_slow(struct lc_pool* pool) { - void* elm = NULL; - while (!elm) { - int steal = rand() % (pool->npools); +LC_INLINE int32_t lc_pool_get_steal(struct lc_pool* pool) +{ + int32_t pid = lc_pool_get_local(pool); + int32_t npools = pool->npools; + int32_t r = rand() % (npools - 1); + return (r + pid + 1) % npools; +} + +LC_INLINE void* lc_pool_steal(struct lc_pool* pool) +{ + void* elm = NULL; + int32_t steal = lc_pool_get_steal(pool); if (likely(pool->lpools[steal] != NULL)) elm = dq_pop_bot(pool->lpools[steal]); - } - return elm; + return elm; } LC_INLINE void lc_pool_put(struct lc_pool* pool, void* elm) { @@ -111,26 +118,19 @@ LC_INLINE void lc_pool_put_to(struct lc_pool* pool, void* elm, int32_t pid) { dq_push_top(lpool, elm); } -LC_INLINE void* lc_pool_get(struct lc_pool* pool) { +LC_INLINE void* lc_pool_get_nb(struct lc_pool* pool) { int32_t pid = lc_pool_get_local(pool); struct dequeue* lpool = pool->lpools[pid]; - void *elm = NULL; - elm = dq_pop_top(lpool); + void* elm = dq_pop_top(lpool); if (elm == NULL) - elm = lc_pool_get_slow(pool); + elm = lc_pool_steal(pool); return elm; } -LC_INLINE void* lc_pool_get_nb(struct lc_pool* pool) { - int32_t pid = lc_pool_get_local(pool); - struct dequeue* lpool = pool->lpools[pid]; +LC_INLINE void* lc_pool_get(struct lc_pool* pool) { void* elm = NULL; - elm = dq_pop_top(lpool); - if (elm == NULL) { - int steal = rand() % (pool->npools); - if (likely(pool->lpools[steal] != NULL)) - elm = dq_pop_bot(pool->lpools[steal]); - } + while (elm == NULL) + elm = lc_pool_get_nb(pool); return elm; }