When popping work, grab cloned work first if possible since original work can be reused to make further clones.
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
diff --git a/cgminer.c b/cgminer.c
index 525614c..7162327 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -3834,17 +3834,29 @@ out:
static struct work *hash_pop(const struct timespec *abstime)
{
- struct work *work = NULL;
+ struct work *work = NULL, *worka, *workb;
int rc = 0;
mutex_lock(stgd_lock);
while (!getq->frozen && !HASH_COUNT(staged_work) && !rc)
rc = pthread_cond_timedwait(&getq->cond, stgd_lock, abstime);
- if (HASH_COUNT(staged_work)) {
- work = staged_work;
- HASH_DEL(staged_work, work);
+ if (unlikely(!HASH_COUNT(staged_work)))
+ goto out_unlock;
+
+ /* Look for cloned work first since original work can be used to
+ * generate further clones */
+ HASH_ITER(hh, staged_work, worka, workb) {
+ if (worka->clone) {
+ HASH_DEL(staged_work, worka);
+ work = worka;
+ goto out_unlock;
+ }
}
+
+ work = staged_work;
+ HASH_DEL(staged_work, work);
+out_unlock:
mutex_unlock(stgd_lock);
queue_request(NULL, false);