Browse Source

bitforce: Abandon (only) stale searches for work restarts

Luke Dashjr 13 years ago
parent
commit
ce644d736c
3 changed files with 72 additions and 12 deletions
  1. 18 4
      driver-bitforce.c
  2. 53 8
      miner.c
  3. 1 0
      miner.h

+ 18 - 4
driver-bitforce.c

@@ -331,6 +331,16 @@ re_send:
 	return true;
 }
 
+static inline int noisy_stale_wait(unsigned int mstime, struct work*work, bool checkend, struct cgpu_info*bitforce)
+{
+	int rv = stale_wait(mstime, work, checkend);
+	if (rv)
+		applog(LOG_NOTICE, "BFL%i: Abandoning stale search to restart after %ums",
+		       bitforce->device_id, bitforce->wait_ms);
+	return rv;
+}
+#define noisy_stale_wait(mstime, work, checkend)  noisy_stale_wait(mstime, work, checkend, bitforce)
+
 static int64_t bitforce_get_result(struct thr_info *thr, struct work *work)
 {
 	struct cgpu_info *bitforce = thr->cgpu;
@@ -354,7 +364,8 @@ static int64_t bitforce_get_result(struct thr_info *thr, struct work *work)
 
 		/* if BFL is throttling, no point checking so quickly */
 		delay_time_ms = (pdevbuf[0] ? BITFORCE_CHECK_INTERVAL_MS : 2 * WORK_CHECK_INTERVAL_MS);
-		nmsleep(delay_time_ms);
+		if (noisy_stale_wait(delay_time_ms, work, true))
+			return 0;
 		bitforce->wait_ms += delay_time_ms;
 	}
 
@@ -447,19 +458,22 @@ static int64_t bitforce_scanhash(struct thr_info *thr, struct work *work, int64_
 		/* Initially wait 2/3 of the average cycle time so we can request more
 		work before full scan is up */
 		sleep_time = (2 * bitforce->sleep_ms) / 3;
-		nmsleep(sleep_time);
+		if (noisy_stale_wait(sleep_time, work, true))
+			return 0;
 
 		bitforce->wait_ms = sleep_time;
 		queue_request(thr, false);
 
 		/* Now wait athe final 1/3rd; no bitforce should be finished by now */
 		sleep_time = bitforce->sleep_ms - sleep_time;
-		nmsleep(sleep_time);
+		if (noisy_stale_wait(sleep_time, work, true))
+			return 0;
 
 		bitforce->wait_ms += sleep_time;
 	} else {
 		sleep_time = bitforce->sleep_ms;
-		nmsleep(sleep_time);
+		if (noisy_stale_wait(sleep_time, work, true))
+			return 0;
 
 		bitforce->wait_ms = sleep_time;
 	}

+ 53 - 8
miner.c

@@ -2510,6 +2510,18 @@ static void discard_stale(void)
 
 bool queue_request(struct thr_info *thr, bool needed);
 
+void ms_to_abstime(unsigned int mstime, struct timespec *abstime)
+{
+	struct timeval now, then, tdiff;
+
+	tdiff.tv_sec = mstime / 1000;
+	tdiff.tv_usec = mstime * 1000 - (tdiff.tv_sec * 1000000);
+	gettimeofday(&now, NULL);
+	timeradd(&now, &tdiff, &then);
+	abstime->tv_sec = then.tv_sec;
+	abstime->tv_nsec = then.tv_usec * 1000;
+}
+
 /* A generic wait function for threads that poll that will wait a specified
  * time tdiff waiting on the pthread conditional that is broadcast when a
  * work restart is required. Returns the value of pthread_cond_timedwait
@@ -2517,23 +2529,56 @@ bool queue_request(struct thr_info *thr, bool needed);
  */
 int restart_wait(unsigned int mstime)
 {
-	struct timeval now, then, tdiff;
 	struct timespec abstime;
 	int rc;
 
-	tdiff.tv_sec = mstime / 1000;
-	tdiff.tv_usec = mstime * 1000 - (tdiff.tv_sec * 1000000);
-	gettimeofday(&now, NULL);
-	timeradd(&now, &tdiff, &then);
-	abstime.tv_sec = then.tv_sec;
-	abstime.tv_nsec = then.tv_usec * 1000;
-
+	ms_to_abstime(mstime, &abstime);
 	mutex_lock(&restart_lock);
 	rc = pthread_cond_timedwait(&restart_cond, &restart_lock, &abstime);
 	mutex_unlock(&restart_lock);
 
 	return rc;
 }
+
+/* A generic wait function for threads that poll that will wait a specified
+ * time waiting on a share to become stale. Returns positive if the share
+ * became stale or zero if the timer expired first. If checkend is true, will
+ * immediatley return negative if the share is guaranteed to become stale
+ * before the timer expires.
+ */
+int stale_wait(unsigned int mstime, struct work*work, bool checkend)
+{
+	struct timespec abstime;
+	int rc;
+
+	if (checkend) {
+		struct timeval tv, orig;
+		ldiv_t d;
+		d = ldiv(mstime, 1000);
+		tv.tv_sec = d.quot;
+		tv.tv_usec = d.rem * 1000;
+		orig = work->tv_staged;
+		timersub(&orig, &tv, &work->tv_staged);
+		rc = stale_work(work, true);
+		work->tv_staged = orig;
+		if (rc)
+			return -1;
+	}
+
+	ms_to_abstime(mstime, &abstime);
+	rc = -1;
+	while (1) {
+		mutex_lock(&restart_lock);
+		if (stale_work(work, true)) {
+			rc = 1;
+		} else if (pthread_cond_timedwait(&restart_cond, &restart_lock, &abstime)) {
+			rc = 0;
+		}
+		mutex_unlock(&restart_lock);
+		if (rc != -1)
+			return rc;
+	}
+}
 	
 static void restart_threads(void)
 {

+ 1 - 0
miner.h

@@ -579,6 +579,7 @@ extern pthread_cond_t restart_cond;
 extern void thread_reportin(struct thr_info *thr);
 extern bool queue_request(struct thr_info *thr, bool needed);
 extern int restart_wait(unsigned int mstime);
+extern int stale_wait(unsigned int mstime, struct work*, bool checkend);
 
 extern void kill_work(void);