mirror of
https://github.com/GOSTSec/sgminer
synced 2025-01-08 22:08:02 +00:00
add support for setting algorithm/nfactor for each pool separately, and fix bugged OpenCL thread cleanup (thread shutdown)
This commit is contained in:
parent
9a2b9286e2
commit
c2131df6aa
@ -33,3 +33,8 @@ void set_algorithm_nfactor(algorithm_t* algo, const uint8_t nfactor) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool cmp_algorithm(algorithm_t* algo1, algorithm_t* algo2) {
|
||||
return (strcmp(algo1->name, algo2->name) == 0) &&
|
||||
(algo1->nfactor == algo2->nfactor);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define ALGORITHM_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/* Describes the Scrypt parameters and hashing functions used to mine
|
||||
* a specific coin.
|
||||
@ -18,4 +19,7 @@ void set_algorithm(algorithm_t* algo, const char* name);
|
||||
/* Set to specific N factor. */
|
||||
void set_algorithm_nfactor(algorithm_t* algo, const uint8_t nfactor);
|
||||
|
||||
/* Compare two algorithm parameters */
|
||||
bool cmp_algorithm(algorithm_t* algo1, algorithm_t* algo2);
|
||||
|
||||
#endif /* ALGORITHM_H */
|
||||
|
2
api.c
2
api.c
@ -2856,7 +2856,7 @@ static void minecoin(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __may
|
||||
message(io_data, MSG_MINECOIN, 0, NULL, isjson);
|
||||
io_open = io_add(io_data, isjson ? COMSTR JSON_MINECOIN : _MINECOIN COMSTR);
|
||||
|
||||
root = api_add_string(root, "Hash Method", algorithm->name, false);
|
||||
root = api_add_string(root, "Hash Method", get_devices(0)->algorithm.name, false);
|
||||
|
||||
cg_rlock(&ch_lock);
|
||||
root = api_add_timeval(root, "Current Block Time", &block_timeval, true);
|
||||
|
@ -23,6 +23,9 @@ cryptocurrencies.
|
||||
* everything else - currently defaults to `scrypt`, subject to change
|
||||
without warning.
|
||||
|
||||
### pool-algorithm
|
||||
|
||||
Allows choosing the algorithm for a specific pool. See `algorithm`.
|
||||
|
||||
### nfactor
|
||||
|
||||
@ -33,6 +36,9 @@ Overrides the default scrypt parameter N, specified as the factor of 2
|
||||
|
||||
*Default:* depends on `algorithm`; otherwise `10`.
|
||||
|
||||
### pool-nfactor
|
||||
|
||||
Overrides the default scrypt parameter N for a specific pool. See `nfactor`.
|
||||
|
||||
## CLI-only options
|
||||
|
||||
|
@ -1094,6 +1094,8 @@ select_cgpu:
|
||||
cgtime(&thr->sick);
|
||||
if (!pthread_cancel(thr->pth)) {
|
||||
applog(LOG_WARNING, "Thread %d still exists, killing it off", thr_id);
|
||||
pthread_join(thr->pth, NULL);
|
||||
thr->cgpu->drv->thread_shutdown(thr);
|
||||
} else
|
||||
applog(LOG_WARNING, "Thread %d no longer exists", thr_id);
|
||||
}
|
||||
@ -1120,7 +1122,7 @@ select_cgpu:
|
||||
//free(clState);
|
||||
|
||||
applog(LOG_INFO, "Reinit GPU thread %d", thr_id);
|
||||
clStates[thr_id] = initCl(virtual_gpu, name, sizeof(name));
|
||||
clStates[thr_id] = initCl(virtual_gpu, name, sizeof(name), &cgpu->algorithm);
|
||||
if (!clStates[thr_id]) {
|
||||
applog(LOG_ERR, "Failed to reinit GPU thread %d", thr_id);
|
||||
goto select_cgpu;
|
||||
@ -1186,6 +1188,7 @@ static void opencl_detect(bool hotplug)
|
||||
cgpu->threads = 1;
|
||||
#endif
|
||||
cgpu->virtual_gpu = i;
|
||||
cgpu->algorithm = *default_algorithm;
|
||||
add_cgpu(cgpu);
|
||||
}
|
||||
|
||||
@ -1261,7 +1264,7 @@ static bool opencl_thread_prepare(struct thr_info *thr)
|
||||
|
||||
strcpy(name, "");
|
||||
applog(LOG_INFO, "Init GPU thread %i GPU %i virtual GPU %i", i, gpu, virtual_gpu);
|
||||
clStates[i] = initCl(virtual_gpu, name, sizeof(name));
|
||||
clStates[i] = initCl(virtual_gpu, name, sizeof(name), &cgpu->algorithm);
|
||||
if (!clStates[i]) {
|
||||
#ifdef HAVE_CURSES
|
||||
if (use_curses)
|
||||
@ -1443,15 +1446,25 @@ static int64_t opencl_scanhash(struct thr_info *thr, struct work *work,
|
||||
return hashes;
|
||||
}
|
||||
|
||||
// Cleanup OpenCL memory on the GPU
|
||||
// Note: This function is not thread-safe (clStates modification not atomic)
|
||||
static void opencl_thread_shutdown(struct thr_info *thr)
|
||||
{
|
||||
const int thr_id = thr->id;
|
||||
_clState *clState = clStates[thr_id];
|
||||
clStates[thr_id] = NULL;
|
||||
|
||||
if (clState) {
|
||||
clFinish(clState->commandQueue);
|
||||
clReleaseMemObject(clState->outputBuffer);
|
||||
clReleaseMemObject(clState->CLbuffer0);
|
||||
clReleaseMemObject(clState->padbuffer8);
|
||||
clReleaseKernel(clState->kernel);
|
||||
clReleaseProgram(clState->program);
|
||||
clReleaseCommandQueue(clState->commandQueue);
|
||||
clReleaseContext(clState->context);
|
||||
free(clState);
|
||||
}
|
||||
}
|
||||
|
||||
struct device_drv opencl_drv = {
|
||||
|
8
miner.h
8
miner.h
@ -475,6 +475,7 @@ struct cgpu_info {
|
||||
cl_uint vwidth;
|
||||
size_t work_size;
|
||||
cl_ulong max_alloc;
|
||||
algorithm_t algorithm;
|
||||
|
||||
int opt_lg, lookup_gap;
|
||||
size_t opt_tc, thread_concurrency;
|
||||
@ -548,7 +549,6 @@ struct thread_q {
|
||||
struct thr_info {
|
||||
int id;
|
||||
int device_thread;
|
||||
bool primary_thread;
|
||||
|
||||
pthread_t pth;
|
||||
cgsem_t sem;
|
||||
@ -559,6 +559,7 @@ struct thr_info {
|
||||
struct timeval sick;
|
||||
|
||||
bool pause;
|
||||
bool paused;
|
||||
bool getwork;
|
||||
double rolling;
|
||||
|
||||
@ -1014,8 +1015,7 @@ extern int opt_queue;
|
||||
extern int opt_scantime;
|
||||
extern int opt_expiry;
|
||||
|
||||
extern char *opt_algorithm;
|
||||
extern algorithm_t *algorithm;
|
||||
extern algorithm_t *default_algorithm;
|
||||
|
||||
extern cglock_t control_lock;
|
||||
extern pthread_mutex_t hash_lock;
|
||||
@ -1219,6 +1219,8 @@ struct pool {
|
||||
proxytypes_t rpc_proxytype;
|
||||
char *rpc_proxy;
|
||||
|
||||
algorithm_t algorithm;
|
||||
|
||||
pthread_mutex_t pool_lock;
|
||||
cglock_t data_lock;
|
||||
|
||||
|
8
ocl.c
8
ocl.c
@ -31,6 +31,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "findnonce.h"
|
||||
#include "algorithm.h"
|
||||
#include "ocl.h"
|
||||
|
||||
/* FIXME: only here for global config vars, replace with configuration.h
|
||||
@ -218,7 +219,7 @@ void patch_opcodes(char *w, unsigned remaining)
|
||||
applog(LOG_DEBUG, "Patched a total of %i BFI_INT instructions", patched);
|
||||
}
|
||||
|
||||
_clState *initCl(unsigned int gpu, char *name, size_t nameSize)
|
||||
_clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *algorithm)
|
||||
{
|
||||
_clState *clState = (_clState *)calloc(1, sizeof(_clState));
|
||||
bool patchbfi = false, prog_built = false;
|
||||
@ -732,8 +733,9 @@ built:
|
||||
free(binaries);
|
||||
free(binary_sizes);
|
||||
|
||||
applog(LOG_NOTICE, "Initialising kernel %s with%s bitalign, %spatched BFI",
|
||||
filename, clState->hasBitAlign ? "" : "out", patchbfi ? "" : "un");
|
||||
applog(LOG_NOTICE, "Initialising kernel %s with%s bitalign, %spatched BFI, nfactor %d, n %d",
|
||||
filename, clState->hasBitAlign ? "" : "out", patchbfi ? "" : "un",
|
||||
algorithm->nfactor, algorithm->n);
|
||||
|
||||
if (!prog_built) {
|
||||
/* create a cl program executable for all the devices specified */
|
||||
|
2
ocl.h
2
ocl.h
@ -34,5 +34,5 @@ typedef struct {
|
||||
|
||||
extern char *file_contents(const char *filename, int *length);
|
||||
extern int clDevicesNum(void);
|
||||
extern _clState *initCl(unsigned int gpu, char *name, size_t nameSize);
|
||||
extern _clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *algorithm);
|
||||
#endif /* __OCL_H__ */
|
||||
|
88
scrypt.c
88
scrypt.c
@ -358,7 +358,7 @@ salsa20_8(uint32_t B[16], const uint32_t Bx[16])
|
||||
* scratchpad size needs to be at least (bytes):
|
||||
* 63 + (128 * r * p) + (256 * r + 64) + (128 * r * N)
|
||||
*/
|
||||
static void scrypt_n_1_1_256_sp(const uint32_t* input, char* scratchpad, uint32_t *ostate)
|
||||
static void scrypt_n_1_1_256_sp(const uint32_t* input, char* scratchpad, uint32_t *ostate, uint32_t n)
|
||||
{
|
||||
uint32_t * V;
|
||||
uint32_t X[32];
|
||||
@ -372,7 +372,7 @@ static void scrypt_n_1_1_256_sp(const uint32_t* input, char* scratchpad, uint32_
|
||||
|
||||
PBKDF2_SHA256_80_128(input, X);
|
||||
|
||||
for (i = 0; i < algorithm->n; i += 2) {
|
||||
for (i = 0; i < n; i += 2) {
|
||||
memcpy(&V[i * 32], X, 128);
|
||||
|
||||
salsa20_8(&X[0], &X[16]);
|
||||
@ -383,8 +383,8 @@ static void scrypt_n_1_1_256_sp(const uint32_t* input, char* scratchpad, uint32_
|
||||
salsa20_8(&X[0], &X[16]);
|
||||
salsa20_8(&X[16], &X[0]);
|
||||
}
|
||||
for (i = 0; i < algorithm->n; i += 2) {
|
||||
j = X[16] & (algorithm->n-1);
|
||||
for (i = 0; i < n; i += 2) {
|
||||
j = X[16] & (n-1);
|
||||
p2 = (uint64_t *)(&V[j * 32]);
|
||||
for(k = 0; k < 16; k++)
|
||||
p1[k] ^= p2[k];
|
||||
@ -392,7 +392,7 @@ static void scrypt_n_1_1_256_sp(const uint32_t* input, char* scratchpad, uint32_
|
||||
salsa20_8(&X[0], &X[16]);
|
||||
salsa20_8(&X[16], &X[0]);
|
||||
|
||||
j = X[16] & (algorithm->n-1);
|
||||
j = X[16] & (n-1);
|
||||
p2 = (uint64_t *)(&V[j * 32]);
|
||||
for(k = 0; k < 16; k++)
|
||||
p1[k] ^= p2[k];
|
||||
@ -404,7 +404,7 @@ static void scrypt_n_1_1_256_sp(const uint32_t* input, char* scratchpad, uint32_
|
||||
PBKDF2_SHA256_80_128_32(input, X, ostate);
|
||||
}
|
||||
|
||||
void scrypt_regenhash(struct work *work)
|
||||
void scrypt_regenhash(struct work *work, uint32_t n)
|
||||
{
|
||||
uint32_t data[20];
|
||||
char *scratchbuf;
|
||||
@ -414,81 +414,9 @@ void scrypt_regenhash(struct work *work)
|
||||
be32enc_vect(data, (const uint32_t *)work->data, 19);
|
||||
data[19] = htobe32(*nonce);
|
||||
|
||||
scratchbuf = (char *)alloca(algorithm->n * 128 + 512);
|
||||
scrypt_n_1_1_256_sp(data, scratchbuf, ohash);
|
||||
scratchbuf = (char *)alloca(n * 128 + 512);
|
||||
scrypt_n_1_1_256_sp(data, scratchbuf, ohash, n);
|
||||
flip32(ohash, ohash);
|
||||
}
|
||||
|
||||
static const uint32_t diff1targ = 0x0000ffff;
|
||||
|
||||
/* Used externally as confirmation of correct OCL code */
|
||||
/* FIXME: find reference in git blame and see why it was present, remove if obsolete */
|
||||
/*
|
||||
int scrypt_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce)
|
||||
{
|
||||
uint32_t tmp_hash7, Htarg = le32toh(((const uint32_t *)ptarget)[7]);
|
||||
uint32_t data[20], ohash[8];
|
||||
char *scratchbuf;
|
||||
|
||||
be32enc_vect(data, (const uint32_t *)pdata, 19);
|
||||
data[19] = htobe32(nonce);
|
||||
scratchbuf = (char *)alloca(SCRATCHBUF_SIZE);
|
||||
scrypt_n_1_1_256_sp(data, scratchbuf, ohash, algorithm->n);
|
||||
tmp_hash7 = be32toh(ohash[7]);
|
||||
|
||||
applog(LOG_DEBUG, "htarget %08lx diff1 %08lx hash %08lx",
|
||||
(long unsigned int)Htarg,
|
||||
(long unsigned int)diff1targ,
|
||||
(long unsigned int)tmp_hash7);
|
||||
if (tmp_hash7 > diff1targ)
|
||||
return -1;
|
||||
if (tmp_hash7 > Htarg)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool scanhash_scrypt(struct thr_info *thr, const unsigned char __maybe_unused *pmidstate,
|
||||
unsigned char *pdata, unsigned char __maybe_unused *phash1,
|
||||
unsigned char __maybe_unused *phash, const unsigned char *ptarget,
|
||||
uint32_t max_nonce, uint32_t *last_nonce, uint32_t n)
|
||||
{
|
||||
uint32_t *nonce = (uint32_t *)(pdata + 76);
|
||||
char *scratchbuf;
|
||||
uint32_t data[20];
|
||||
uint32_t tmp_hash7;
|
||||
uint32_t Htarg = le32toh(((const uint32_t *)ptarget)[7]);
|
||||
bool ret = false;
|
||||
|
||||
be32enc_vect(data, (const uint32_t *)pdata, 19);
|
||||
|
||||
scratchbuf = (char *)malloc(SCRATCHBUF_SIZE);
|
||||
if (unlikely(!scratchbuf)) {
|
||||
applog(LOG_ERR, "Failed to malloc scratchbuf in scanhash_scrypt");
|
||||
return ret;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
uint32_t ostate[8];
|
||||
|
||||
*nonce = ++n;
|
||||
data[19] = htobe32(n);
|
||||
scrypt_n_1_1_256_sp(data, scratchbuf, ostate, algorithm->n);
|
||||
tmp_hash7 = be32toh(ostate[7]);
|
||||
|
||||
if (unlikely(tmp_hash7 <= Htarg)) {
|
||||
((uint32_t *)pdata)[19] = htobe32(n);
|
||||
*last_nonce = n;
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (unlikely((n >= max_nonce) || thr->work_restart)) {
|
||||
*last_nonce = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(scratchbuf);;
|
||||
return ret;
|
||||
}
|
||||
*/
|
||||
|
2
scrypt.h
2
scrypt.h
@ -5,6 +5,6 @@
|
||||
|
||||
/* extern int scrypt_test(unsigned char *pdata, const unsigned char *ptarget, */
|
||||
/* uint32_t nonce); */
|
||||
extern void scrypt_regenhash(struct work *work);
|
||||
extern void scrypt_regenhash(struct work *work, uint32_t n);
|
||||
|
||||
#endif /* SCRYPT_H */
|
||||
|
134
sgminer.c
134
sgminer.c
@ -98,8 +98,7 @@ int opt_queue = 1;
|
||||
int opt_scantime = 7;
|
||||
int opt_expiry = 28;
|
||||
|
||||
char *opt_algorithm;
|
||||
algorithm_t *algorithm;
|
||||
algorithm_t *default_algorithm;
|
||||
|
||||
static const bool opt_time = true;
|
||||
unsigned long long global_hashrate;
|
||||
@ -199,6 +198,9 @@ pthread_rwlock_t devices_lock;
|
||||
static pthread_mutex_t lp_lock;
|
||||
static pthread_cond_t lp_cond;
|
||||
|
||||
static pthread_mutex_t algo_switch_lock;
|
||||
static pthread_t algo_switch_thr = 0;
|
||||
|
||||
pthread_mutex_t restart_lock;
|
||||
pthread_cond_t restart_cond;
|
||||
|
||||
@ -536,6 +538,9 @@ struct pool *add_pool(void)
|
||||
buf[0] = '\0';
|
||||
pool->name = strdup(buf);
|
||||
|
||||
/* Algorithm */
|
||||
pool->algorithm = *default_algorithm;
|
||||
|
||||
pools = (struct pool **)realloc(pools, sizeof(struct pool *) * (total_pools + 2));
|
||||
pools[total_pools++] = pool;
|
||||
mutex_init(&pool->pool_lock);
|
||||
@ -769,6 +774,35 @@ static char *set_url(char *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static char *set_pool_algorithm(char *arg)
|
||||
{
|
||||
struct pool *pool;
|
||||
|
||||
while ((json_array_index + 1) > total_pools)
|
||||
add_pool();
|
||||
pool = pools[json_array_index];
|
||||
|
||||
applog(LOG_DEBUG, "Setting pool %i algorithm to %s", pool->pool_no, arg);
|
||||
set_algorithm(&pool->algorithm, arg);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *set_pool_nfactor(char *arg)
|
||||
{
|
||||
struct pool *pool;
|
||||
|
||||
while ((json_array_index + 1) > total_pools)
|
||||
add_pool();
|
||||
pool = pools[json_array_index];
|
||||
|
||||
applog(LOG_DEBUG, "Setting pool %i N-factor to %s", pool->pool_no, arg);
|
||||
set_algorithm_nfactor(&pool->algorithm, (const uint8_t) atoi(arg));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *set_poolname(char *arg)
|
||||
{
|
||||
struct pool *pool = get_current_pool();
|
||||
@ -1030,17 +1064,17 @@ static void load_temp_cutoffs()
|
||||
|
||||
static char *set_algo(const char *arg)
|
||||
{
|
||||
set_algorithm(algorithm, arg);
|
||||
applog(LOG_INFO, "Set algorithm to %s", algorithm->name);
|
||||
set_algorithm(default_algorithm, arg);
|
||||
applog(LOG_INFO, "Set default algorithm to %s", default_algorithm->name);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *set_nfactor(const char *arg)
|
||||
{
|
||||
set_algorithm_nfactor(algorithm, (uint8_t)atoi(arg));
|
||||
set_algorithm_nfactor(default_algorithm, (const uint8_t) atoi(arg));
|
||||
applog(LOG_INFO, "Set algorithm N-factor to %d (N to %d)",
|
||||
algorithm->nfactor, algorithm->n);
|
||||
default_algorithm->nfactor, default_algorithm->n);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -1392,6 +1426,12 @@ static struct opt_table opt_config_table[] = {
|
||||
OPT_WITH_ARG("--url|-o",
|
||||
set_url, NULL, NULL,
|
||||
"URL for bitcoin JSON-RPC server"),
|
||||
OPT_WITH_ARG("--pool-algorithm",
|
||||
set_pool_algorithm, NULL, NULL,
|
||||
"Set algorithm for pool"),
|
||||
OPT_WITH_ARG("--pool-nfactor",
|
||||
set_pool_nfactor, NULL, NULL,
|
||||
"Set N-factor for pool"),
|
||||
OPT_WITH_ARG("--user|-u",
|
||||
set_user, NULL, NULL,
|
||||
"Username for bitcoin JSON-RPC server"),
|
||||
@ -3779,7 +3819,6 @@ void switch_pools(struct pool *selected)
|
||||
mutex_lock(&lp_lock);
|
||||
pthread_cond_broadcast(&lp_cond);
|
||||
mutex_unlock(&lp_lock);
|
||||
|
||||
}
|
||||
|
||||
void discard_work(struct work *work)
|
||||
@ -4411,8 +4450,8 @@ void write_config(FILE *fcfg)
|
||||
}
|
||||
if (opt_removedisabled)
|
||||
fprintf(fcfg, ",\n\"remove-disabled\" : true");
|
||||
if (strcmp(algorithm->name, "scrypt") != 0)
|
||||
fprintf(fcfg, ",\n\"algorithm\" : \"%s\"", json_escape(algorithm->name));
|
||||
if (strcmp(default_algorithm->name, "scrypt") != 0)
|
||||
fprintf(fcfg, ",\n\"algorithm\" : \"%s\"", json_escape(default_algorithm->name));
|
||||
if (opt_api_allow)
|
||||
fprintf(fcfg, ",\n\"api-allow\" : \"%s\"", json_escape(opt_api_allow));
|
||||
if (strcmp(opt_api_mcast_addr, API_MCAST_ADDR) != 0)
|
||||
@ -5984,6 +6023,69 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
|
||||
cgtime(&work->tv_staged);
|
||||
}
|
||||
|
||||
static void *switch_algo_thread(void *arg)
|
||||
{
|
||||
algorithm_t *new_algo = (algorithm_t *) arg;
|
||||
int i;
|
||||
|
||||
pthread_detach(pthread_self());
|
||||
|
||||
applog(LOG_WARNING, "Switching algorithm to %s (%d)",
|
||||
new_algo->name, new_algo->nfactor);
|
||||
|
||||
// TODO: When threads are canceled, they may leak memory, for example
|
||||
// the "work" variable in get_work.
|
||||
rd_lock(&devices_lock);
|
||||
for (i = 0; i < total_devices; i++) {
|
||||
devices[i]->algorithm = *new_algo;
|
||||
reinit_device(devices[i]);
|
||||
}
|
||||
rd_unlock(&devices_lock);
|
||||
|
||||
// Wait for reinit_gpu to finish
|
||||
while (42) {
|
||||
struct thread_q *tq = control_thr[gpur_thr_id].q;
|
||||
bool stop = false;
|
||||
mutex_lock(&tq->mutex);
|
||||
stop = list_empty(&tq->q);
|
||||
mutex_unlock(&tq->mutex);
|
||||
if (stop) break;
|
||||
usleep(50000);
|
||||
}
|
||||
|
||||
mutex_lock(&algo_switch_lock);
|
||||
algo_switch_thr = 0;
|
||||
mutex_unlock(&algo_switch_lock);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void wait_to_die(void)
|
||||
{
|
||||
mutex_unlock(&algo_switch_lock);
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||
sleep(60);
|
||||
applog(LOG_ERR, "Thread not canceled within 60 seconds");
|
||||
}
|
||||
|
||||
static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
|
||||
{
|
||||
struct cgpu_info *cgpu = mythr->cgpu;
|
||||
|
||||
mutex_lock(&algo_switch_lock);
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
||||
if (!cmp_algorithm(&work->pool->algorithm, &cgpu->algorithm)) {
|
||||
// stage work back to queue, we cannot process it yet
|
||||
stage_work(work);
|
||||
if (algo_switch_thr == 0)
|
||||
pthread_create(&algo_switch_thr, NULL, &switch_algo_thread, &work->pool->algorithm);
|
||||
wait_to_die();
|
||||
} else {
|
||||
mutex_unlock(&algo_switch_lock);
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
struct work *get_work(struct thr_info *thr, const int thr_id)
|
||||
{
|
||||
struct work *work = NULL;
|
||||
@ -6000,6 +6102,9 @@ struct work *get_work(struct thr_info *thr, const int thr_id)
|
||||
wake_gws();
|
||||
}
|
||||
}
|
||||
|
||||
get_work_prepare_thread(thr, work);
|
||||
|
||||
diff_t = time(NULL) - diff_t;
|
||||
/* Since this is a blocking function, we need to add grace time to
|
||||
* the device's last valid work to not make outages appear to be
|
||||
@ -6080,7 +6185,7 @@ static void rebuild_nonce(struct work *work, uint32_t nonce)
|
||||
|
||||
*work_nonce = htole32(nonce);
|
||||
|
||||
scrypt_regenhash(work);
|
||||
scrypt_regenhash(work, work->pool->algorithm.n);
|
||||
}
|
||||
|
||||
/* For testing a nonce against diff 1 */
|
||||
@ -6208,8 +6313,10 @@ static void mt_disable(struct thr_info *mythr, const int thr_id,
|
||||
applog(LOG_WARNING, "Thread %d being disabled", thr_id);
|
||||
mythr->rolling = mythr->cgpu->rolling = 0;
|
||||
applog(LOG_DEBUG, "Waiting on sem in miner thread");
|
||||
mythr->paused = true;
|
||||
cgsem_wait(&mythr->sem);
|
||||
applog(LOG_WARNING, "Thread %d being re-enabled", thr_id);
|
||||
mythr->paused = false;
|
||||
drv->thread_enable(mythr);
|
||||
}
|
||||
|
||||
@ -6226,7 +6333,7 @@ static void hash_sole_work(struct thr_info *mythr)
|
||||
struct sgminer_stats *pool_stats;
|
||||
/* Try to cycle approximately 5 times before each log update */
|
||||
const long cycle = opt_log_interval / 5 ? 5 : 1;
|
||||
const bool primary = (!mythr->device_thread) || mythr->primary_thread;
|
||||
const bool primary = mythr->device_thread == 0;
|
||||
struct timeval diff, sdiff, wdiff = {0, 0};
|
||||
uint32_t max_nonce = drv->can_limit_work(mythr);
|
||||
int64_t hashes_done = 0;
|
||||
@ -7831,6 +7938,7 @@ int main(int argc, char *argv[])
|
||||
rwlock_init(&netacc_lock);
|
||||
rwlock_init(&mining_thr_lock);
|
||||
rwlock_init(&devices_lock);
|
||||
mutex_init(&algo_switch_lock);
|
||||
|
||||
mutex_init(&lp_lock);
|
||||
if (unlikely(pthread_cond_init(&lp_cond, NULL)))
|
||||
@ -7883,8 +7991,8 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
|
||||
/* Default algorithm specified in algorithm.c ATM */
|
||||
algorithm = (algorithm_t *)alloca(sizeof(algorithm_t));
|
||||
set_algorithm(algorithm, "scrypt");
|
||||
default_algorithm = (algorithm_t *)alloca(sizeof(algorithm_t));
|
||||
set_algorithm(default_algorithm, "scrypt");
|
||||
|
||||
devcursor = 8;
|
||||
logstart = devcursor + 1;
|
||||
|
Loading…
Reference in New Issue
Block a user