From a8255243254baeee796eae28c1c4b328b7b57d92 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sat, 8 Feb 2014 11:09:11 +1100 Subject: [PATCH] We shouldn't block on no work situations directly from the getwork scheduler itself. --- sgminer.c | 48 ++++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/sgminer.c b/sgminer.c index c1c4774c..d287e182 100644 --- a/sgminer.c +++ b/sgminer.c @@ -5713,29 +5713,35 @@ static void pool_resus(struct pool *pool) applog(LOG_INFO, "%s alive", pool->poolname); } -static struct work *hash_pop(void) +/* If this is called non_blocking, it will return NULL for work so that must + * be handled. */ +static struct work *hash_pop(bool blocking) { struct work *work = NULL, *tmp; int hc; mutex_lock(stgd_lock); - while (!HASH_COUNT(staged_work)) { - struct timespec then; - struct timeval now; - int rc; + if (!HASH_COUNT(staged_work)) { + if (!blocking) + goto out_unlock; + do { + struct timespec then; + struct timeval now; + int rc; - cgtime(&now); - then.tv_sec = now.tv_sec + 10; - then.tv_nsec = now.tv_usec * 1000; - pthread_cond_signal(&gws_cond); - rc = pthread_cond_timedwait(&getq->cond, stgd_lock, &then); - /* Check again for !no_work as multiple threads may be - * waiting on this condition and another may set the - * bool separately. */ - if (rc && !no_work) { - no_work = true; - applog(LOG_WARNING, "Waiting for work to be available from pools."); - } + cgtime(&now); + then.tv_sec = now.tv_sec + 10; + then.tv_nsec = now.tv_usec * 1000; + pthread_cond_signal(&gws_cond); + rc = pthread_cond_timedwait(&getq->cond, stgd_lock, &then); + /* Check again for !no_work as multiple threads may be + * waiting on this condition and another may set the + * bool separately. */ + if (rc && !no_work) { + no_work = true; + applog(LOG_WARNING, "Waiting for work to be available from pools."); + } + } while (!HASH_COUNT(staged_work)); } if (no_work) { @@ -5764,6 +5770,7 @@ static struct work *hash_pop(void) /* Keep track of last getwork grabbed */ last_getwork = time(NULL); +out_unlock: mutex_unlock(stgd_lock); return work; @@ -5918,7 +5925,7 @@ struct work *get_work(struct thr_info *thr, const int thr_id) applog(LOG_DEBUG, "Popping work from get queue to get work"); diff_t = time(NULL); while (!work) { - work = hash_pop(); + work = hash_pop(true); if (stale_work(work, false)) { discard_work(work); work = NULL; @@ -8178,8 +8185,9 @@ begin_bench: /* Keeps slowly generating work even if it's not being * used to keep last_getwork incrementing and to see * if pools are still alive. */ - work = hash_pop(); - discard_work(work); + work = hash_pop(false); + if (work) + discard_work(work); continue; }