diff --git a/cpu-miner.c b/cpu-miner.c index 652c35b..7cd6e74 100644 --- a/cpu-miner.c +++ b/cpu-miner.c @@ -90,6 +90,7 @@ static char *rpc_url; static char *userpass; static struct thr_info *thr_info; static int work_thr_id; +struct work_restart *work_restart = NULL; struct option_help { @@ -514,7 +515,7 @@ static void *miner_thread(void *userdata) /* scan nonces for a proof-of-work hash */ switch (opt_algo) { case ALGO_C: - rc = scanhash_c(work.midstate, work.data + 64, + rc = scanhash_c(thr_id, work.midstate, work.data + 64, work.hash1, work.hash, work.target, max_nonce, &hashes_done); break; @@ -522,7 +523,7 @@ static void *miner_thread(void *userdata) #ifdef WANT_X8664_SSE2 case ALGO_SSE2_64: { unsigned int rc5 = - scanhash_sse2_64(work.midstate, work.data + 64, + scanhash_sse2_64(thr_id, work.midstate, work.data + 64, work.hash1, work.hash, work.target, max_nonce, &hashes_done); @@ -534,7 +535,7 @@ static void *miner_thread(void *userdata) #ifdef WANT_SSE2_4WAY case ALGO_4WAY: { unsigned int rc4 = - ScanHash_4WaySSE2(work.midstate, work.data + 64, + ScanHash_4WaySSE2(thr_id, work.midstate, work.data + 64, work.hash1, work.hash, work.target, max_nonce, &hashes_done); @@ -545,19 +546,19 @@ static void *miner_thread(void *userdata) #ifdef WANT_VIA_PADLOCK case ALGO_VIA: - rc = scanhash_via(work.data, work.target, + rc = scanhash_via(thr_id, work.data, work.target, max_nonce, &hashes_done); break; #endif case ALGO_CRYPTOPP: - rc = scanhash_cryptopp(work.midstate, work.data + 64, + rc = scanhash_cryptopp(thr_id, work.midstate, work.data + 64, work.hash1, work.hash, work.target, max_nonce, &hashes_done); break; #ifdef WANT_CRYPTOPP_ASM32 case ALGO_CRYPTOPP_ASM32: - rc = scanhash_asm32(work.midstate, work.data + 64, + rc = scanhash_asm32(thr_id, work.midstate, work.data + 64, work.hash1, work.hash, work.target, max_nonce, &hashes_done); break; @@ -595,6 +596,14 @@ out: return NULL; } +void restart_threads(void) +{ + int i; + + for (i = 0; i < opt_n_threads; i++) + work_restart[i].restart = 1; +} + static void show_usage(void) { int i; @@ -761,6 +770,10 @@ int main (int argc, char *argv[]) if (!thr_info) return 1; + work_restart = calloc(opt_n_threads, sizeof(*work_restart)); + if (!work_restart) + return 1; + work_thr_id = opt_n_threads; thr = &thr_info[work_thr_id]; thr->id = opt_n_threads; diff --git a/miner.h b/miner.h index 52be480..6556f2a 100644 --- a/miner.h +++ b/miner.h @@ -74,33 +74,33 @@ extern json_t *json_rpc_call(CURL *curl, const char *url, const char *userpass, extern char *bin2hex(const unsigned char *p, size_t len); extern bool hex2bin(unsigned char *p, const char *hexstr, size_t len); -extern unsigned int ScanHash_4WaySSE2(const unsigned char *pmidstate, +extern unsigned int ScanHash_4WaySSE2(int, const unsigned char *pmidstate, unsigned char *pdata, unsigned char *phash1, unsigned char *phash, const unsigned char *ptarget, uint32_t max_nonce, unsigned long *nHashesDone); -extern unsigned int scanhash_sse2_amd64(const unsigned char *pmidstate, +extern unsigned int scanhash_sse2_amd64(int, const unsigned char *pmidstate, unsigned char *pdata, unsigned char *phash1, unsigned char *phash, const unsigned char *ptarget, uint32_t max_nonce, unsigned long *nHashesDone); -extern bool scanhash_via(unsigned char *data_inout, +extern bool scanhash_via(int, unsigned char *data_inout, const unsigned char *target, uint32_t max_nonce, unsigned long *hashes_done); -extern bool scanhash_c(const unsigned char *midstate, unsigned char *data, +extern bool scanhash_c(int, const unsigned char *midstate, unsigned char *data, unsigned char *hash1, unsigned char *hash, const unsigned char *target, uint32_t max_nonce, unsigned long *hashes_done); -extern bool scanhash_cryptopp(const unsigned char *midstate,unsigned char *data, +extern bool scanhash_cryptopp(int, const unsigned char *midstate,unsigned char *data, unsigned char *hash1, unsigned char *hash, const unsigned char *target, uint32_t max_nonce, unsigned long *hashes_done); -extern bool scanhash_asm32(const unsigned char *midstate,unsigned char *data, +extern bool scanhash_asm32(int, const unsigned char *midstate,unsigned char *data, unsigned char *hash1, unsigned char *hash, const unsigned char *target, uint32_t max_nonce, unsigned long *hashes_done); -extern int scanhash_sse2_64(const unsigned char *pmidstate, unsigned char *pdata, +extern int scanhash_sse2_64(int, const unsigned char *pmidstate, unsigned char *pdata, unsigned char *phash1, unsigned char *phash, const unsigned char *ptarget, uint32_t max_nonce, unsigned long *nHashesDone); @@ -112,6 +112,13 @@ extern bool fulltest(const unsigned char *hash, const unsigned char *target); struct thread_q; +struct work_restart { + volatile unsigned long restart; +}; + +extern struct work_restart *work_restart; +extern void restart_threads(void); + extern struct thread_q *tq_new(void); extern void tq_free(struct thread_q *tq); extern bool tq_push(struct thread_q *tq, void *data); diff --git a/sha256_4way.c b/sha256_4way.c index 742682f..6d42451 100644 --- a/sha256_4way.c +++ b/sha256_4way.c @@ -100,7 +100,8 @@ static const unsigned int pSHA256InitState[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; -unsigned int ScanHash_4WaySSE2(const unsigned char *pmidstate, unsigned char *pdata, +unsigned int ScanHash_4WaySSE2(int thr_id, const unsigned char *pmidstate, + unsigned char *pdata, unsigned char *phash1, unsigned char *phash, const unsigned char *ptarget, uint32_t max_nonce, unsigned long *nHashesDone) @@ -108,6 +109,8 @@ unsigned int ScanHash_4WaySSE2(const unsigned char *pmidstate, unsigned char *pd unsigned int *nNonce_p = (unsigned int*)(pdata + 12); unsigned int nonce = 0; + work_restart[thr_id].restart = 0; + for (;;) { unsigned int thash[9][NPAR] __attribute__((aligned(128))); @@ -135,7 +138,7 @@ unsigned int ScanHash_4WaySSE2(const unsigned char *pmidstate, unsigned char *pd } } - if (nonce >= max_nonce) + if ((nonce >= max_nonce) || work_restart[thr_id].restart) { *nHashesDone = nonce; return -1; diff --git a/sha256_cryptopp.c b/sha256_cryptopp.c index f5f8900..76e178c 100644 --- a/sha256_cryptopp.c +++ b/sha256_cryptopp.c @@ -91,7 +91,8 @@ static void runhash(void *state, const void *input, const void *init) } /* suspiciously similar to ScanHash* from bitcoin */ -bool scanhash_cryptopp(const unsigned char *midstate, unsigned char *data, +bool scanhash_cryptopp(int thr_id, const unsigned char *midstate, + unsigned char *data, unsigned char *hash1, unsigned char *hash, const unsigned char *target, uint32_t max_nonce, unsigned long *hashes_done) @@ -101,6 +102,8 @@ bool scanhash_cryptopp(const unsigned char *midstate, unsigned char *data, uint32_t n = 0; unsigned long stat_ctr = 0; + work_restart[thr_id].restart = 0; + while (1) { n++; *nonce = n; @@ -115,7 +118,7 @@ bool scanhash_cryptopp(const unsigned char *midstate, unsigned char *data, return true; } - if (n >= max_nonce) { + if ((n >= max_nonce) || work_restart[thr_id].restart) { *hashes_done = stat_ctr; return false; } @@ -573,7 +576,8 @@ static void runhash32(void *state, const void *input, const void *init) } /* suspiciously similar to ScanHash* from bitcoin */ -bool scanhash_asm32(const unsigned char *midstate, unsigned char *data, +bool scanhash_asm32(int thr_id, const unsigned char *midstate, + unsigned char *data, unsigned char *hash1, unsigned char *hash, const unsigned char *target, uint32_t max_nonce, unsigned long *hashes_done) @@ -583,6 +587,8 @@ bool scanhash_asm32(const unsigned char *midstate, unsigned char *data, uint32_t n = 0; unsigned long stat_ctr = 0; + work_restart[thr_id].restart = 0; + while (1) { n++; *nonce = n; @@ -599,7 +605,7 @@ bool scanhash_asm32(const unsigned char *midstate, unsigned char *data, return true; } - if (n >= max_nonce) { + if ((n >= max_nonce) || work_restart[thr_id].restart) { if (opt_debug) fprintf(stderr, "DBG: end of nonce range\n"); *hashes_done = stat_ctr; diff --git a/sha256_generic.c b/sha256_generic.c index 596a6db..b30b326 100644 --- a/sha256_generic.c +++ b/sha256_generic.c @@ -237,7 +237,7 @@ const uint32_t sha256_init_state[8] = { }; /* suspiciously similar to ScanHash* from bitcoin */ -bool scanhash_c(const unsigned char *midstate, unsigned char *data, +bool scanhash_c(int thr_id, const unsigned char *midstate, unsigned char *data, unsigned char *hash1, unsigned char *hash, const unsigned char *target, uint32_t max_nonce, unsigned long *hashes_done) @@ -247,6 +247,8 @@ bool scanhash_c(const unsigned char *midstate, unsigned char *data, uint32_t n = 0; unsigned long stat_ctr = 0; + work_restart[thr_id].restart = 0; + while (1) { n++; *nonce = n; @@ -261,7 +263,7 @@ bool scanhash_c(const unsigned char *midstate, unsigned char *data, return true; } - if (n >= max_nonce) { + if ((n >= max_nonce) || work_restart[thr_id].restart) { *hashes_done = stat_ctr; return false; } diff --git a/sha256_sse2_amd64.c b/sha256_sse2_amd64.c index 03a8323..d97d888 100644 --- a/sha256_sse2_amd64.c +++ b/sha256_sse2_amd64.c @@ -47,7 +47,8 @@ uint32_t g_sha256_hinit[8] = __m128i g_4sha256_k[64]; -int scanhash_sse2_64(const unsigned char *pmidstate, unsigned char *pdata, +int scanhash_sse2_64(int thr_id, const unsigned char *pmidstate, + unsigned char *pdata, unsigned char *phash1, unsigned char *phash, const unsigned char *ptarget, uint32_t max_nonce, unsigned long *nHashesDone) @@ -59,6 +60,8 @@ int scanhash_sse2_64(const unsigned char *pmidstate, unsigned char *pdata, __m128i offset; int i; + work_restart[thr_id].restart = 0; + /* For debugging */ union { __m128i m; @@ -116,7 +119,7 @@ int scanhash_sse2_64(const unsigned char *pmidstate, unsigned char *pdata, nonce += 4; - if (nonce >= max_nonce) + if ((nonce >= max_nonce) || work_restart[thr_id].restart) { *nHashesDone = nonce; return -1; diff --git a/sha256_via.c b/sha256_via.c index 186007e..158e757 100644 --- a/sha256_via.c +++ b/sha256_via.c @@ -17,7 +17,7 @@ static void via_sha256(void *hash, void *buf, unsigned len) :"memory"); } -bool scanhash_via(unsigned char *data_inout, +bool scanhash_via(int thr_id, unsigned char *data_inout, const unsigned char *target, uint32_t max_nonce, unsigned long *hashes_done) { @@ -31,6 +31,8 @@ bool scanhash_via(unsigned char *data_inout, unsigned long stat_ctr = 0; int i; + work_restart[thr_id].restart = 0; + /* bitcoin gives us big endian input, but via wants LE, * so we reverse the swapping bitcoin has already done (extra work) * in order to permit the hardware to swap everything @@ -70,7 +72,7 @@ bool scanhash_via(unsigned char *data_inout, return true; } - if (n >= max_nonce) { + if ((n >= max_nonce) || work_restart[thr_id].restart) { *hashes_done = stat_ctr; return false; }