Use the work clone flag to determine if we should subtract it from the total queued variable and provide a subtract queued function to prevent looping over locked code.
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 87 88 89 90 91 92 93 94 95 96 97 98 99 100
diff --git a/cgminer.c b/cgminer.c
index 45a9303..1d68349 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -2398,8 +2398,11 @@ static void inc_queued(void)
mutex_unlock(&qd_lock);
}
-static void dec_queued(void)
+static void dec_queued(struct work *work)
{
+ if (work->clone)
+ return;
+
mutex_lock(&qd_lock);
if (total_queued > 0)
total_queued--;
@@ -2416,10 +2419,19 @@ static int requests_queued(void)
return ret;
}
+static void subtract_queued(int work_units)
+{
+ mutex_lock(&qd_lock);
+ total_queued -= work_units;
+ if (total_queued < 0)
+ total_queued = 0;
+ mutex_unlock(&qd_lock);
+}
+
static int discard_stale(void)
{
struct work *work, *tmp;
- int i, stale = 0;
+ int stale = 0, nonclone = 0;
mutex_lock(stgd_lock);
HASH_ITER(hh, staged_work, work, tmp) {
@@ -2427,6 +2439,8 @@ static int discard_stale(void)
HASH_DEL(staged_work, work);
if (work->clone)
--staged_extras;
+ else
+ nonclone++;
discard_work(work);
stale++;
}
@@ -2436,8 +2450,7 @@ static int discard_stale(void)
applog(LOG_DEBUG, "Discarded %d stales that didn't match current hash", stale);
/* Dec queued outside the loop to not have recursive locks */
- for (i = 0; i < stale; i++)
- dec_queued();
+ subtract_queued(nonclone);
return stale;
}
@@ -3542,7 +3555,6 @@ static bool queue_request(struct thr_info *thr, bool needed)
wc = calloc(1, sizeof(*wc));
if (unlikely(!wc)) {
applog(LOG_ERR, "Failed to calloc wc in queue_request");
- dec_queued();
return false;
}
@@ -3564,7 +3576,6 @@ static bool queue_request(struct thr_info *thr, bool needed)
if (unlikely(!tq_push(thr_info[work_thr_id].q, wc))) {
applog(LOG_ERR, "Failed to tq_push in queue_request");
workio_cmd_free(wc);
- dec_queued();
return false;
}
@@ -3666,7 +3677,6 @@ static struct work *clone_work(struct work *work)
cloned = false;
break;
}
- inc_queued();
roll_work(work);
work_clone = make_clone(work);
/* Roll it again to prevent duplicates should this be used
@@ -3756,7 +3766,7 @@ retry:
}
if (stale_work(work_heap, false)) {
- dec_queued();
+ dec_queued(work_heap);
discard_work(work_heap);
goto retry;
}
@@ -3771,8 +3781,8 @@ retry:
work_heap = clone_work(work_heap);
memcpy(work, work_heap, sizeof(struct work));
+ dec_queued(work_heap);
free_work(work_heap);
- dec_queued();
ret = true;
out: