Browse Source

Merge remote-tracking branch 'mrbrdo/poolalgo' into poolalgo

Conflicts (resolved):
	ocl.h
	sgminer.c
refactor
Noel Maersk 11 years ago
parent
commit
0793c96074
  1. 5
      algorithm.c
  2. 4
      algorithm.h
  3. 2
      api.c
  4. 6
      doc/configuration.md
  5. 17
      driver-opencl.c
  6. 8
      miner.h
  7. 8
      ocl.c
  8. 3
      ocl.h
  9. 88
      scrypt.c
  10. 2
      scrypt.h
  11. 124
      sgminer.c

5
algorithm.c

@ -33,3 +33,8 @@ void set_algorithm_nfactor(algorithm_t* algo, const uint8_t nfactor) {
return; return;
} }
bool cmp_algorithm(algorithm_t* algo1, algorithm_t* algo2) {
return (strcmp(algo1->name, algo2->name) == 0) &&
(algo1->nfactor == algo2->nfactor);
}

4
algorithm.h

@ -2,6 +2,7 @@
#define ALGORITHM_H #define ALGORITHM_H
#include <inttypes.h> #include <inttypes.h>
#include <stdbool.h>
/* Describes the Scrypt parameters and hashing functions used to mine /* Describes the Scrypt parameters and hashing functions used to mine
* a specific coin. * a specific coin.
@ -18,4 +19,7 @@ void set_algorithm(algorithm_t* algo, const char* name);
/* Set to specific N factor. */ /* Set to specific N factor. */
void set_algorithm_nfactor(algorithm_t* algo, const uint8_t nfactor); 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 */ #endif /* ALGORITHM_H */

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); message(io_data, MSG_MINECOIN, 0, NULL, isjson);
io_open = io_add(io_data, isjson ? COMSTR JSON_MINECOIN : _MINECOIN COMSTR); 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); cg_rlock(&ch_lock);
root = api_add_timeval(root, "Current Block Time", &block_timeval, true); root = api_add_timeval(root, "Current Block Time", &block_timeval, true);

6
doc/configuration.md

@ -23,6 +23,9 @@ cryptocurrencies.
* everything else - currently defaults to `scrypt`, subject to change * everything else - currently defaults to `scrypt`, subject to change
without warning. without warning.
### pool-algorithm
Allows choosing the algorithm for a specific pool. See `algorithm`.
### nfactor ### nfactor
@ -33,6 +36,9 @@ Overrides the default scrypt parameter N, specified as the factor of 2
*Default:* depends on `algorithm`; otherwise `10`. *Default:* depends on `algorithm`; otherwise `10`.
### pool-nfactor
Overrides the default scrypt parameter N for a specific pool. See `nfactor`.
## CLI-only options ## CLI-only options

17
driver-opencl.c

