Merge branch 'master' of git://github.com/ckolivas/cgminer.git Conflicts: driver-bitforce.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
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);