Browse Source

erupter: Continue searching a job until the end, even if an earlier result is found

Luke Dashjr 12 years ago
parent
commit
e15dfb37be
4 changed files with 32 additions and 9 deletions
  1. 1 0
      driver-erupter.c
  2. 21 9
      driver-icarus.c
  3. 1 0
      icarus-common.h
  4. 9 0
      util.h

+ 1 - 0
driver-erupter.c

@@ -29,6 +29,7 @@ static bool _erupter_detect_one(const char *devpath, struct device_drv *drv)
 		.baud = ERUPTER_IO_SPEED,
 		.Hs = ERUPTER_HASH_TIME,
 		.timing_mode = MODE_DEFAULT,
+		.continue_search = true,
 	};
 
 	if (!icarus_detect_custom(devpath, drv, info)) {

+ 21 - 9
driver-icarus.c

@@ -898,7 +898,7 @@ static int64_t icarus_scanhash(struct thr_info *thr, struct work *work,
 	struct timeval tv_history_start, tv_history_finish;
 	double Ti, Xi;
 	int i;
-	bool was_hw_error;
+	bool was_hw_error = false;
 	bool was_first_run;
 
 	struct ICARUS_HISTORY *history0, *history;
@@ -929,9 +929,10 @@ static int64_t icarus_scanhash(struct thr_info *thr, struct work *work,
 		}
 		else
 		{
+			read_count = info->read_count;
 keepwaiting:
 			/* Icarus will return 4 bytes (ICARUS_READ_SIZE) nonces or nothing */
-			ret = icarus_gets((void*)&nonce, fd, &state->tv_workfinish, thr, info->read_count);
+			ret = icarus_gets((void*)&nonce, fd, &state->tv_workfinish, thr, read_count);
 			switch (ret) {
 				case ICA_GETS_RESTART:
 					// The prepared work is invalid, and the current work is abandoned
@@ -973,16 +974,27 @@ keepwaiting:
 	if (ret == ICA_GETS_OK)
 	{
 		nonce_work = icarus_process_worknonce(state, &nonce);
-		if (nonce_work == state->last2_work)
+		if (likely(nonce_work))
 		{
-			// nonce was for the last job; submit and keep processing the current one
-			submit_nonce(thr, nonce_work, nonce);
-			goto keepwaiting;
+			if (nonce_work == state->last2_work)
+			{
+				// nonce was for the last job; submit and keep processing the current one
+				submit_nonce(thr, nonce_work, nonce);
+				goto keepwaiting;
+			}
+			if (info->continue_search)
+			{
+				read_count = info->read_count - ((timer_elapsed_us(&state->tv_workstart, NULL) / (1000000 / TIME_FACTOR)) + 1);
+				if (read_count)
+				{
+					submit_nonce(thr, nonce_work, nonce);
+					goto keepwaiting;
+				}
+			}
 		}
-		was_hw_error = (!nonce_work);
+		else
+			was_hw_error = true;
 	}
-	else
-		was_hw_error = false;
 	
 	// Handle dynamic clocking for "subclass" devices
 	// This needs to run before sending next job, since it hashes the command too

+ 1 - 0
icarus-common.h

@@ -83,6 +83,7 @@ struct ICARUS_INFO {
 	uint32_t nonce_mask;
 	bool quirk_reopen;
 	uint8_t user_set;
+	bool continue_search;
 
 	dclk_change_clock_func_t dclk_change_clock_func;
 	struct dclk_data dclk;

+ 9 - 0
util.h

@@ -335,6 +335,15 @@ const struct timeval *_bfg_nullisnow(const struct timeval *tvp, struct timeval *
 	return tvp_buf;
 }
 
+static inline
+long timer_elapsed_us(const struct timeval *tvp_timer, const struct timeval *tvp_now)
+{
+	struct timeval tv;
+	const struct timeval *_tvp_now = _bfg_nullisnow(tvp_now, &tv);
+	timersub(_tvp_now, tvp_timer, &tv);
+	return ((long)tv.tv_sec * 1000000) + tv.tv_usec;
+}
+
 static inline
 int timer_elapsed(const struct timeval *tvp_timer, const struct timeval *tvp_now)
 {