diff --git a/cgminer.c b/cgminer.c index 0654a1da..f37fa038 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 26e53e0a..fed1a501 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 8f21a3e6..eb49be46 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 8d9ef2f3..88c03927 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);