From 8959f8d0ae8f35d35cc193b7c1468c10fbec7b6e Mon Sep 17 00:00:00 2001 From: Kano Date: Fri, 5 Apr 2013 20:06:03 +1100 Subject: [PATCH 01/10] cgminer.c -S help to only say Icarus --- cgminer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cgminer.c b/cgminer.c index f2a9e43a..7779c9c7 100644 --- a/cgminer.c +++ b/cgminer.c @@ -1102,7 +1102,7 @@ static struct opt_table opt_config_table[] = { #ifdef USE_FPGA_SERIAL OPT_WITH_ARG("--scan-serial|-S", add_serial, NULL, NULL, - "Serial port to probe for FPGA Mining device"), + "Serial port to probe for Icarus FPGA Mining device"), #endif OPT_WITH_ARG("--scan-time|-s", set_int_0_to_9999, opt_show_intval, &opt_scantime, From c6ca12f08477ee094b123012f3db8d51bd50cc2a Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sat, 6 Apr 2013 11:21:55 +1100 Subject: [PATCH 02/10] Differentiate socket closed from socket error in recv_line. --- util.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/util.c b/util.c index 4428199f..5665f809 100644 --- a/util.c +++ b/util.c @@ -1038,11 +1038,16 @@ char *recv_line(struct pool *pool) mutex_lock(&pool->stratum_lock); do { char s[RBUFSIZE]; - size_t slen, n; + size_t slen; + ssize_t n; memset(s, 0, RBUFSIZE); n = recv(pool->sock, s, RECVSIZE, 0); - if (n < 1 && errno != EAGAIN && errno != EWOULDBLOCK) { + if (!n) { + applog(LOG_DEBUG, "Socket closed waiting in recv_line"); + break; + } + if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { applog(LOG_DEBUG, "Failed to recv sock in recv_line"); break; } From 7783ab56318f7f5b0c6c695e4664c0ddcd4ff3ae Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sat, 6 Apr 2013 13:01:42 +1100 Subject: [PATCH 03/10] Only get extra work in fill_queue if we don't have any unqueued work in the list. --- cgminer.c | 12 +++++++++--- miner.h | 1 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/cgminer.c b/cgminer.c index 8d5eaf7a..821d1641 100644 --- a/cgminer.c +++ b/cgminer.c @@ -5754,11 +5754,14 @@ static void fill_queue(struct thr_info *mythr, struct cgpu_info *cgpu, struct de { thread_reportout(mythr); do { - struct work *work = get_work(mythr, thr_id); + struct work *work; - work->device_diff = MIN(drv->max_diff, work->work_difficulty); wr_lock(&cgpu->qlock); - HASH_ADD_INT(cgpu->queued_work, id, work); + if (HASH_COUNT(cgpu->queued_work) == cgpu->queued_count) { + work = get_work(mythr, thr_id); + work->device_diff = MIN(drv->max_diff, work->work_difficulty); + HASH_ADD_INT(cgpu->queued_work, id, work); + } wr_unlock(&cgpu->qlock); /* The queue_full function should be used by the driver to * actually place work items on the physical device if it @@ -5778,6 +5781,7 @@ struct work *get_queued(struct cgpu_info *cgpu) HASH_ITER(hh, cgpu->queued_work, work, tmp) { if (!work->queued) { work->queued = true; + cgpu->queued_count++; ret = work; break; } @@ -5828,6 +5832,8 @@ struct work *find_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, void work_completed(struct cgpu_info *cgpu, struct work *work) { wr_lock(&cgpu->qlock); + if (work->queued) + cgpu->queued_count--; HASH_DEL(cgpu->queued_work, work); wr_unlock(&cgpu->qlock); free_work(work); diff --git a/miner.h b/miner.h index 68f17c7b..3e420fbd 100644 --- a/miner.h +++ b/miner.h @@ -527,6 +527,7 @@ struct cgpu_info { pthread_rwlock_t qlock; struct work *queued_work; + unsigned int queued_count; }; extern bool add_cgpu(struct cgpu_info*); From 1e14748c68e213b82abd67d47ee5025101696672 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sat, 6 Apr 2013 15:49:55 +1100 Subject: [PATCH 04/10] Small timeouts on select() instead of instant timeout increase reliability of socket reads and writes. --- util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util.c b/util.c index 5665f809..5497e7a8 100644 --- a/util.c +++ b/util.c @@ -912,7 +912,7 @@ static bool __stratum_send(struct pool *pool, char *s, ssize_t len) len++; while (len > 0 ) { - struct timeval timeout = {0, 0}; + struct timeval timeout = {1, 0}; ssize_t sent; fd_set wd; @@ -966,7 +966,7 @@ static bool socket_full(struct pool *pool, bool wait) if (wait) timeout.tv_sec = 60; else - timeout.tv_sec = 0; + timeout.tv_sec = 1; if (select(sock + 1, &rd, NULL, NULL, &timeout) > 0) return true; return false; From 23c02415acfbdf0268292ae0875f2f017795caf0 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 5 Apr 2013 11:53:18 +1100 Subject: [PATCH 05/10] Bump version to 2.11.4 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 441dfb13..b2b45e43 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ ##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## m4_define([v_maj], [2]) m4_define([v_min], [11]) -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)) From d86f7b774177ac15cca6720510f733540b406974 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 7 Apr 2013 01:46:16 +1100 Subject: [PATCH 06/10] Fix warning with no curses built in. --- cgminer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cgminer.c b/cgminer.c index 821d1641..2c49aa3b 100644 --- a/cgminer.c +++ b/cgminer.c @@ -2299,12 +2299,14 @@ static void enable_pool(struct pool *pool) } } +#ifdef HAVE_CURSES static void disable_pool(struct pool *pool) { if (pool->enabled == POOL_ENABLED) enabled_pools--; pool->enabled = POOL_DISABLED; } +#endif static void reject_pool(struct pool *pool) { From b7b5b9ded2d9884c2fd680f5cddc3e9970c4c53d Mon Sep 17 00:00:00 2001 From: Kano Date: Sun, 7 Apr 2013 07:46:45 +1000 Subject: [PATCH 07/10] usbutils more stats for bflsc --- usbutils.c | 4 ++++ usbutils.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/usbutils.c b/usbutils.c index 69bd72ec..6b214c82 100644 --- a/usbutils.c +++ b/usbutils.c @@ -294,6 +294,8 @@ static const char *C_REQUESTQUEJOB_S = "RequestQueJob"; static const char *C_REQUESTQUEJOBSTATUS_S = "RequestQueJobStatus"; static const char *C_QUEJOB_S = "QueJob"; static const char *C_QUEJOBSTATUS_S = "QueJobStatus"; +static const char *C_QUEFLUSH_S = "QueFlush"; +static const char *C_QUEFLUSHREPLY_S = "QueFlushReply"; #ifdef EOL #undef EOL @@ -759,6 +761,8 @@ static void cgusb_check_init() usb_commands[C_REQUESTQUEJOBSTATUS] = C_REQUESTQUEJOBSTATUS_S; usb_commands[C_QUEJOB] = C_QUEJOB_S; usb_commands[C_QUEJOBSTATUS] = C_QUEJOBSTATUS_S; + usb_commands[C_QUEFLUSH] = C_QUEFLUSH_S; + usb_commands[C_QUEFLUSHREPLY] = C_QUEFLUSHREPLY_S; stats_initialised = true; } diff --git a/usbutils.h b/usbutils.h index 8e34d817..db279ce0 100644 --- a/usbutils.h +++ b/usbutils.h @@ -131,6 +131,8 @@ enum usb_cmds { C_REQUESTQUEJOBSTATUS, C_QUEJOB, C_QUEJOBSTATUS, + C_QUEFLUSH, + C_QUEFLUSHREPLY, C_MAX }; From 220eb85818ec569297d306625bd3a6a8445fa304 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Mon, 8 Apr 2013 21:26:10 +1000 Subject: [PATCH 08/10] Rationalise and simplify the share diff and block solve detection to a common site. --- cgminer.c | 119 ++++++++++++++++-------------------------------------- miner.h | 3 +- 2 files changed, 37 insertions(+), 85 deletions(-) diff --git a/cgminer.c b/cgminer.c index 2c49aa3b..b5f47dda 100644 --- a/cgminer.c +++ b/cgminer.c @@ -238,7 +238,7 @@ static char datestamp[40]; static char blocktime[32]; struct timeval block_timeval; static char best_share[8] = "0"; -double current_diff; +double current_diff = 0xFFFFFFFFFFFFFFFF; static char block_diff[8]; uint64_t best_diff = 0; @@ -2245,52 +2245,6 @@ void clear_logwin(void) } #endif -/* Returns true if the regenerated work->hash solves a block */ -static bool solves_block(const struct work *work) -{ - uint32_t *hash32 = (uint32_t *)(work->hash); - uint32_t difficulty = 0; - uint32_t diffbytes = 0; - uint32_t diffvalue = 0; - uint32_t diffcmp[8]; - int diffshift = 0; - int i; - - difficulty = swab32(*((uint32_t *)(work->data + 72))); - - diffbytes = ((difficulty >> 24) & 0xff) - 3; - diffvalue = difficulty & 0x00ffffff; - - diffshift = (diffbytes % 4) * 8; - if (diffshift == 0) { - diffshift = 32; - diffbytes--; - } - - memset(diffcmp, 0, 32); - diffbytes >>= 2; - /* Sanity check looking for overflow */ - if (unlikely(diffbytes > 6)) - return false; - diffcmp[diffbytes + 1] = diffvalue >> (32 - diffshift); - diffcmp[diffbytes] = diffvalue << diffshift; - - for (i = 7; i >= 0; i--) { - if (hash32[i] > diffcmp[i]) - return false; - if (hash32[i] < diffcmp[i]) - return true; - } - - // https://en.bitcoin.it/wiki/Block says: "numerically below" - // https://en.bitcoin.it/wiki/Target says: "lower than or equal to" - // code in bitcoind 0.3.24 main.cpp CheckWork() says: if (hash > hashTarget) return false; - if (hash32[0] == diffcmp[0]) - return true; - else - return false; -} - static void enable_pool(struct pool *pool) { if (pool->enabled != POOL_ENABLED) { @@ -2440,34 +2394,6 @@ share_result(json_t *val, json_t *res, json_t *err, const struct work *work, } } -static const uint64_t diffone = 0xFFFF000000000000ull; - -static uint64_t share_diff(const struct work *work) -{ - uint64_t *data64, d64; - char rhash[32]; - uint64_t ret; - - swab256(rhash, work->hash); - if (opt_scrypt) - data64 = (uint64_t *)(rhash + 2); - else - data64 = (uint64_t *)(rhash + 4); - d64 = be64toh(*data64); - if (unlikely(!d64)) - d64 = 1; - ret = diffone / d64; - cg_wlock(&control_lock); - if (ret > best_diff) { - best_diff = ret; - suffix_string(best_diff, best_share, 0); - } - if (ret > work->pool->best_diff) - work->pool->best_diff = ret; - cg_wunlock(&control_lock); - return ret; -} - static bool submit_upstream_work(struct work *work, CURL *curl, bool resubmit) { char *hexstr = NULL; @@ -2562,15 +2488,13 @@ static bool submit_upstream_work(struct work *work, CURL *curl, bool resubmit) int intdiff = floor(work->work_difficulty); char diffdisp[16], *outhash; unsigned char rhash[32]; - uint64_t sharediff; swab256(rhash, work->hash); if (opt_scrypt) outhash = bin2hex(rhash + 2, 4); else outhash = bin2hex(rhash + 4, 4); - sharediff = share_diff(work); - suffix_string(sharediff, diffdisp, 0); + suffix_string(work->share_diff, diffdisp, 0); sprintf(hashshow, "%s Diff %s/%d%s", outhash, diffdisp, intdiff, work->block? " BLOCK!" : ""); free(outhash); @@ -2712,6 +2636,7 @@ static inline struct pool *select_pool(bool lagging) } static double DIFFEXACTONE = 26959946667150639794667015087019630673637144422540572481103610249215.0; +static const uint64_t diffone = 0xFFFF000000000000ull; /* * Calculate the work share difficulty @@ -3240,6 +3165,32 @@ static bool stale_work(struct work *work, bool share) return false; } +static uint64_t share_diff(const struct work *work) +{ + uint64_t *data64, d64; + char rhash[32]; + uint64_t ret; + + swab256(rhash, work->hash); + if (opt_scrypt) + data64 = (uint64_t *)(rhash + 2); + else + data64 = (uint64_t *)(rhash + 4); + d64 = be64toh(*data64); + if (unlikely(!d64)) + d64 = 1; + ret = diffone / d64; + cg_wlock(&control_lock); + if (ret > best_diff) { + best_diff = ret; + suffix_string(best_diff, best_share, 0); + } + if (ret > work->pool->best_diff) + work->pool->best_diff = ret; + cg_wunlock(&control_lock); + return ret; +} + static void regen_hash(struct work *work) { uint32_t *data32 = (uint32_t *)(work->data); @@ -3252,15 +3203,16 @@ static void regen_hash(struct work *work) sha2(hash1, 32, (unsigned char *)(work->hash)); } -static void check_solve(struct work *work) +static void rebuild_hash(struct work *work) { if (opt_scrypt) scrypt_outputhash(work); else regen_hash(work); - work->block = solves_block(work); - if (unlikely(work->block)) { + work->share_diff = share_diff(work); + if (unlikely(work->share_diff >= current_diff)) { + work->block = true; work->pool->solved++; found_blocks++; work->mandatory = true; @@ -3283,7 +3235,7 @@ static void *submit_work_thread(void *userdata) applog(LOG_DEBUG, "Creating extra submit work thread"); - check_solve(work); + rebuild_hash(work); if (stale_work(work, true)) { if (opt_submit_stale) @@ -4736,7 +4688,6 @@ static void stratum_share_result(json_t *val, json_t *res_val, json_t *err_val, struct stratum_share *sshare) { struct work *work = sshare->work; - uint64_t sharediff = share_diff(work); char hashshow[65]; uint32_t *hash32; char diffdisp[16]; @@ -4744,7 +4695,7 @@ static void stratum_share_result(json_t *val, json_t *res_val, json_t *err_val, hash32 = (uint32_t *)(work->hash); intdiff = floor(work->work_difficulty); - suffix_string(sharediff, diffdisp, 0); + suffix_string(work->share_diff, diffdisp, 0); sprintf(hashshow, "%08lx Diff %s/%d%s", (unsigned long)htole32(hash32[6]), diffdisp, intdiff, work->block? " BLOCK!" : ""); share_result(val, res_val, err_val, work, hashshow, false, ""); diff --git a/miner.h b/miner.h index 3e420fbd..5ab227f5 100644 --- a/miner.h +++ b/miner.h @@ -1108,7 +1108,8 @@ struct work { unsigned char target[32]; unsigned char hash[32]; - double device_diff; + double device_diff; + uint64_t share_diff; int rolls; From c1ec55a6a34cf3ee4c858bc71aebeb668726ade7 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Tue, 9 Apr 2013 07:08:09 +1000 Subject: [PATCH 09/10] Avoid curl_easy_cleanup on old curl versions in setup_stratum_curl as well. --- util.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/util.c b/util.c index 5497e7a8..b3cb9c03 100644 --- a/util.c +++ b/util.c @@ -1429,8 +1429,14 @@ static bool setup_stratum_curl(struct pool *pool) mutex_lock(&pool->stratum_lock); pool->stratum_active = false; - if (pool->stratum_curl) + if (pool->stratum_curl) { +#if CURL_HAS_KEEPALIVE curl_easy_cleanup(pool->stratum_curl); +#else + /* See above in suspend_stratum */ + CLOSESOCKET(pool->sock); +#endif + } pool->stratum_curl = curl_easy_init(); if (unlikely(!pool->stratum_curl)) quit(1, "Failed to curl_easy_init in initiate_stratum"); From 7231f7f92d8543c3205572d85601e96a03c58796 Mon Sep 17 00:00:00 2001 From: ckolivas Date: Wed, 10 Apr 2013 10:59:38 +1000 Subject: [PATCH 10/10] Fix warning on 32bit. --- cgminer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cgminer.c b/cgminer.c index b5f47dda..7816af3c 100644 --- a/cgminer.c +++ b/cgminer.c @@ -238,7 +238,7 @@ static char datestamp[40]; static char blocktime[32]; struct timeval block_timeval; static char best_share[8] = "0"; -double current_diff = 0xFFFFFFFFFFFFFFFF; +double current_diff = 0xFFFFFFFFFFFFFFFFULL; static char block_diff[8]; uint64_t best_diff = 0;