Commit cc0ad5eaa7635d095cf6ba69305857fe534ba33b

Paul Sheppard 2012-07-01T23:35:06

Merge branch 'master' of git://github.com/ckolivas/cgminer.git Conflicts: driver-bitforce.c

diff --git a/cgminer.c b/cgminer.c
index 0654a1d..f37fa03 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -174,6 +174,9 @@ pthread_rwlock_t netacc_lock;
 static pthread_mutex_t lp_lock;
 static pthread_cond_t lp_cond;
 
+pthread_mutex_t restart_lock;
+pthread_cond_t restart_cond;
+
 double total_mhashes_done;
 static struct timeval total_tv_start, total_tv_end;
 
@@ -2472,8 +2475,29 @@ static void discard_stale(void)
 	subtract_queued(nonclone);
 }
 
-static bool queue_request(struct thr_info *thr, bool needed);
+bool queue_request(struct thr_info *thr, bool needed);
 
+/* 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
+ * which is zero if the condition was met or ETIMEDOUT if not.
+ */
+int restart_wait(struct timeval *tdiff)
+{
+	struct timeval now, then;
+	struct timespec abstime;
+	int rc;
+
+	gettimeofday(&now, NULL);
+	timeradd(&now, tdiff, &then);
+	abstime.tv_sec = then.tv_sec;
+	abstime.tv_nsec = then.tv_usec * 1000;
+	mutex_lock(&restart_lock);
+	rc = pthread_cond_timedwait(&restart_cond, &restart_lock, &abstime);
+	mutex_unlock(&restart_lock);
+	return rc;
+}
+	
 static void restart_threads(void)
 {
 	int i;
@@ -2485,6 +2509,10 @@ static void restart_threads(void)
 
 	for (i = 0; i < mining_threads; i++)
 		work_restart[i].restart = 1;
+
+	mutex_lock(&restart_lock);
+	pthread_cond_broadcast(&restart_cond);
+	mutex_unlock(&restart_lock);
 }
 
 static void set_curblock(char *hexstr, unsigned char *hash)
@@ -3564,7 +3592,7 @@ static void control_tclear(bool *var)
 
 static bool queueing;
 
-static bool queue_request(struct thr_info *thr, bool needed)
+bool queue_request(struct thr_info *thr, bool needed)
 {
 	struct workio_cmd *wc;
 	struct timeval now;
@@ -5010,6 +5038,10 @@ int main(int argc, char *argv[])
 	if (unlikely(pthread_cond_init(&lp_cond, NULL)))
 		quit(1, "Failed to pthread_cond_init lp_cond");
 
+	mutex_init(&restart_lock);
+	if (unlikely(pthread_cond_init(&restart_cond, NULL)))
+		quit(1, "Failed to pthread_cond_init restart_cond");
+
 	sprintf(packagename, "%s %s", PACKAGE, VERSION);
 
 #ifdef WANT_CPUMINE
diff --git a/configure.ac b/configure.ac
index 26e53e0..fed1a50 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
 ##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
 m4_define([v_maj], [2])
 m4_define([v_min], [4])
-m4_define([v_mic], [3])
+m4_define([v_mic], [4])
 ##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
 m4_define([v_ver], [v_maj.v_min.v_mic])
 m4_define([lt_rev], m4_eval(v_maj + v_min))
diff --git a/driver-bitforce.c b/driver-bitforce.c
index 8f21a3e..eb49be4 100644
--- a/driver-bitforce.c
+++ b/driver-bitforce.c
@@ -20,7 +20,7 @@
 #include "fpgautils.h"
 #include "miner.h"
 
-#define BITFORCE_SLEEP_MS 2000
+#define BITFORCE_SLEEP_MS 3000
 #define BITFORCE_TIMEOUT_MS 10000
 #define BITFORCE_CHECK_INTERVAL_MS 10
 #define WORK_CHECK_INTERVAL_MS 50
@@ -43,10 +43,8 @@ static ssize_t BFwrite(int fd, const void *buf, ssize_t bufLen)
 	if ((bufLen) != write(fd, buf, bufLen)) {
 		applog(LOG_ERR, "BFL: Error writing: %s", buf); 
 		return 0;
-	} else {
-		usleep(100);
+	} else
 		return bufLen;
-	}
 }
 
 #define BFclose(fd) close(fd)
@@ -297,6 +295,8 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work)
 		return 0;
 
 	while (bitforce->wait_ms < BITFORCE_TIMEOUT_MS) {
+		if (unlikely(work_restart[thr->id].restart))
+			return 1;
 		mutex_lock(&bitforce->device_mutex);
 		BFwrite(fdDev, "ZFX", 3);
 		BFgets(pdevbuf, sizeof(pdevbuf), fdDev);
@@ -371,10 +371,30 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6
 {
 	struct cgpu_info *bitforce = thr->cgpu;
 	uint64_t ret;
+	struct timeval tdiff;
+	unsigned int sleep_time;
 
 	bitforce->wait_ms = 0;
 	ret = bitforce_send_work(thr, work);
 
+	/* 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;
+	tdiff.tv_sec = sleep_time/1000;
+	tdiff.tv_usec = sleep_time*1000 - (tdiff.tv_sec * 1000000);
+	if (!restart_wait(&tdiff))
+		return 1;
+	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;
+	tdiff.tv_sec = sleep_time/1000;
+	tdiff.tv_usec = sleep_time*1000 - (tdiff.tv_sec * 1000000);
+	if (!restart_wait(&tdiff))
+		return 1;
+	bitforce->wait_ms += sleep_time;
+/*
 	while (bitforce->wait_ms < bitforce->sleep_ms) {
 		usleep(WORK_CHECK_INTERVAL_MS*1000);
 		bitforce->wait_ms += WORK_CHECK_INTERVAL_MS;
@@ -383,7 +403,7 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6
 			return 1; //we have discarded all work; equivilent to 0 hashes done.
 		}
 	}
-
+*/
 	if (ret)
 		ret = bitforce_get_result(thr, work);
 
diff --git a/miner.h b/miner.h
index 8d9ef2f..88c0392 100644
--- a/miner.h
+++ b/miner.h
@@ -570,7 +570,12 @@ struct work_restart {
 	char			padding[128 - sizeof(unsigned long)];
 };
 
+extern pthread_mutex_t restart_lock;
+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(struct timeval *tdiff);
 
 extern void kill_work(void);