Commit 757922e4ce88af4665ad8819a8e470941512d811

Con Kolivas 2012-06-25T00:33:47

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.

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: