Commit 6cc8d22beb85c3f9c4ddbc72e694b4e022e056c7

Con Kolivas 2011-07-27T14:53:43

Properly detect stale work based on time from staging and discard instead of handing on, but be more lax about how long work can be divided for up to the scantime.

diff --git a/main.c b/main.c
index 0510579..babadfb 100644
--- a/main.c
+++ b/main.c
@@ -1212,15 +1212,15 @@ static bool stale_work(struct work *work)
 	bool ret = false;
 	char *hexstr;
 
+	gettimeofday(&now, NULL);
+	if ((now.tv_sec - work->tv_staged.tv_sec) > opt_scantime)
+		return true;
+
 	/* Only use the primary pool for determination as the work may
 	 * interleave at times of new blocks */
 	if (work->pool != current_pool())
 		return ret;
 
-	gettimeofday(&now, NULL);
-	if ((now.tv_sec - work->tv_staged.tv_sec) > opt_scantime)
-		return ret;
-
 	hexstr = bin2hex(work->data, 36);
 	if (unlikely(!hexstr)) {
 		applog(LOG_ERR, "submit_work_thread OOM");
@@ -2203,12 +2203,24 @@ static bool queue_request(void)
 	return true;
 }
 
+static void discard_work(struct work *work)
+{
+	if (!work->clone) {
+		if (work->pool)
+			work->pool->discarded_work++;
+		total_discarded++;
+		if (opt_debug)
+			applog(LOG_DEBUG, "Discarded cloned work");
+	} else if (opt_debug)
+		applog(LOG_DEBUG, "Discarded work");
+	free(work);
+}
+
 static void discard_staged(void)
 {
 	struct timespec abstime = {};
 	struct timeval now;
 	struct work *work_heap;
-	struct pool *pool;
 
 	/* Just in case we fell in a hole and missed a queue filling */
 	if (unlikely(!requests_staged()))
@@ -2221,11 +2233,8 @@ static void discard_staged(void)
 	if (unlikely(!work_heap))
 		return;
 
-	pool = work_heap->pool;
-	free(work_heap);
+	discard_work(work_heap);
 	dec_queued();
-	pool->discarded_work++;
-	total_discarded++;
 }
 
 static void flush_requests(void)
@@ -2290,7 +2299,7 @@ static bool divide_work(struct timeval *now, struct work *work, uint32_t hash_di
 	if ((uint64_t)work->blk.nonce + hash_inc < MAXTHREADS) {
 		/* Don't keep handing it out if it's getting old, but try to
 		 * roll it instead */
-		if ((now->tv_sec - work->tv_staged.tv_sec) > opt_scantime * 2 / 3) {
+		if ((now->tv_sec - work->tv_staged.tv_sec) > opt_scantime) {
 			if (!can_roll(work))
 				return false;
 			else {
@@ -2369,6 +2378,11 @@ retry:
 		goto retry;
 	}
 
+	if (stale_work(work_heap)) {
+		discard_work(work_heap);
+		goto retry;
+	}
+
 	pool = work_heap->pool;
 	/* If we make it here we have succeeded in getting fresh work */
 	if (pool_tclear(pool, &pool->idle))