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;
|
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
|
#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 */
|
||||||
|
4
api.c
4
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);
|
||||||
@ -4027,7 +4027,7 @@ die:
|
|||||||
pthread_cleanup_pop(true);
|
pthread_cleanup_pop(true);
|
||||||
|
|
||||||
free(apisock);
|
free(apisock);
|
||||||
|
|
||||||
if (opt_debug)
|
if (opt_debug)
|
||||||
applog(LOG_DEBUG, "API: terminating due to: %s",
|
applog(LOG_DEBUG, "API: terminating due to: %s",
|
||||||
do_a_quit ? "QUIT" : (do_a_restart ? "RESTART" : (bye ? "BYE" : "UNKNOWN!")));
|
do_a_quit ? "QUIT" : (do_a_restart ? "RESTART" : (bye ? "BYE" : "UNKNOWN!")));
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ char *set_gpu_threads(char *arg)
|
|||||||
for (i = device; i < MAX_GPUDEVICES; i++)
|
for (i = device; i < MAX_GPUDEVICES; i++)
|
||||||
gpus[i].threads = gpus[0].threads;
|
gpus[i].threads = gpus[0].threads;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -880,7 +880,7 @@ retry: // TODO: refactor
|
|||||||
|
|
||||||
intvar = curses_input("Set GPU scan intensity (d or "
|
intvar = curses_input("Set GPU scan intensity (d or "
|
||||||
MIN_INTENSITY_STR " -> "
|
MIN_INTENSITY_STR " -> "
|
||||||
MAX_INTENSITY_STR ")");
|
MAX_INTENSITY_STR ")");
|
||||||
if (!intvar) {
|
if (!intvar) {
|
||||||
wlogprint("Invalid input\n");
|
wlogprint("Invalid input\n");
|
||||||
goto retry;
|
goto retry;
|
||||||
@ -937,14 +937,14 @@ retry: // TODO: refactor
|
|||||||
} else if (!strncasecmp(&input, "a", 1)) {
|
} else if (!strncasecmp(&input, "a", 1)) {
|
||||||
int rawintensity;
|
int rawintensity;
|
||||||
char *intvar;
|
char *intvar;
|
||||||
|
|
||||||
if (selected)
|
if (selected)
|
||||||
selected = curses_int("Select GPU to change raw intensity on");
|
selected = curses_int("Select GPU to change raw intensity on");
|
||||||
if (selected < 0 || selected >= nDevs) {
|
if (selected < 0 || selected >= nDevs) {
|
||||||
wlogprint("Invalid selection\n");
|
wlogprint("Invalid selection\n");
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
intvar = curses_input("Set raw GPU scan intensity (" MIN_RAWINTENSITY_STR " -> " MAX_RAWINTENSITY_STR ")");
|
intvar = curses_input("Set raw GPU scan intensity (" MIN_RAWINTENSITY_STR " -> " MAX_RAWINTENSITY_STR ")");
|
||||||
if (!intvar) {
|
if (!intvar) {
|
||||||
wlogprint("Invalid input\n");
|
wlogprint("Invalid input\n");
|
||||||
@ -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;
|
||||||
|
|
||||||
clReleaseKernel(clState->kernel);
|
if (clState) {
|
||||||
clReleaseProgram(clState->program);
|
clFinish(clState->commandQueue);
|
||||||
clReleaseCommandQueue(clState->commandQueue);
|
clReleaseMemObject(clState->outputBuffer);
|
||||||
clReleaseContext(clState->context);
|
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 = {
|
struct device_drv opencl_drv = {
|
||||||
|
10
miner.h
10
miner.h
@ -241,7 +241,7 @@ enum drv_driver {
|
|||||||
/* Use DRIVER_PARSE_COMMANDS to generate extern device_drv prototypes */
|
/* Use DRIVER_PARSE_COMMANDS to generate extern device_drv prototypes */
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
DRIVER_PARSE_COMMANDS(DRIVER_PROTOTYPE)
|
DRIVER_PARSE_COMMANDS(DRIVER_PROTOTYPE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum alive {
|
enum alive {
|
||||||
LIFE_WELL,
|
LIFE_WELL,
|
||||||
@ -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;
|
||||||
|
|
||||||
|
12
ocl.c
12
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;
|
||||||
@ -350,7 +351,7 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize)
|
|||||||
find = strstr(extensions, camo);
|
find = strstr(extensions, camo);
|
||||||
if (find)
|
if (find)
|
||||||
clState->hasBitAlign = true;
|
clState->hasBitAlign = true;
|
||||||
|
|
||||||
/* Check for OpenCL >= 1.0 support, needed for global offset parameter usage. */
|
/* Check for OpenCL >= 1.0 support, needed for global offset parameter usage. */
|
||||||
char * devoclver = (char *)malloc(1024);
|
char * devoclver = (char *)malloc(1024);
|
||||||
const char * ocl10 = "OpenCL 1.0";
|
const char * ocl10 = "OpenCL 1.0";
|
||||||
@ -382,7 +383,7 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
applog(LOG_DEBUG, "Max work group size reported %d", (int)(clState->max_work_size));
|
applog(LOG_DEBUG, "Max work group size reported %d", (int)(clState->max_work_size));
|
||||||
|
|
||||||
size_t compute_units = 0;
|
size_t compute_units = 0;
|
||||||
status = clGetDeviceInfo(devices[gpu], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(size_t), (void *)&compute_units, NULL);
|
status = clGetDeviceInfo(devices[gpu], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(size_t), (void *)&compute_units, NULL);
|
||||||
if (status != CL_SUCCESS) {
|
if (status != CL_SUCCESS) {
|
||||||
@ -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 */
|
||||||
|
2
ocl.h
2
ocl.h
@ -34,5 +34,5 @@ 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__ */
|
||||||
|
96
scrypt.c
96
scrypt.c
@ -204,7 +204,7 @@ PBKDF2_SHA256_80_128(const uint32_t * passwd, uint32_t * buf)
|
|||||||
uint32_t ihash[8];
|
uint32_t ihash[8];
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint32_t pad[16];
|
uint32_t pad[16];
|
||||||
|
|
||||||
static const uint32_t innerpad[11] = {0x00000080, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xa0040000};
|
static const uint32_t innerpad[11] = {0x00000080, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xa0040000};
|
||||||
|
|
||||||
/* If Klen > 64, the key is really SHA256(K). */
|
/* If Klen > 64, the key is really SHA256(K). */
|
||||||
@ -237,7 +237,7 @@ PBKDF2_SHA256_80_128(const uint32_t * passwd, uint32_t * buf)
|
|||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
uint32_t istate[8];
|
uint32_t istate[8];
|
||||||
uint32_t ostate[8];
|
uint32_t ostate[8];
|
||||||
|
|
||||||
memcpy(istate, PShictx.state, 32);
|
memcpy(istate, PShictx.state, 32);
|
||||||
PShictx.buf[4] = i + 1;
|
PShictx.buf[4] = i + 1;
|
||||||
SHA256_Transform(istate, PShictx.buf, 0);
|
SHA256_Transform(istate, PShictx.buf, 0);
|
||||||
@ -259,7 +259,7 @@ PBKDF2_SHA256_80_128_32(const uint32_t * passwd, const uint32_t * salt, uint32_t
|
|||||||
|
|
||||||
/* Compute HMAC state after processing P and S. */
|
/* Compute HMAC state after processing P and S. */
|
||||||
uint32_t pad[16];
|
uint32_t pad[16];
|
||||||
|
|
||||||
static const uint32_t ihash_finalblk[16] = {0x00000001,0x80000000,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0x00000620};
|
static const uint32_t ihash_finalblk[16] = {0x00000001,0x80000000,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0x00000620};
|
||||||
|
|
||||||
/* If Klen > 64, the key is really SHA256(K). */
|
/* If Klen > 64, the key is really SHA256(K). */
|
||||||
@ -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,91 +404,19 @@ 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;
|
||||||
uint32_t *nonce = (uint32_t *)(work->data + 76);
|
uint32_t *nonce = (uint32_t *)(work->data + 76);
|
||||||
uint32_t *ohash = (uint32_t *)(work->hash);
|
uint32_t *ohash = (uint32_t *)(work->hash);
|
||||||
|
|
||||||
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
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 */
|
||||||
|
148
sgminer.c
148
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,9 @@ 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 pthread_t algo_switch_thr = 0;
|
||||||
|
|
||||||
pthread_mutex_t restart_lock;
|
pthread_mutex_t restart_lock;
|
||||||
pthread_cond_t restart_cond;
|
pthread_cond_t restart_cond;
|
||||||
|
|
||||||
@ -536,6 +538,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);
|
||||||
@ -559,7 +564,7 @@ struct pool *add_pool(void)
|
|||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pool* get_current_pool()
|
static struct pool* get_current_pool()
|
||||||
{
|
{
|
||||||
while ((json_array_index + 1) > total_pools)
|
while ((json_array_index + 1) > total_pools)
|
||||||
add_pool();
|
add_pool();
|
||||||
@ -569,8 +574,8 @@ static struct pool* get_current_pool()
|
|||||||
add_pool();
|
add_pool();
|
||||||
return pools[total_pools - 1];
|
return pools[total_pools - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
return pools[json_array_index];
|
return pools[json_array_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pool variant of test and set */
|
/* Pool variant of test and set */
|
||||||
@ -769,10 +774,39 @@ 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();
|
||||||
|
|
||||||
applog(LOG_DEBUG, "Setting pool %i name to %s", pool->pool_no, arg);
|
applog(LOG_DEBUG, "Setting pool %i name to %s", pool->pool_no, arg);
|
||||||
opt_set_charp(arg, &pool->name);
|
opt_set_charp(arg, &pool->name);
|
||||||
|
|
||||||
@ -1030,17 +1064,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;
|
||||||
}
|
}
|
||||||
@ -1392,6 +1426,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"),
|
||||||
@ -3779,7 +3819,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)
|
||||||
@ -4411,8 +4450,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)
|
||||||
@ -5984,6 +6023,69 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
|
|||||||
cgtime(&work->tv_staged);
|
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 *get_work(struct thr_info *thr, const int thr_id)
|
||||||
{
|
{
|
||||||
struct work *work = NULL;
|
struct work *work = NULL;
|
||||||
@ -6000,6 +6102,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
|
||||||
@ -6080,7 +6185,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 */
|
||||||
@ -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);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6226,7 +6333,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;
|
||||||
@ -7174,7 +7281,7 @@ static void *watchdog_thread(void __maybe_unused *userdata)
|
|||||||
temp, fanpercent, fanspeed, engineclock, memclock, vddc, activity, powertune);
|
temp, fanpercent, fanspeed, engineclock, memclock, vddc, activity, powertune);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Thread is disabled or waiting on getwork */
|
/* Thread is disabled or waiting on getwork */
|
||||||
if (*denable == DEV_DISABLED || thr->getwork)
|
if (*denable == DEV_DISABLED || thr->getwork)
|
||||||
continue;
|
continue;
|
||||||
@ -7737,7 +7844,7 @@ bool add_cgpu(struct cgpu_info *cgpu)
|
|||||||
{
|
{
|
||||||
static struct _cgpu_devid_counter *devids = NULL;
|
static struct _cgpu_devid_counter *devids = NULL;
|
||||||
struct _cgpu_devid_counter *d;
|
struct _cgpu_devid_counter *d;
|
||||||
|
|
||||||
HASH_FIND_STR(devids, cgpu->drv->name, d);
|
HASH_FIND_STR(devids, cgpu->drv->name, d);
|
||||||
if (d)
|
if (d)
|
||||||
cgpu->device_id = ++d->lastid;
|
cgpu->device_id = ++d->lastid;
|
||||||
@ -7831,6 +7938,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)))
|
||||||
@ -7883,8 +7991,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;
|
||||||
@ -8180,7 +8288,7 @@ begin_bench:
|
|||||||
|
|
||||||
cgpu->rolling = cgpu->total_mhashes = 0;
|
cgpu->rolling = cgpu->total_mhashes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cgtime(&total_tv_start);
|
cgtime(&total_tv_start);
|
||||||
cgtime(&total_tv_end);
|
cgtime(&total_tv_end);
|
||||||
get_datestamp(datestamp, sizeof(datestamp), &total_tv_start);
|
get_datestamp(datestamp, sizeof(datestamp), &total_tv_start);
|
||||||
|
Loading…
Reference in New Issue
Block a user