@ -1094,6 +1094,8 @@ select_cgpu:
cgtime(&thr->sick); cgtime(&thr->sick);
if (!pthread_cancel(thr->pth)) { if (!pthread_cancel(thr->pth)) {
applog(LOG_WARNING, "Thread %d still exists, killing it off", thr_id); applog(LOG_WARNING, "Thread %d still exists, killing it off", thr_id);
pthread_join(thr->pth, NULL);
thr->cgpu->drv->thread_shutdown(thr);
} else } else
applog(LOG_WARNING, "Thread %d no longer exists", thr_id); applog(LOG_WARNING, "Thread %d no longer exists", thr_id);
} }
@ -1120,7 +1122,7 @@ select_cgpu:
//free(clState); //free(clState);
applog(LOG_INFO, "Reinit GPU thread %d", thr_id); 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]) { if (!clStates[thr_id]) {
applog(LOG_ERR, "Failed to reinit GPU thread %d", thr_id); applog(LOG_ERR, "Failed to reinit GPU thread %d", thr_id);
goto select_cgpu; goto select_cgpu;
@ -1186,6 +1188,7 @@ static void opencl_detect(bool hotplug)
cgpu->threads = 1; cgpu->threads = 1;
#endif #endif
cgpu->virtual_gpu = i; cgpu->virtual_gpu = i;
cgpu->algorithm = *default_algorithm;
add_cgpu(cgpu); add_cgpu(cgpu);
} }
@ -1261,7 +1264,7 @@ static bool opencl_thread_prepare(struct thr_info *thr)
strcpy(name, ""); strcpy(name, "");
applog(LOG_INFO, "Init GPU thread %i GPU %i virtual GPU %i", i, gpu, virtual_gpu); 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]) { if (!clStates[i]) {
#ifdef HAVE_CURSES #ifdef HAVE_CURSES
if (use_curses) if (use_curses)
@ -1443,15 +1446,25 @@ static int64_t opencl_scanhash(struct thr_info *thr, struct work *work,
return hashes; 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) static void opencl_thread_shutdown(struct thr_info *thr)
{ {
const int thr_id = thr->id; const int thr_id = thr->id;
_clState *clState = clStates[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); clReleaseKernel(clState->kernel);
clReleaseProgram(clState->program); clReleaseProgram(clState->program);
clReleaseCommandQueue(clState->commandQueue); clReleaseCommandQueue(clState->commandQueue);
clReleaseContext(clState->context); clReleaseContext(clState->context);
free(clState);
}
} }
struct device_drv opencl_drv = { struct device_drv opencl_drv = {

8
miner.h

@ -475,6 +475,7 @@ struct cgpu_info {
cl_uint vwidth; cl_uint vwidth;
size_t work_size; size_t work_size;
cl_ulong max_alloc; cl_ulong max_alloc;
algorithm_t algorithm;
int opt_lg, lookup_gap; int opt_lg, lookup_gap;
size_t opt_tc, thread_concurrency; size_t opt_tc, thread_concurrency;
@ -548,7 +549,6 @@ struct thread_q {
struct thr_info { struct thr_info {
int id; int id;
int device_thread; int device_thread;
bool primary_thread;
pthread_t pth; pthread_t pth;
cgsem_t sem; cgsem_t sem;
@ -559,6 +559,7 @@ struct thr_info {
struct timeval sick; struct timeval sick;
bool pause; bool pause;
bool paused;
bool getwork; bool getwork;
double rolling; double rolling;
@ -1014,8 +1015,7 @@ extern int opt_queue;
extern int opt_scantime; extern int opt_scantime;
extern int opt_expiry; extern int opt_expiry;
extern char *opt_algorithm; extern algorithm_t *default_algorithm;
extern algorithm_t *algorithm;
extern cglock_t control_lock; extern cglock_t control_lock;
extern pthread_mutex_t hash_lock; extern pthread_mutex_t hash_lock;
@ -1219,6 +1219,8 @@ struct pool {
proxytypes_t rpc_proxytype; proxytypes_t rpc_proxytype;
char *rpc_proxy; char *rpc_proxy;
algorithm_t algorithm;
pthread_mutex_t pool_lock; pthread_mutex_t pool_lock;
cglock_t data_lock; cglock_t data_lock;

8
ocl.c

@ -31,6 +31,7 @@
#include <unistd.h> #include <unistd.h>
#include "findnonce.h" #include "findnonce.h"
#include "algorithm.h"
#include "ocl.h" #include "ocl.h"
/* FIXME: only here for global config vars, replace with configuration.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); 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)); _clState *clState = (_clState *)calloc(1, sizeof(_clState));
bool patchbfi = false, prog_built = false; bool patchbfi = false, prog_built = false;
@ -732,8 +733,9 @@ built:
free(binaries); free(binaries);
free(binary_sizes); free(binary_sizes);
applog(LOG_NOTICE, "Initialising kernel %s with%s bitalign, %spatched BFI", applog(LOG_NOTICE, "Initialising kernel %s with%s bitalign, %spatched BFI, nfactor %d, n %d",
filename, clState->hasBitAlign ? "" : "out", patchbfi ? "" : "un"); filename, clState->hasBitAlign ? "" : "out", patchbfi ? "" : "un",
algorithm->nfactor, algorithm->n);
if (!prog_built) { if (!prog_built) {
/* create a cl program executable for all the devices specified */ /* create a cl program executable for all the devices specified */

3
ocl.h

@ -34,6 +34,7 @@ typedef struct {
extern char *file_contents(const char *filename, int *length); extern char *file_contents(const char *filename, int *length);
extern int clDevicesNum(void); 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 */ #endif /* OCL_H */

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): * scratchpad size needs to be at least (bytes):
* 63 + (128 * r * p) + (256 * r + 64) + (128 * r * N) * 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 * V;
uint32_t X[32]; 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); 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); memcpy(&V[i * 32], X, 128);
salsa20_8(&X[0], &X[16]); 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[0], &X[16]);
salsa20_8(&X[16], &X[0]); salsa20_8(&X[16], &X[0]);
} }
for (i = 0; i < algorithm->n; i += 2) { for (i = 0; i < n; i += 2) {
j = X[16] & (algorithm->n-1); j = X[16] & (n-1);
p2 = (uint64_t *)(&V[j * 32]); p2 = (uint64_t *)(&V[j * 32]);
for(k = 0; k < 16; k++) for(k = 0; k < 16; k++)
p1[k] ^= p2[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[0], &X[16]);
salsa20_8(&X[16], &X[0]); salsa20_8(&X[16], &X[0]);
j = X[16] & (algorithm->n-1); j = X[16] & (n-1);
p2 = (uint64_t *)(&V[j * 32]); p2 = (uint64_t *)(&V[j * 32]);
for(k = 0; k < 16; k++) for(k = 0; k < 16; k++)
p1[k] ^= p2[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); 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]; uint32_t data[20];
char *scratchbuf; char *scratchbuf;
@ -414,81 +414,9 @@ void scrypt_regenhash(struct work *work)
be32enc_vect(data, (const uint32_t *)work->data, 19); be32enc_vect(data, (const uint32_t *)work->data, 19);
data[19] = htobe32(*nonce); data[19] = htobe32(*nonce);
scratchbuf = (char *)alloca(algorithm->n * 128 + 512); scratchbuf = (char *)alloca(n * 128 + 512);
scrypt_n_1_1_256_sp(data, scratchbuf, ohash); scrypt_n_1_1_256_sp(data, scratchbuf, ohash, n);
flip32(ohash, ohash); flip32(ohash, ohash);
} }
static const uint32_t diff1targ = 0x0000ffff; 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

@ -5,6 +5,6 @@
/* extern int scrypt_test(unsigned char *pdata, const unsigned char *ptarget, */ /* extern int scrypt_test(unsigned char *pdata, const unsigned char *ptarget, */
/* uint32_t nonce); */ /* uint32_t nonce); */
extern void scrypt_regenhash(struct work *work); extern void scrypt_regenhash(struct work *work, uint32_t n);
#endif /* SCRYPT_H */ #endif /* SCRYPT_H */

124
sgminer.c

@ -98,8 +98,7 @@ int opt_queue = 1;
int opt_scantime = 7; int opt_scantime = 7;
int opt_expiry = 28; int opt_expiry = 28;
char *opt_algorithm; algorithm_t *default_algorithm;
algorithm_t *algorithm;
static const bool opt_time = true; static const bool opt_time = true;
unsigned long long global_hashrate; unsigned long long global_hashrate;
@ -199,6 +198,11 @@ pthread_rwlock_t devices_lock;
static pthread_mutex_t lp_lock; static pthread_mutex_t lp_lock;
static pthread_cond_t lp_cond; static pthread_cond_t lp_cond;
static pthread_mutex_t algo_switch_lock;
static int algo_switch_n = 0;
static pthread_mutex_t algo_switch_wait_lock;
static pthread_cond_t algo_switch_wait_cond;
pthread_mutex_t restart_lock; pthread_mutex_t restart_lock;
pthread_cond_t restart_cond; pthread_cond_t restart_cond;
@ -538,6 +542,9 @@ struct pool *add_pool(void)
buf[0] = '\0'; buf[0] = '\0';
pool->name = strdup(buf); pool->name = strdup(buf);
/* Algorithm */
pool->algorithm = *default_algorithm;
pools = (struct pool **)realloc(pools, sizeof(struct pool *) * (total_pools + 2)); pools = (struct pool **)realloc(pools, sizeof(struct pool *) * (total_pools + 2));
pools[total_pools++] = pool; pools[total_pools++] = pool;
mutex_init(&pool->pool_lock); mutex_init(&pool->pool_lock);
@ -773,6 +780,35 @@ static char *set_url(char *arg)
return NULL; 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) static char *set_poolname(char *arg)
{ {
struct pool *pool = get_current_pool(); struct pool *pool = get_current_pool();
@ -1034,17 +1070,17 @@ static void load_temp_cutoffs()
static char *set_algo(const char *arg) static char *set_algo(const char *arg)
{ {
set_algorithm(algorithm, arg); set_algorithm(default_algorithm, arg);
applog(LOG_INFO, "Set algorithm to %s", algorithm->name); applog(LOG_INFO, "Set default algorithm to %s", default_algorithm->name);
return NULL; return NULL;
} }
static char *set_nfactor(const char *arg) 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)", applog(LOG_INFO, "Set algorithm N-factor to %d (N to %d)",
algorithm->nfactor, algorithm->n); default_algorithm->nfactor, default_algorithm->n);
return NULL; return NULL;
} }
@ -1399,6 +1435,12 @@ static struct opt_table opt_config_table[] = {
OPT_WITH_ARG("--url|-o", OPT_WITH_ARG("--url|-o",
set_url, NULL, NULL, set_url, NULL, NULL,
"URL for bitcoin JSON-RPC server"), "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", OPT_WITH_ARG("--user|-u",
set_user, NULL, NULL, set_user, NULL, NULL,
"Username for bitcoin JSON-RPC server"), "Username for bitcoin JSON-RPC server"),
@ -3783,7 +3825,6 @@ void switch_pools(struct pool *selected)
mutex_lock(&lp_lock); mutex_lock(&lp_lock);
pthread_cond_broadcast(&lp_cond); pthread_cond_broadcast(&lp_cond);
mutex_unlock(&lp_lock); mutex_unlock(&lp_lock);
} }
void discard_work(struct work *work) void discard_work(struct work *work)
@ -4415,8 +4456,8 @@ void write_config(FILE *fcfg)
} }
if (opt_removedisabled) if (opt_removedisabled)
fprintf(fcfg, ",\n\"remove-disabled\" : true"); fprintf(fcfg, ",\n\"remove-disabled\" : true");
if (strcmp(algorithm->name, "scrypt") != 0) if (strcmp(default_algorithm->name, "scrypt") != 0)
fprintf(fcfg, ",\n\"algorithm\" : \"%s\"", json_escape(algorithm->name)); fprintf(fcfg, ",\n\"algorithm\" : \"%s\"", json_escape(default_algorithm->name));
if (opt_api_allow) if (opt_api_allow)
fprintf(fcfg, ",\n\"api-allow\" : \"%s\"", json_escape(opt_api_allow)); fprintf(fcfg, ",\n\"api-allow\" : \"%s\"", json_escape(opt_api_allow));
if (strcmp(opt_api_mcast_addr, API_MCAST_ADDR) != 0) if (strcmp(opt_api_mcast_addr, API_MCAST_ADDR) != 0)
@ -5988,6 +6029,53 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
cgtime(&work->tv_staged); cgtime(&work->tv_staged);
} }
static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
{
int i;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
mutex_lock(&algo_switch_lock);
if (cmp_algorithm(&work->pool->algorithm, &mythr->cgpu->algorithm) && (algo_switch_n == 0)) {
mutex_unlock(&algo_switch_lock);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
return;
}
algo_switch_n++;
// If all threads are waiting now
if (algo_switch_n >= mining_threads) {
rd_lock(&mining_thr_lock);
// Shutdown all threads first (necessary)
for (i = 0; i < mining_threads; i++) {
struct thr_info *thr = mining_thr[i];
thr->cgpu->drv->thread_shutdown(thr);
}
// Change algorithm for each thread (thread_prepare calls initCl)
for (i = 0; i < mining_threads; i++) {
struct thr_info *thr = mining_thr[i];
thr->cgpu->algorithm = work->pool->algorithm;
thr->cgpu->drv->thread_prepare(thr);
}
rd_unlock(&mining_thr_lock);
algo_switch_n = 0;
mutex_unlock(&algo_switch_lock);
// Signal other threads to start working now
mutex_lock(&algo_switch_wait_lock);
pthread_cond_broadcast(&algo_switch_wait_cond);
mutex_unlock(&algo_switch_wait_lock);
// Not all threads are waiting, join the waiting list
} else {
mutex_unlock(&algo_switch_lock);
// Wait for signal to start working again
mutex_lock(&algo_switch_wait_lock);
pthread_cond_wait(&algo_switch_wait_cond, &algo_switch_wait_lock);
mutex_unlock(&algo_switch_wait_lock);
}
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
}
struct work *get_work(struct thr_info *thr, const int thr_id) struct work *get_work(struct thr_info *thr, const int thr_id)
{ {
struct work *work = NULL; struct work *work = NULL;
@ -6004,6 +6092,9 @@ struct work *get_work(struct thr_info *thr, const int thr_id)
wake_gws(); wake_gws();
} }
} }
get_work_prepare_thread(thr, work);
diff_t = time(NULL) - diff_t; diff_t = time(NULL) - diff_t;
/* Since this is a blocking function, we need to add grace time to /* 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 * the device's last valid work to not make outages appear to be
@ -6084,7 +6175,7 @@ static void rebuild_nonce(struct work *work, uint32_t nonce)
*work_nonce = htole32(nonce); *work_nonce = htole32(nonce);
scrypt_regenhash(work); scrypt_regenhash(work, work->pool->algorithm.n);
} }
/* For testing a nonce against diff 1 */ /* For testing a nonce against diff 1 */
@ -6212,8 +6303,10 @@ static void mt_disable(struct thr_info *mythr, const int thr_id,
applog(LOG_WARNING, "Thread %d being disabled", thr_id); applog(LOG_WARNING, "Thread %d being disabled", thr_id);
mythr->rolling = mythr->cgpu->rolling = 0; mythr->rolling = mythr->cgpu->rolling = 0;
applog(LOG_DEBUG, "Waiting on sem in miner thread"); applog(LOG_DEBUG, "Waiting on sem in miner thread");
mythr->paused = true;
cgsem_wait(&mythr->sem); cgsem_wait(&mythr->sem);
applog(LOG_WARNING, "Thread %d being re-enabled", thr_id); applog(LOG_WARNING, "Thread %d being re-enabled", thr_id);
mythr->paused = false;
drv->thread_enable(mythr); drv->thread_enable(mythr);
} }
@ -6230,7 +6323,7 @@ static void hash_sole_work(struct thr_info *mythr)
struct sgminer_stats *pool_stats; struct sgminer_stats *pool_stats;
/* Try to cycle approximately 5 times before each log update */ /* Try to cycle approximately 5 times before each log update */
const long cycle = opt_log_interval / 5 ? 5 : 1; 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}; struct timeval diff, sdiff, wdiff = {0, 0};
uint32_t max_nonce = drv->can_limit_work(mythr); uint32_t max_nonce = drv->can_limit_work(mythr);
int64_t hashes_done = 0; int64_t hashes_done = 0;
@ -7835,6 +7928,7 @@ int main(int argc, char *argv[])
rwlock_init(&netacc_lock); rwlock_init(&netacc_lock);
rwlock_init(&mining_thr_lock); rwlock_init(&mining_thr_lock);
rwlock_init(&devices_lock); rwlock_init(&devices_lock);
mutex_init(&algo_switch_lock);
mutex_init(&lp_lock); mutex_init(&lp_lock);
if (unlikely(pthread_cond_init(&lp_cond, NULL))) if (unlikely(pthread_cond_init(&lp_cond, NULL)))
@ -7844,6 +7938,10 @@ int main(int argc, char *argv[])
if (unlikely(pthread_cond_init(&restart_cond, NULL))) if (unlikely(pthread_cond_init(&restart_cond, NULL)))
quit(1, "Failed to pthread_cond_init restart_cond"); quit(1, "Failed to pthread_cond_init restart_cond");
mutex_init(&algo_switch_wait_lock);
if (unlikely(pthread_cond_init(&algo_switch_wait_cond, NULL)))
quit(1, "Failed to pthread_cond_init algo_switch_wait_cond");
if (unlikely(pthread_cond_init(&gws_cond, NULL))) if (unlikely(pthread_cond_init(&gws_cond, NULL)))
quit(1, "Failed to pthread_cond_init gws_cond"); quit(1, "Failed to pthread_cond_init gws_cond");
@ -7887,8 +7985,8 @@ int main(int argc, char *argv[])
#endif #endif
/* Default algorithm specified in algorithm.c ATM */ /* Default algorithm specified in algorithm.c ATM */
algorithm = (algorithm_t *)alloca(sizeof(algorithm_t)); default_algorithm = (algorithm_t *)alloca(sizeof(algorithm_t));
set_algorithm(algorithm, "scrypt"); set_algorithm(default_algorithm, "scrypt");
devcursor = 8; devcursor = 8;
logstart = devcursor + 1; logstart = devcursor + 1;

Loading…
Cancel
Save