We shouldn't block on no work situations directly from the getwork scheduler itself.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
diff --git a/cgminer.c b/cgminer.c
index a9a1ead..11f7e99 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -5817,29 +5817,35 @@ static void pool_resus(struct pool *pool)
applog(LOG_INFO, "Pool %d %s alive", pool->pool_no, pool->rpc_url);
}
-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) {
@@ -5868,6 +5874,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;
@@ -6021,7 +6028,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;
@@ -8378,8 +8385,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;
}