mirror of
https://github.com/GOSTSec/sgminer
synced 2025-01-09 06:18:06 +00:00
Merge pull request #2 from veox/forward-port
Forward-port relevant changes up to ckolivas/cgminer 3.10.0
This commit is contained in:
commit
909af927c3
14
Makefile.am
14
Makefile.am
@ -1,16 +1,16 @@
|
|||||||
|
|
||||||
ACLOCAL_AMFLAGS = -I m4
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
|
||||||
JANSSON_INCLUDES= -I$(top_builddir)/compat/jansson-2.5/src -I$(top_srcdir)/compat/jansson-2.5/src
|
JANSSON_CPPFLAGS= -I$(top_builddir)/compat/jansson-2.5/src -I$(top_srcdir)/compat/jansson-2.5/src
|
||||||
|
|
||||||
EXTRA_DIST = example.conf m4/gnulib-cache.m4 linux-usb-cgminer \
|
EXTRA_DIST = example.conf m4/gnulib-cache.m4 \
|
||||||
ADL_SDK/readme.txt api-example.php miner.php \
|
ADL_SDK/readme.txt api-example.php miner.php \
|
||||||
API.class API.java api-example.c windows-build.txt \
|
API.class API.java api-example.c windows-build.txt \
|
||||||
API-README SCRYPT-README hexdump.c GPU-README
|
API-README SCRYPT-README hexdump.c GPU-README
|
||||||
|
|
||||||
SUBDIRS = lib compat ccan
|
SUBDIRS = lib compat ccan
|
||||||
|
|
||||||
INCLUDES = $(PTHREAD_FLAGS) -fno-strict-aliasing $(JANSSON_INCLUDES)
|
INCLUDES = $(PTHREAD_FLAGS) -fno-strict-aliasing $(JANSSON_CPPFLAGS)
|
||||||
|
|
||||||
bin_PROGRAMS = cgminer
|
bin_PROGRAMS = cgminer
|
||||||
|
|
||||||
@ -19,10 +19,10 @@ cgminer_LDADD = $(DLOPEN_FLAGS) @LIBCURL_LIBS@ @JANSSON_LIBS@ @PTHREAD_LIBS@ \
|
|||||||
@OPENCL_LIBS@ @NCURSES_LIBS@ @PDCURSES_LIBS@ @WS2_LIBS@ \
|
@OPENCL_LIBS@ @NCURSES_LIBS@ @PDCURSES_LIBS@ @WS2_LIBS@ \
|
||||||
@MM_LIBS@ @RT_LIBS@ @MATH_LIBS@ lib/libgnu.a ccan/libccan.a
|
@MM_LIBS@ @RT_LIBS@ @MATH_LIBS@ lib/libgnu.a ccan/libccan.a
|
||||||
|
|
||||||
if HAVE_WINDOWS
|
cgminer_CPPFLAGS += -I$(top_builddir)/lib -I$(top_srcdir)/lib @OPENCL_FLAGS@
|
||||||
cgminer_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib @OPENCL_FLAGS@
|
|
||||||
else
|
if !HAVE_WINDOWS
|
||||||
cgminer_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib @OPENCL_FLAGS@ @LIBCURL_CFLAGS@
|
cgminer_CPPFLAGS += @LIBCURL_CFLAGS@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
cgminer_CPPFLAGS += $(ADL_CPPFLAGS)
|
cgminer_CPPFLAGS += $(ADL_CPPFLAGS)
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Compile:
|
/* Compile:
|
||||||
* gcc api-example.c -Icompat/jansson -Icompat/libusb-1.0/libusb -o cgminer-api
|
* gcc api-example.c -Icompat/jansson-2.5 -Icompat/libusb-1.0/libusb -o cgminer-api
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
33
api.c
33
api.c
@ -587,6 +587,7 @@ static void io_free()
|
|||||||
do {
|
do {
|
||||||
io_next = io_list->next;
|
io_next = io_list->next;
|
||||||
|
|
||||||
|
free(io_list->io_data->ptr);
|
||||||
free(io_list->io_data);
|
free(io_list->io_data);
|
||||||
free(io_list);
|
free(io_list);
|
||||||
|
|
||||||
@ -1392,10 +1393,14 @@ uint64_t api_trylock(void *lock, const char *file, const char *func, const int l
|
|||||||
LOCKINFO *info;
|
LOCKINFO *info;
|
||||||
uint64_t id;
|
uint64_t id;
|
||||||
|
|
||||||
|
locklock();
|
||||||
|
|
||||||
info = findlock(lock, CGLOCK_UNKNOWN, file, func, linenum);
|
info = findlock(lock, CGLOCK_UNKNOWN, file, func, linenum);
|
||||||
id = lock_id++;
|
id = lock_id++;
|
||||||
addgettry(info, id, file, func, linenum, false);
|
addgettry(info, id, file, func, linenum, false);
|
||||||
|
|
||||||
|
lockunlock();
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3559,7 +3564,7 @@ static void mcast()
|
|||||||
|
|
||||||
count++;
|
count++;
|
||||||
came_from_siz = sizeof(came_from);
|
came_from_siz = sizeof(came_from);
|
||||||
if (SOCKETFAIL(rep = recvfrom(mcast_sock, buf, sizeof(buf),
|
if (SOCKETFAIL(rep = recvfrom(mcast_sock, buf, sizeof(buf) - 1,
|
||||||
0, (struct sockaddr *)(&came_from), &came_from_siz))) {
|
0, (struct sockaddr *)(&came_from), &came_from_siz))) {
|
||||||
applog(LOG_DEBUG, "API mcast failed count=%d (%s) (%d)",
|
applog(LOG_DEBUG, "API mcast failed count=%d (%s) (%d)",
|
||||||
count, SOCKERRMSG, (int)mcast_sock);
|
count, SOCKERRMSG, (int)mcast_sock);
|
||||||
@ -3663,12 +3668,12 @@ void api(int api_thr_id)
|
|||||||
struct sockaddr_in cli;
|
struct sockaddr_in cli;
|
||||||
socklen_t clisiz;
|
socklen_t clisiz;
|
||||||
char cmdbuf[100];
|
char cmdbuf[100];
|
||||||
char *cmd;
|
char *cmd = NULL;
|
||||||
char *param;
|
char *param;
|
||||||
bool addrok;
|
bool addrok;
|
||||||
char group;
|
char group;
|
||||||
json_error_t json_err;
|
json_error_t json_err;
|
||||||
json_t *json_config;
|
json_t *json_config = NULL;
|
||||||
json_t *json_val;
|
json_t *json_val;
|
||||||
bool isjson;
|
bool isjson;
|
||||||
bool did;
|
bool did;
|
||||||
@ -3681,6 +3686,7 @@ void api(int api_thr_id)
|
|||||||
|
|
||||||
if (!opt_api_listen) {
|
if (!opt_api_listen) {
|
||||||
applog(LOG_DEBUG, "API not running%s", UNAVAILABLE);
|
applog(LOG_DEBUG, "API not running%s", UNAVAILABLE);
|
||||||
|
free(apisock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3698,6 +3704,7 @@ void api(int api_thr_id)
|
|||||||
|
|
||||||
if (ips == 0) {
|
if (ips == 0) {
|
||||||
applog(LOG_WARNING, "API not running (no valid IPs specified)%s", UNAVAILABLE);
|
applog(LOG_WARNING, "API not running (no valid IPs specified)%s", UNAVAILABLE);
|
||||||
|
free(apisock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3709,6 +3716,7 @@ void api(int api_thr_id)
|
|||||||
*apisock = socket(AF_INET, SOCK_STREAM, 0);
|
*apisock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
if (*apisock == INVSOCK) {
|
if (*apisock == INVSOCK) {
|
||||||
applog(LOG_ERR, "API1 initialisation failed (%s)%s", SOCKERRMSG, UNAVAILABLE);
|
applog(LOG_ERR, "API1 initialisation failed (%s)%s", SOCKERRMSG, UNAVAILABLE);
|
||||||
|
free(apisock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3720,6 +3728,7 @@ void api(int api_thr_id)
|
|||||||
serv.sin_addr.s_addr = inet_addr(localaddr);
|
serv.sin_addr.s_addr = inet_addr(localaddr);
|
||||||
if (serv.sin_addr.s_addr == (in_addr_t)INVINETADDR) {
|
if (serv.sin_addr.s_addr == (in_addr_t)INVINETADDR) {
|
||||||
applog(LOG_ERR, "API2 initialisation failed (%s)%s", SOCKERRMSG, UNAVAILABLE);
|
applog(LOG_ERR, "API2 initialisation failed (%s)%s", SOCKERRMSG, UNAVAILABLE);
|
||||||
|
free(apisock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3758,12 +3767,14 @@ void api(int api_thr_id)
|
|||||||
|
|
||||||
if (bound == 0) {
|
if (bound == 0) {
|
||||||
applog(LOG_ERR, "API bind to port %d failed (%s)%s", port, binderror, UNAVAILABLE);
|
applog(LOG_ERR, "API bind to port %d failed (%s)%s", port, binderror, UNAVAILABLE);
|
||||||
|
free(apisock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SOCKETFAIL(listen(*apisock, QUEUE))) {
|
if (SOCKETFAIL(listen(*apisock, QUEUE))) {
|
||||||
applog(LOG_ERR, "API3 initialisation failed (%s)%s", SOCKERRMSG, UNAVAILABLE);
|
applog(LOG_ERR, "API3 initialisation failed (%s)%s", SOCKERRMSG, UNAVAILABLE);
|
||||||
CLOSESOCKET(*apisock);
|
CLOSESOCKET(*apisock);
|
||||||
|
free(apisock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3837,21 +3848,18 @@ void api(int api_thr_id)
|
|||||||
message(io_data, MSG_INVJSON, 0, NULL, isjson);
|
message(io_data, MSG_INVJSON, 0, NULL, isjson);
|
||||||
send_result(io_data, c, isjson);
|
send_result(io_data, c, isjson);
|
||||||
did = true;
|
did = true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
json_val = json_object_get(json_config, JSON_COMMAND);
|
json_val = json_object_get(json_config, JSON_COMMAND);
|
||||||
if (json_val == NULL) {
|
if (json_val == NULL) {
|
||||||
message(io_data, MSG_MISCMD, 0, NULL, isjson);
|
message(io_data, MSG_MISCMD, 0, NULL, isjson);
|
||||||
send_result(io_data, c, isjson);
|
send_result(io_data, c, isjson);
|
||||||
did = true;
|
did = true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (!json_is_string(json_val)) {
|
if (!json_is_string(json_val)) {
|
||||||
message(io_data, MSG_INVCMD, 0, NULL, isjson);
|
message(io_data, MSG_INVCMD, 0, NULL, isjson);
|
||||||
send_result(io_data, c, isjson);
|
send_result(io_data, c, isjson);
|
||||||
did = true;
|
did = true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
cmd = (char *)json_string_value(json_val);
|
cmd = (char *)json_string_value(json_val);
|
||||||
json_val = json_object_get(json_config, JSON_PARAMETER);
|
json_val = json_object_get(json_config, JSON_PARAMETER);
|
||||||
if (json_is_string(json_val))
|
if (json_is_string(json_val))
|
||||||
@ -3868,7 +3876,7 @@ void api(int api_thr_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!did)
|
if (!did) {
|
||||||
for (i = 0; cmds[i].name != NULL; i++) {
|
for (i = 0; cmds[i].name != NULL; i++) {
|
||||||
if (strcmp(cmd, cmds[i].name) == 0) {
|
if (strcmp(cmd, cmds[i].name) == 0) {
|
||||||
sprintf(cmdbuf, "|%s|", cmd);
|
sprintf(cmdbuf, "|%s|", cmd);
|
||||||
@ -3884,11 +3892,14 @@ void api(int api_thr_id)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!did) {
|
if (!did) {
|
||||||
message(io_data, MSG_INVCMD, 0, NULL, isjson);
|
message(io_data, MSG_INVCMD, 0, NULL, isjson);
|
||||||
send_result(io_data, c, isjson);
|
send_result(io_data, c, isjson);
|
||||||
}
|
}
|
||||||
|
if (isjson && json_is_object(json_config))
|
||||||
|
json_decref(json_config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CLOSESOCKET(c);
|
CLOSESOCKET(c);
|
||||||
@ -3900,6 +3911,8 @@ die:
|
|||||||
;
|
;
|
||||||
pthread_cleanup_pop(true);
|
pthread_cleanup_pop(true);
|
||||||
|
|
||||||
|
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!")));
|
||||||
|
194
cgminer.c
194
cgminer.c
@ -1615,13 +1615,15 @@ static void gen_gbt_work(struct pool *pool, struct work *work)
|
|||||||
{
|
{
|
||||||
unsigned char *merkleroot;
|
unsigned char *merkleroot;
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
|
uint64_t nonce2le;
|
||||||
|
|
||||||
cgtime(&now);
|
cgtime(&now);
|
||||||
if (now.tv_sec - pool->tv_lastwork.tv_sec > 60)
|
if (now.tv_sec - pool->tv_lastwork.tv_sec > 60)
|
||||||
update_gbt(pool);
|
update_gbt(pool);
|
||||||
|
|
||||||
cg_wlock(&pool->gbt_lock);
|
cg_wlock(&pool->gbt_lock);
|
||||||
memcpy(pool->coinbase + pool->nonce2_offset, &pool->nonce2, 4);
|
nonce2le = htole64(pool->nonce2);
|
||||||
|
memcpy(pool->coinbase + pool->nonce2_offset, &nonce2le, pool->n2size);
|
||||||
pool->nonce2++;
|
pool->nonce2++;
|
||||||
cg_dwlock(&pool->gbt_lock);
|
cg_dwlock(&pool->gbt_lock);
|
||||||
merkleroot = __gbt_merkleroot(pool);
|
merkleroot = __gbt_merkleroot(pool);
|
||||||
@ -1720,8 +1722,9 @@ static bool gbt_decode(struct pool *pool, json_t *res_val)
|
|||||||
free(pool->coinbasetxn);
|
free(pool->coinbasetxn);
|
||||||
pool->coinbasetxn = strdup(coinbasetxn);
|
pool->coinbasetxn = strdup(coinbasetxn);
|
||||||
cbt_len = strlen(pool->coinbasetxn) / 2;
|
cbt_len = strlen(pool->coinbasetxn) / 2;
|
||||||
pool->coinbase_len = cbt_len + 4;
|
/* We add 8 bytes of extra data corresponding to nonce2 */
|
||||||
/* We add 4 bytes of extra data corresponding to nonce2 of stratum */
|
pool->n2size = 8;
|
||||||
|
pool->coinbase_len = cbt_len + pool->n2size;
|
||||||
cal_len = pool->coinbase_len + 1;
|
cal_len = pool->coinbase_len + 1;
|
||||||
align_len(&cal_len);
|
align_len(&cal_len);
|
||||||
free(pool->coinbase);
|
free(pool->coinbase);
|
||||||
@ -1732,7 +1735,7 @@ static bool gbt_decode(struct pool *pool, json_t *res_val)
|
|||||||
extra_len = (uint8_t *)(pool->coinbase + 41);
|
extra_len = (uint8_t *)(pool->coinbase + 41);
|
||||||
orig_len = *extra_len;
|
orig_len = *extra_len;
|
||||||
hex2bin(pool->coinbase + 42, pool->coinbasetxn + 84, orig_len);
|
hex2bin(pool->coinbase + 42, pool->coinbasetxn + 84, orig_len);
|
||||||
*extra_len += 4;
|
*extra_len += pool->n2size;
|
||||||
hex2bin(pool->coinbase + 42 + *extra_len, pool->coinbasetxn + 84 + (orig_len * 2),
|
hex2bin(pool->coinbase + 42 + *extra_len, pool->coinbasetxn + 84 + (orig_len * 2),
|
||||||
cbt_len - orig_len - 42);
|
cbt_len - orig_len - 42);
|
||||||
pool->nonce2_offset = orig_len + 42;
|
pool->nonce2_offset = orig_len + 42;
|
||||||
@ -3350,6 +3353,17 @@ static void _copy_work(struct work *work, const struct work *base_work, int noff
|
|||||||
work->coinbase = strdup(base_work->coinbase);
|
work->coinbase = strdup(base_work->coinbase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_work_ntime(struct work *work, int ntime)
|
||||||
|
{
|
||||||
|
uint32_t *work_ntime = (uint32_t *)(work->data + 68);
|
||||||
|
|
||||||
|
*work_ntime = htobe32(ntime);
|
||||||
|
if (work->ntime) {
|
||||||
|
free(work->ntime);
|
||||||
|
work->ntime = bin2hex((unsigned char *)work_ntime, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Generates a copy of an existing work struct, creating fresh heap allocations
|
/* Generates a copy of an existing work struct, creating fresh heap allocations
|
||||||
* for all dynamically allocated arrays within the struct. noffset is used for
|
* for all dynamically allocated arrays within the struct. noffset is used for
|
||||||
* when a driver has internally rolled the ntime, noffset is a relative value.
|
* when a driver has internally rolled the ntime, noffset is a relative value.
|
||||||
@ -3660,11 +3674,13 @@ int restart_wait(struct thr_info *thr, unsigned int mstime)
|
|||||||
|
|
||||||
static void flush_queue(struct cgpu_info *cgpu);
|
static void flush_queue(struct cgpu_info *cgpu);
|
||||||
|
|
||||||
static void restart_threads(void)
|
static void *restart_thread(void __maybe_unused *arg)
|
||||||
{
|
{
|
||||||
struct pool *cp = current_pool();
|
struct pool *cp = current_pool();
|
||||||
struct cgpu_info *cgpu;
|
struct cgpu_info *cgpu;
|
||||||
int i;
|
int i, mt;
|
||||||
|
|
||||||
|
pthread_detach(pthread_self());
|
||||||
|
|
||||||
/* Artificially set the lagging flag to avoid pool not providing work
|
/* Artificially set the lagging flag to avoid pool not providing work
|
||||||
* fast enough messages after every long poll */
|
* fast enough messages after every long poll */
|
||||||
@ -3674,19 +3690,35 @@ static void restart_threads(void)
|
|||||||
discard_stale();
|
discard_stale();
|
||||||
|
|
||||||
rd_lock(&mining_thr_lock);
|
rd_lock(&mining_thr_lock);
|
||||||
for (i = 0; i < mining_threads; i++) {
|
mt = mining_threads;
|
||||||
|
rd_unlock(&mining_thr_lock);
|
||||||
|
|
||||||
|
for (i = 0; i < mt; i++) {
|
||||||
cgpu = mining_thr[i]->cgpu;
|
cgpu = mining_thr[i]->cgpu;
|
||||||
if (unlikely(!cgpu))
|
if (unlikely(!cgpu))
|
||||||
continue;
|
continue;
|
||||||
|
if (cgpu->deven != DEV_ENABLED)
|
||||||
|
continue;
|
||||||
mining_thr[i]->work_restart = true;
|
mining_thr[i]->work_restart = true;
|
||||||
flush_queue(cgpu);
|
flush_queue(cgpu);
|
||||||
cgpu->drv->flush_work(cgpu);
|
cgpu->drv->flush_work(cgpu);
|
||||||
}
|
}
|
||||||
rd_unlock(&mining_thr_lock);
|
|
||||||
|
|
||||||
mutex_lock(&restart_lock);
|
mutex_lock(&restart_lock);
|
||||||
pthread_cond_broadcast(&restart_cond);
|
pthread_cond_broadcast(&restart_cond);
|
||||||
mutex_unlock(&restart_lock);
|
mutex_unlock(&restart_lock);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In order to prevent a deadlock via the various drv->flush_work
|
||||||
|
* implementations we send the restart messages via a separate thread. */
|
||||||
|
static void restart_threads(void)
|
||||||
|
{
|
||||||
|
pthread_t rthread;
|
||||||
|
|
||||||
|
if (unlikely(pthread_create(&rthread, NULL, restart_thread, NULL)))
|
||||||
|
quit(1, "Failed to create restart thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void signal_work_update(void)
|
static void signal_work_update(void)
|
||||||
@ -4299,6 +4331,30 @@ void zero_stats(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_highprio(void)
|
||||||
|
{
|
||||||
|
#ifndef WIN32
|
||||||
|
int ret = nice(-10);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
applog(LOG_DEBUG, "Unable to set thread to high priority");
|
||||||
|
#else
|
||||||
|
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_lowprio(void)
|
||||||
|
{
|
||||||
|
#ifndef WIN32
|
||||||
|
int ret = nice(10);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
applog(LOG_INFO, "Unable to set thread to low priority");
|
||||||
|
#else
|
||||||
|
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_CURSES
|
#ifdef HAVE_CURSES
|
||||||
static void display_pools(void)
|
static void display_pools(void)
|
||||||
{
|
{
|
||||||
@ -4706,6 +4762,7 @@ static void *api_thread(void *userdata)
|
|||||||
|
|
||||||
RenameThread("api");
|
RenameThread("api");
|
||||||
|
|
||||||
|
set_lowprio();
|
||||||
api(api_thr_id);
|
api(api_thr_id);
|
||||||
|
|
||||||
PTH(mythr) = 0L;
|
PTH(mythr) = 0L;
|
||||||
@ -5195,10 +5252,11 @@ static void *stratum_sthread(void *userdata)
|
|||||||
quit(1, "Failed to create stratum_q in stratum_sthread");
|
quit(1, "Failed to create stratum_q in stratum_sthread");
|
||||||
|
|
||||||
while (42) {
|
while (42) {
|
||||||
char noncehex[12], nonce2hex[20];
|
char noncehex[12], nonce2hex[20], s[1024];
|
||||||
struct stratum_share *sshare;
|
struct stratum_share *sshare;
|
||||||
uint32_t *hash32, nonce;
|
uint32_t *hash32, nonce;
|
||||||
char s[1024], nonce2[8];
|
unsigned char nonce2[8];
|
||||||
|
uint64_t *nonce2_64;
|
||||||
struct work *work;
|
struct work *work;
|
||||||
bool submitted;
|
bool submitted;
|
||||||
|
|
||||||
@ -5233,10 +5291,9 @@ static void *stratum_sthread(void *userdata)
|
|||||||
sshare->id = swork_id++;
|
sshare->id = swork_id++;
|
||||||
mutex_unlock(&sshare_lock);
|
mutex_unlock(&sshare_lock);
|
||||||
|
|
||||||
memset(nonce2, 0, 8);
|
nonce2_64 = (uint64_t *)nonce2;
|
||||||
/* We only use uint32_t sized nonce2 increments internally */
|
*nonce2_64 = htole64(work->nonce2);
|
||||||
memcpy(nonce2, &work->nonce2, sizeof(uint32_t));
|
__bin2hex(nonce2hex, nonce2, work->nonce2_len);
|
||||||
__bin2hex(nonce2hex, (const unsigned char *)nonce2, work->nonce2_len);
|
|
||||||
|
|
||||||
snprintf(s, sizeof(s),
|
snprintf(s, sizeof(s),
|
||||||
"{\"params\": [\"%s\", \"%s\", \"%s\", \"%s\", \"%s\"], \"id\": %d, \"method\": \"mining.submit\"}",
|
"{\"params\": [\"%s\", \"%s\", \"%s\", \"%s\", \"%s\"], \"id\": %d, \"method\": \"mining.submit\"}",
|
||||||
@ -5368,7 +5425,7 @@ retry_stratum:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Probe for GBT support on first pass */
|
/* Probe for GBT support on first pass */
|
||||||
if (!pool->probed && !opt_fix_protocol) {
|
if (!pool->probed) {
|
||||||
applog(LOG_DEBUG, "Probing for GBT support");
|
applog(LOG_DEBUG, "Probing for GBT support");
|
||||||
val = json_rpc_call(curl, pool->rpc_url, pool->rpc_userpass,
|
val = json_rpc_call(curl, pool->rpc_url, pool->rpc_userpass,
|
||||||
gbt_req, true, false, &rolltime, pool, false);
|
gbt_req, true, false, &rolltime, pool, false);
|
||||||
@ -5641,12 +5698,15 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
|
|||||||
{
|
{
|
||||||
unsigned char merkle_root[32], merkle_sha[64];
|
unsigned char merkle_root[32], merkle_sha[64];
|
||||||
uint32_t *data32, *swap32;
|
uint32_t *data32, *swap32;
|
||||||
|
uint64_t nonce2le;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
cg_wlock(&pool->data_lock);
|
cg_wlock(&pool->data_lock);
|
||||||
|
|
||||||
/* Update coinbase */
|
/* Update coinbase. Always use an LE encoded nonce2 to fill in values
|
||||||
memcpy(pool->coinbase + pool->nonce2_offset, &pool->nonce2, sizeof(uint32_t));
|
* from left to right and prevent overflow errors with small n2sizes */
|
||||||
|
nonce2le = htole64(pool->nonce2);
|
||||||
|
memcpy(pool->coinbase + pool->nonce2_offset, &nonce2le, pool->n2size);
|
||||||
work->nonce2 = pool->nonce2++;
|
work->nonce2 = pool->nonce2++;
|
||||||
work->nonce2_len = pool->n2size;
|
work->nonce2_len = pool->n2size;
|
||||||
|
|
||||||
@ -5686,7 +5746,8 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
|
|||||||
merkle_hash = bin2hex((const unsigned char *)merkle_root, 32);
|
merkle_hash = bin2hex((const unsigned char *)merkle_root, 32);
|
||||||
applog(LOG_DEBUG, "Generated stratum merkle %s", merkle_hash);
|
applog(LOG_DEBUG, "Generated stratum merkle %s", merkle_hash);
|
||||||
applog(LOG_DEBUG, "Generated stratum header %s", header);
|
applog(LOG_DEBUG, "Generated stratum header %s", header);
|
||||||
applog(LOG_DEBUG, "Work job_id %s nonce2 %d ntime %s", work->job_id, work->nonce2, work->ntime);
|
applog(LOG_DEBUG, "Work job_id %s nonce2 %"PRIu64" ntime %s", work->job_id,
|
||||||
|
work->nonce2, work->ntime);
|
||||||
free(header);
|
free(header);
|
||||||
free(merkle_hash);
|
free(merkle_hash);
|
||||||
}
|
}
|
||||||
@ -6197,6 +6258,30 @@ void __work_completed(struct cgpu_info *cgpu, struct work *work)
|
|||||||
cgpu->queued_count--;
|
cgpu->queued_count--;
|
||||||
HASH_DEL(cgpu->queued_work, work);
|
HASH_DEL(cgpu->queued_work, work);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This iterates over a queued hashlist finding work started more than secs
|
||||||
|
* seconds ago and discards the work as completed. The driver must set the
|
||||||
|
* work->tv_work_start value appropriately. Returns the number of items aged. */
|
||||||
|
int age_queued_work(struct cgpu_info *cgpu, double secs)
|
||||||
|
{
|
||||||
|
struct work *work, *tmp;
|
||||||
|
struct timeval tv_now;
|
||||||
|
int aged = 0;
|
||||||
|
|
||||||
|
cgtime(&tv_now);
|
||||||
|
|
||||||
|
wr_lock(&cgpu->qlock);
|
||||||
|
HASH_ITER(hh, cgpu->queued_work, work, tmp) {
|
||||||
|
if (tdiff(&tv_now, &work->tv_work_start) > secs) {
|
||||||
|
__work_completed(cgpu, work);
|
||||||
|
aged++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wr_unlock(&cgpu->qlock);
|
||||||
|
|
||||||
|
return aged;
|
||||||
|
}
|
||||||
|
|
||||||
/* This function should be used by queued device drivers when they're sure
|
/* This function should be used by queued device drivers when they're sure
|
||||||
* the work struct is no longer in use. */
|
* the work struct is no longer in use. */
|
||||||
void work_completed(struct cgpu_info *cgpu, struct work *work)
|
void work_completed(struct cgpu_info *cgpu, struct work *work)
|
||||||
@ -6368,6 +6453,7 @@ void *miner_thread(void *userdata)
|
|||||||
applog(LOG_DEBUG, "Waiting on sem in miner thread");
|
applog(LOG_DEBUG, "Waiting on sem in miner thread");
|
||||||
cgsem_wait(&mythr->sem);
|
cgsem_wait(&mythr->sem);
|
||||||
|
|
||||||
|
set_highprio();
|
||||||
drv->hash_work(mythr);
|
drv->hash_work(mythr);
|
||||||
out:
|
out:
|
||||||
drv->thread_shutdown(mythr);
|
drv->thread_shutdown(mythr);
|
||||||
@ -6646,6 +6732,8 @@ static void *watchpool_thread(void __maybe_unused *userdata)
|
|||||||
|
|
||||||
RenameThread("watchpool");
|
RenameThread("watchpool");
|
||||||
|
|
||||||
|
set_lowprio();
|
||||||
|
|
||||||
while (42) {
|
while (42) {
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
int i;
|
int i;
|
||||||
@ -6729,6 +6817,7 @@ static void *watchdog_thread(void __maybe_unused *userdata)
|
|||||||
|
|
||||||
RenameThread("watchdog");
|
RenameThread("watchdog");
|
||||||
|
|
||||||
|
set_lowprio();
|
||||||
memset(&zero_tv, 0, sizeof(struct timeval));
|
memset(&zero_tv, 0, sizeof(struct timeval));
|
||||||
cgtime(&rotate_tv);
|
cgtime(&rotate_tv);
|
||||||
|
|
||||||
@ -7719,6 +7808,37 @@ int main(int argc, char *argv[])
|
|||||||
quit(1, "Failed to calloc mining_thr[%d]", i);
|
quit(1, "Failed to calloc mining_thr[%d]", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start threads
|
||||||
|
k = 0;
|
||||||
|
for (i = 0; i < total_devices; ++i) {
|
||||||
|
struct cgpu_info *cgpu = devices[i];
|
||||||
|
cgpu->thr = malloc(sizeof(*cgpu->thr) * (cgpu->threads+1));
|
||||||
|
cgpu->thr[cgpu->threads] = NULL;
|
||||||
|
cgpu->status = LIFE_INIT;
|
||||||
|
|
||||||
|
for (j = 0; j < cgpu->threads; ++j, ++k) {
|
||||||
|
thr = get_thread(k);
|
||||||
|
thr->id = k;
|
||||||
|
thr->cgpu = cgpu;
|
||||||
|
thr->device_thread = j;
|
||||||
|
|
||||||
|
if (!cgpu->drv->thread_prepare(thr))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (unlikely(thr_info_create(thr, NULL, miner_thread, thr)))
|
||||||
|
quit(1, "thread %d create failed", thr->id);
|
||||||
|
|
||||||
|
cgpu->thr[j] = thr;
|
||||||
|
|
||||||
|
/* Enable threads for devices set not to mine but disable
|
||||||
|
* their queue in case we wish to enable them later */
|
||||||
|
if (cgpu->deven != DEV_DISABLED) {
|
||||||
|
applog(LOG_DEBUG, "Pushing sem post to thread %d", thr->id);
|
||||||
|
cgsem_post(&thr->sem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (opt_benchmark)
|
if (opt_benchmark)
|
||||||
goto begin_bench;
|
goto begin_bench;
|
||||||
|
|
||||||
@ -7776,44 +7896,6 @@ begin_bench:
|
|||||||
cgtime(&total_tv_end);
|
cgtime(&total_tv_end);
|
||||||
get_datestamp(datestamp, sizeof(datestamp), &total_tv_start);
|
get_datestamp(datestamp, sizeof(datestamp), &total_tv_start);
|
||||||
|
|
||||||
// Start threads
|
|
||||||
k = 0;
|
|
||||||
for (i = 0; i < total_devices; ++i) {
|
|
||||||
struct cgpu_info *cgpu = devices[i];
|
|
||||||
cgpu->thr = malloc(sizeof(*cgpu->thr) * (cgpu->threads+1));
|
|
||||||
cgpu->thr[cgpu->threads] = NULL;
|
|
||||||
cgpu->status = LIFE_INIT;
|
|
||||||
|
|
||||||
for (j = 0; j < cgpu->threads; ++j, ++k) {
|
|
||||||
thr = get_thread(k);
|
|
||||||
thr->id = k;
|
|
||||||
thr->cgpu = cgpu;
|
|
||||||
thr->device_thread = j;
|
|
||||||
|
|
||||||
if (!cgpu->drv->thread_prepare(thr))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (unlikely(thr_info_create(thr, NULL, miner_thread, thr)))
|
|
||||||
quit(1, "thread %d create failed", thr->id);
|
|
||||||
|
|
||||||
cgpu->thr[j] = thr;
|
|
||||||
|
|
||||||
/* Enable threads for devices set not to mine but disable
|
|
||||||
* their queue in case we wish to enable them later */
|
|
||||||
if (cgpu->deven != DEV_DISABLED) {
|
|
||||||
applog(LOG_DEBUG, "Pushing sem post to thread %d", thr->id);
|
|
||||||
cgsem_post(&thr->sem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
applog(LOG_INFO, "%d gpu miner threads started", gpu_threads);
|
|
||||||
for (i = 0; i < nDevs; i++)
|
|
||||||
pause_dynamic_threads(i);
|
|
||||||
|
|
||||||
cgtime(&total_tv_start);
|
|
||||||
cgtime(&total_tv_end);
|
|
||||||
|
|
||||||
watchpool_thr_id = 2;
|
watchpool_thr_id = 2;
|
||||||
thr = &control_thr[watchpool_thr_id];
|
thr = &control_thr[watchpool_thr_id];
|
||||||
/* start watchpool thread */
|
/* start watchpool thread */
|
||||||
|
@ -4,6 +4,7 @@ AC_INIT([jansson], [2.5], [petri@digip.org])
|
|||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
|
||||||
AM_INIT_AUTOMAKE([1.10 foreign])
|
AM_INIT_AUTOMAKE([1.10 foreign])
|
||||||
|
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||||
|
|
||||||
AC_CONFIG_SRCDIR([src/value.c])
|
AC_CONFIG_SRCDIR([src/value.c])
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
|
6
miner.h
6
miner.h
@ -1234,7 +1234,7 @@ struct pool {
|
|||||||
char *nonce1;
|
char *nonce1;
|
||||||
unsigned char *nonce1bin;
|
unsigned char *nonce1bin;
|
||||||
size_t n1_len;
|
size_t n1_len;
|
||||||
uint32_t nonce2;
|
uint64_t nonce2;
|
||||||
int n2size;
|
int n2size;
|
||||||
char *sessionid;
|
char *sessionid;
|
||||||
bool has_stratum;
|
bool has_stratum;
|
||||||
@ -1311,7 +1311,7 @@ struct work {
|
|||||||
|
|
||||||
bool stratum;
|
bool stratum;
|
||||||
char *job_id;
|
char *job_id;
|
||||||
uint32_t nonce2;
|
uint64_t nonce2;
|
||||||
size_t nonce2_len;
|
size_t nonce2_len;
|
||||||
char *ntime;
|
char *ntime;
|
||||||
double sdiff;
|
double sdiff;
|
||||||
@ -1368,6 +1368,7 @@ extern struct work *__find_work_bymidstate(struct work *que, char *midstate, siz
|
|||||||
extern struct work *find_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
|
extern struct work *find_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
|
||||||
extern struct work *clone_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
|
extern struct work *clone_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
|
||||||
extern void __work_completed(struct cgpu_info *cgpu, struct work *work);
|
extern void __work_completed(struct cgpu_info *cgpu, struct work *work);
|
||||||
|
extern int age_queued_work(struct cgpu_info *cgpu, double secs);
|
||||||
extern void work_completed(struct cgpu_info *cgpu, struct work *work);
|
extern void work_completed(struct cgpu_info *cgpu, struct work *work);
|
||||||
extern struct work *take_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
|
extern struct work *take_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
|
||||||
extern void hash_driver_work(struct thr_info *mythr);
|
extern void hash_driver_work(struct thr_info *mythr);
|
||||||
@ -1399,6 +1400,7 @@ extern void adl(void);
|
|||||||
extern void app_restart(void);
|
extern void app_restart(void);
|
||||||
extern void clean_work(struct work *work);
|
extern void clean_work(struct work *work);
|
||||||
extern void free_work(struct work *work);
|
extern void free_work(struct work *work);
|
||||||
|
extern void set_work_ntime(struct work *work, int ntime);
|
||||||
extern struct work *copy_work_noffset(struct work *base_work, int noffset);
|
extern struct work *copy_work_noffset(struct work *base_work, int noffset);
|
||||||
#define copy_work(work_in) copy_work_noffset(work_in, 0)
|
#define copy_work(work_in) copy_work_noffset(work_in, 0)
|
||||||
extern struct thr_info *get_thread(int thr_id);
|
extern struct thr_info *get_thread(int thr_id);
|
||||||
|
@ -2910,7 +2910,7 @@ function display()
|
|||||||
|
|
||||||
if ($allowcustompages === true)
|
if ($allowcustompages === true)
|
||||||
{
|
{
|
||||||
$pg = trim(getparam('pg', true));
|
$pg = urlencode(trim(getparam('pg', true)));
|
||||||
if ($pagesonly === true)
|
if ($pagesonly === true)
|
||||||
{
|
{
|
||||||
if ($pg !== null && $pg !== '')
|
if ($pg !== null && $pg !== '')
|
||||||
|
30
util.c
30
util.c
@ -1837,7 +1837,7 @@ bool auth_stratum(struct pool *pool)
|
|||||||
ss = json_dumps(err_val, JSON_INDENT(3));
|
ss = json_dumps(err_val, JSON_INDENT(3));
|
||||||
else
|
else
|
||||||
ss = strdup("(unknown reason)");
|
ss = strdup("(unknown reason)");
|
||||||
applog(LOG_WARNING, "pool %d JSON stratum auth failed: %s", pool->pool_no, ss);
|
applog(LOG_INFO, "pool %d JSON stratum auth failed: %s", pool->pool_no, ss);
|
||||||
free(ss);
|
free(ss);
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
@ -2599,6 +2599,25 @@ int _cgsem_mswait(cgsem_t *cgsem, int ms, const char *file, const char *func, co
|
|||||||
/* We don't reach here */
|
/* We don't reach here */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reset semaphore count back to zero */
|
||||||
|
void cgsem_reset(cgsem_t *cgsem)
|
||||||
|
{
|
||||||
|
int ret, fd;
|
||||||
|
fd_set rd;
|
||||||
|
char buf;
|
||||||
|
|
||||||
|
fd = cgsem->pipefd[0];
|
||||||
|
FD_ZERO(&rd);
|
||||||
|
FD_SET(fd, &rd);
|
||||||
|
do {
|
||||||
|
struct timeval timeout = {0, 0};
|
||||||
|
|
||||||
|
ret = select(fd + 1, &rd, NULL, NULL, &timeout);
|
||||||
|
if (ret > 0)
|
||||||
|
ret = read(fd, &buf, 1);
|
||||||
|
} while (ret > 0);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
void _cgsem_init(cgsem_t *cgsem, const char *file, const char *func, const int line)
|
void _cgsem_init(cgsem_t *cgsem, const char *file, const char *func, const int line)
|
||||||
{
|
{
|
||||||
@ -2639,6 +2658,15 @@ int _cgsem_mswait(cgsem_t *cgsem, int ms, const char *file, const char *func, co
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cgsem_reset(cgsem_t *cgsem)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
do {
|
||||||
|
ret = sem_trywait(cgsem);
|
||||||
|
} while (!ret);
|
||||||
|
}
|
||||||
|
|
||||||
void cgsem_destroy(cgsem_t *cgsem)
|
void cgsem_destroy(cgsem_t *cgsem)
|
||||||
{
|
{
|
||||||
sem_destroy(cgsem);
|
sem_destroy(cgsem);
|
||||||
|
1
util.h
1
util.h
@ -138,6 +138,7 @@ void _cgsem_init(cgsem_t *cgsem, const char *file, const char *func, const int l
|
|||||||
void _cgsem_post(cgsem_t *cgsem, const char *file, const char *func, const int line);
|
void _cgsem_post(cgsem_t *cgsem, const char *file, const char *func, const int line);
|
||||||
void _cgsem_wait(cgsem_t *cgsem, const char *file, const char *func, const int line);
|
void _cgsem_wait(cgsem_t *cgsem, const char *file, const char *func, const int line);
|
||||||
int _cgsem_mswait(cgsem_t *cgsem, int ms, const char *file, const char *func, const int line);
|
int _cgsem_mswait(cgsem_t *cgsem, int ms, const char *file, const char *func, const int line);
|
||||||
|
void cgsem_reset(cgsem_t *cgsem);
|
||||||
void cgsem_destroy(cgsem_t *cgsem);
|
void cgsem_destroy(cgsem_t *cgsem);
|
||||||
bool cg_completion_timeout(void *fn, void *fnarg, int timeout);
|
bool cg_completion_timeout(void *fn, void *fnarg, int timeout);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user