Browse Source

Merge remote-tracking branch 'origin/port-ckolivas' into build-mingw

Conflicts (resolved):
	NEWS.md
	logging.h
	sgminer.c
build-mingw
Noel Maersk 11 years ago
parent
commit
bafc71345c
  1. 2
      NEWS.md
  2. 27
      README.md
  3. 2
      api.c
  4. 5
      autogen.sh
  5. 33
      doc/API
  6. 20
      logging.c
  7. 1
      logging.h
  8. 2
      miner.h
  9. 127
      miner.php
  10. 217
      sgminer.c

2
NEWS.md

@ -13,6 +13,8 @@
* Multiple `--name` parsing should now work as expected (by _troky_). * Multiple `--name` parsing should now work as expected (by _troky_).
* `--coin` configuration parameter to specify a freeform pool * `--coin` configuration parameter to specify a freeform pool
description (by _troky_). description (by _troky_).
* Forward-port changes from `ckolivas/cgminer` slightly after 3.12.3
(up to 133252175b90159d18151b004bf767d5a43812ea).
## Version 4.1.153 - 14th March 2014 ## Version 4.1.153 - 14th March 2014

27
README.md

@ -460,3 +460,30 @@ For example (this is wrapped, but it's all on one line for real):
000000004a4366808f81d44f26df3d69d7dc4b3473385930462d9ab707b50498 000000004a4366808f81d44f26df3d69d7dc4b3473385930462d9ab707b50498
f681634a4f1f63d01a0cd43fb338000000000080000000000000000000000000 f681634a4f1f63d01a0cd43fb338000000000080000000000000000000000000
0000000000000000000000000000000000000000000000000000000080020000 0000000000000000000000000000000000000000000000000000000080020000
## Benchmark
The --benchmark option hashes a single fixed work item over and over and does
not submit shares to any pools.
The --benchfile <arg> option hashes the work given in the file <arg> supplied.
The format of the work file is:
version,merkleroot,prevhash,diffbits,noncetime
Any empty line or any line starting with '#' or '/' is ignored.
When it reaches the end of the file it continues back at the top.
The format of the data items matches the byte ordering and format of the
the bitcoind getblock RPC output.
An example file containing bitcoin block #1 would be:
# Block 1
1,0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098,00000000001
9d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f,1d00ffff,1231469665
However, the work data should be one line without the linebreak in the middle
If you use --benchfile <arg>, then --benchfile-display will output a log line,
for each nonce found, showing the nonce value in decimal and hex and the work
used to find it in hex.

2
api.c

@ -3738,7 +3738,7 @@ void api(int api_thr_id)
json_t *json_config = NULL; json_t *json_config = NULL;
json_t *json_val; json_t *json_val;
bool isjson; bool isjson;
bool did, isjoin, firstjoin; bool did, isjoin = false, firstjoin;
int i; int i;
SOCKETTYPE *apisock; SOCKETTYPE *apisock;

5
autogen.sh

@ -4,3 +4,8 @@ bs_dir="$(dirname $(readlink -f $0))"
#Some versions of libtoolize don't like there being no ltmain.sh file already #Some versions of libtoolize don't like there being no ltmain.sh file already
touch "${bs_dir}"/ltmain.sh touch "${bs_dir}"/ltmain.sh
autoreconf -fi "${bs_dir}" autoreconf -fi "${bs_dir}"
if test -n "$1" && test -z "$NOCONFIGURE" ; then
echo 'Configuring...'
"$bs_dir"/configure "$@"
fi

33
doc/API

@ -1270,20 +1270,49 @@ However, if $readonly is true, it will not display them
--------- ---------
Default:
$rigport = 4028;
Default port to use if any $rigs entries don't specify the port number
---------
Default: Default:
$rigs = array('127.0.0.1:4028'); $rigs = array('127.0.0.1:4028');
Set $rigs to an array of your sgminer rigs that are running Set $rigs to an array of your rigs that are running
format: 'IP:Port' or 'Host:Port' or 'Host:Port:Name' format: 'IP' or 'Host' or 'IP:Port' or 'Host:Port' or 'Host:Port:Name'
If you only have one rig, it will just show the detail of that rig If you only have one rig, it will just show the detail of that rig
If you have more than one rig it will show a summary of all the rigs If you have more than one rig it will show a summary of all the rigs
with buttons to show the details of each rig - with buttons to show the details of each rig -
the button contents will be 'Name' rather than rig number, if you the button contents will be 'Name' rather than rig number, if you
specify 'Name' specify 'Name'
If Port is missing or blank, it will try $rigport
e.g. $rigs = array('127.0.0.1:4028','myrig.com:4028:Sugoi'); e.g. $rigs = array('127.0.0.1:4028','myrig.com:4028:Sugoi');
--------- ---------
Default:
$rignames = false;
Set $rignames to false to not affect the display.
Set $rignames to one of 'ip' or 'ipx' to alter the name displayed
if the rig doesn't have a 'name' in $rigs
Currently:
'ip' means use the 4th byte of the rig IP address as an integer
'ipx' means use the 4th byte of the rig IP address as 2 hex bytes
---------
Default:
$rigbuttons = true;
Set $rigbuttons to false to display a link rather than a button on
the left of any summary table with rig buttons, in order to reduce
the height of the table cells
---------
Default: Default:
$mcast = false; $mcast = false;

20
logging.c

@ -124,3 +124,23 @@ void _applog(int prio, const char *str, bool force)
my_log_curses(prio, datetime, str, force); my_log_curses(prio, datetime, str, force);
} }
} }
void _simplelog(int prio, const char *str, bool force)
{
#ifdef HAVE_SYSLOG_H
if (use_syslog) {
syslog(prio, "%s", str);
}
#else
if (0) {}
#endif
else {
/* Only output to stderr if it's not going to the screen as well */
if (!isatty(fileno((FILE *)stderr))) {
fprintf(stderr, "%s\n", str); /* atomic write to stderr */
fflush(stderr);
}
my_log_curses(prio, "", str, force);
}
}

1
logging.h

@ -32,6 +32,7 @@ extern int opt_log_show_date;
void applog(int prio, const char* fmt, ...); void applog(int prio, const char* fmt, ...);
extern void _applog(int prio, const char *str, bool force); extern void _applog(int prio, const char *str, bool force);
extern void _simplelog(int prio, const char *str, bool force);
#define IN_FMT_FFL " in %s %s():%d" #define IN_FMT_FFL " in %s %s():%d"

2
miner.h

@ -161,6 +161,7 @@ static inline int fsync (int fd)
#ifndef htobe32 #ifndef htobe32
# if __BYTE_ORDER == __LITTLE_ENDIAN # if __BYTE_ORDER == __LITTLE_ENDIAN
# define htole16(x) (x) # define htole16(x) (x)
# define le16toh(x) (x)
# define htole32(x) (x) # define htole32(x) (x)
# define htole64(x) (x) # define htole64(x) (x)
# define le32toh(x) (x) # define le32toh(x) (x)
@ -171,6 +172,7 @@ static inline int fsync (int fd)
# define htobe64(x) bswap_64(x) # define htobe64(x) bswap_64(x)
# elif __BYTE_ORDER == __BIG_ENDIAN # elif __BYTE_ORDER == __BIG_ENDIAN
# define htole16(x) bswap_16(x) # define htole16(x) bswap_16(x)
# define le16toh(x) bswap_16(x)
# define htole32(x) bswap_32(x) # define htole32(x) bswap_32(x)
# define le32toh(x) bswap_32(x) # define le32toh(x) bswap_32(x)
# define le64toh(x) bswap_64(x) # define le64toh(x) bswap_64(x)

127
miner.php

@ -1,7 +1,8 @@
<?php <?php
session_start(); session_start();
# #
global $doctype, $title, $miner, $port, $readonly, $notify, $rigs; global $doctype, $title, $miner, $port, $readonly, $notify;
global $rigport, $rigs, $rignames, $rigbuttons;
global $mcast, $mcastexpect, $mcastaddr, $mcastport, $mcastcode; global $mcast, $mcastexpect, $mcastaddr, $mcastport, $mcastcode;
global $mcastlistport, $mcasttimeout, $mcastretries, $allowgen; global $mcastlistport, $mcasttimeout, $mcastretries, $allowgen;
global $rigipsecurity, $rigtotals, $forcerigtotals; global $rigipsecurity, $rigtotals, $forcerigtotals;
@ -44,10 +45,20 @@ $checklastshare = true;
# N.B. also if $readonly is true, it will not display the fields # N.B. also if $readonly is true, it will not display the fields
$poolinputs = false; $poolinputs = false;
# #
# Set $rigs to an array of your sgminer rigs that are running # Default port to use if any $rigs entries don't specify the port number
# format: 'IP:Port' or 'Host:Port' or 'Host:Port:Name' $rigport = 4028;
#
# Set $rigs to an array of your rigs that are running
# format: 'IP' or 'Host' or 'IP:Port' or 'Host:Port' or 'Host:Port:Name'
$rigs = array('127.0.0.1:4028'); $rigs = array('127.0.0.1:4028');
# #
# Set $rignames to false, or one of 'ip' or 'ipx'
# this says what to use if $rigs doesn't have a 'name'
$rignames = false;
#
# Set $rigbuttons to false to display a link rather than a button
$rigbuttons = true;
#
# Set $mcast to true to look for your rigs and ignore $rigs # Set $mcast to true to look for your rigs and ignore $rigs
$mcast = false; $mcast = false;
# #
@ -247,6 +258,9 @@ $colourtable = array(
$miner = null; $miner = null;
$port = null; $port = null;
# #
global $rigips;
$rigips = array();
#
# Ensure it is only ever shown once # Ensure it is only ever shown once
global $showndate; global $showndate;
$showndate = false; $showndate = false;
@ -289,6 +303,14 @@ function getdom($domname)
return getcss($domname, true); return getcss($domname, true);
} }
# #
# N.B. don't call this before calling htmlhead()
function php_pr($cmd)
{
global $here, $autorefresh;
return "$here?ref=$autorefresh$cmd";
}
#
function htmlhead($mcerr, $checkapi, $rig, $pg = null, $noscript = false) function htmlhead($mcerr, $checkapi, $rig, $pg = null, $noscript = false)
{ {
global $doctype, $title, $miner_font_family, $miner_font_size; global $doctype, $title, $miner_font_family, $miner_font_size;
@ -491,9 +513,12 @@ function getrigs()
# #
function getsock($rig, $addr, $port) function getsock($rig, $addr, $port)
{ {
global $rigipsecurity; global $rigport, $rigips, $rignames, $rigipsecurity;
global $haderror, $error, $socksndtimeoutsec, $sockrcvtimeoutsec; global $haderror, $error, $socksndtimeoutsec, $sockrcvtimeoutsec;
$port = trim($port);
if (strlen($port) == 0)
$port = $rigport;
$error = null; $error = null;
$socket = null; $socket = null;
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
@ -534,6 +559,9 @@ function getsock($rig, $addr, $port)
socket_close($socket); socket_close($socket);
return null; return null;
} }
if ($rignames !== false && !isset($rigips[$addr]))
if (socket_getpeername($socket, $ip) == true)
$rigips[$addr] = $ip;
return $socket; return $socket;
} }
# #
@ -1536,39 +1564,67 @@ function process($cmds, $rig)
# #
function rigname($rig, $rigname) function rigname($rig, $rigname)
{ {
global $rigs; global $rigs, $rignames, $rigips;
if (isset($rigs[$rig])) if (isset($rigs[$rig]))
{ {
$parts = explode(':', $rigs[$rig], 3); $parts = explode(':', $rigs[$rig], 3);
if (count($parts) == 3) if (count($parts) == 3)
$rigname = $parts[2]; $rigname = $parts[2];
else
if ($rignames !== false)
{
switch ($rignames)
{
case 'ip':
if (isset($parts[0]) && isset($rigips[$parts[0]]))
{
$ip = explode('.', $rigips[$parts[0]]);
if (count($ip) == 4)
$rigname = intval($ip[3]);
}
break;
case 'ipx':
if (isset($parts[0]) && isset($rigips[$parts[0]]))
{
$ip = explode('.', $rigips[$parts[0]]);
if (count($ip) == 4)
$rigname = intval($ip[3], 16);
}
break;
}
}
} }
return $rigname; return $rigname;
} }
# #
function riginput($rig, $rigname) function riginput($rig, $rigname, $usebuttons)
{ {
$rigname = rigname($rig, $rigname); $rigname = rigname($rig, $rigname);
return "<input type=button value='$rigname' onclick='pr(\"&rig=$rig\",null)'>"; if ($usebuttons === true)
return "<input type=button value='$rigname' onclick='pr(\"&rig=$rig\",null)'>";
else
return "<a href='".php_pr("&rig=$rig")."'>$rigname</a>";
} }
# #
function rigbutton($rig, $rigname, $when, $row) function rigbutton($rig, $rigname, $when, $row, $usebuttons)
{ {
list($value, $class) = fmt('BUTTON', 'Rig', '', $when, $row); list($value, $class) = fmt('BUTTON', 'Rig', '', $when, $row);
if ($rig === '') if ($rig === '')
$ri = '&nbsp;'; $ri = '&nbsp;';
else else
$ri = riginput($rig, $rigname); $ri = riginput($rig, $rigname, $usebuttons);
return "<td align=middle$class>$ri</td>"; return "<td align=middle$class>$ri</td>";
} }
# #
function showrigs($anss, $headname, $rigname) function showrigs($anss, $headname, $rigname)
{ {
global $rigbuttons;
$dthead = array($headname => 1, 'STATUS' => 1, 'Description' => 1, 'When' => 1, 'API' => 1, 'sgminer' => 1); $dthead = array($headname => 1, 'STATUS' => 1, 'Description' => 1, 'When' => 1, 'API' => 1, 'sgminer' => 1);
showhead('', $dthead); showhead('', $dthead);
@ -1591,7 +1647,7 @@ function showrigs($anss, $headname, $rigname)
foreach ($dthead as $name => $x) foreach ($dthead as $name => $x)
{ {
if ($item == 'STATUS' && $name == $headname) if ($item == 'STATUS' && $name == $headname)
echo rigbutton($rig, $rigname.$rig, $when, null); echo rigbutton($rig, $rigname.$rig, $when, null, $rigbuttons);
else else
{ {
if (isset($row[$name])) if (isset($row[$name]))
@ -1610,7 +1666,7 @@ function showrigs($anss, $headname, $rigname)
function doforeach($cmd, $des, $sum, $head, $datetime) function doforeach($cmd, $des, $sum, $head, $datetime)
{ {
global $miner, $port; global $miner, $port;
global $error, $readonly, $notify, $rigs; global $error, $readonly, $notify, $rigs, $rigbuttons;
global $warnfont, $warnoff, $dfmt; global $warnfont, $warnoff, $dfmt;
global $rigerror; global $rigerror;
@ -1629,10 +1685,13 @@ function doforeach($cmd, $des, $sum, $head, $datetime)
continue; continue;
$parts = explode(':', $rig, 3); $parts = explode(':', $rig, 3);
if (count($parts) >= 2) if (count($parts) >= 1)
{ {
$miner = $parts[0]; $miner = $parts[0];
$port = $parts[1]; if (count($parts) >= 2)
$port = $parts[1];
else
$port = '';
if (count($parts) > 2) if (count($parts) > 2)
$name = $parts[2]; $name = $parts[2];
@ -1747,7 +1806,7 @@ function doforeach($cmd, $des, $sum, $head, $datetime)
echo "<td align=right$class>Total:</td>"; echo "<td align=right$class>Total:</td>";
} }
else else
echo rigbutton($rig, "Rig $rig", $when, $row); echo rigbutton($rig, "Rig $rig", $when, $row, $rigbuttons);
} }
else else
{ {
@ -1780,7 +1839,7 @@ function refreshbuttons()
# #
function pagebuttons($rig, $pg) function pagebuttons($rig, $pg)
{ {
global $readonly, $rigs, $userlist, $ses; global $readonly, $rigs, $rigbuttons, $userlist, $ses;
global $allowcustompages, $customsummarypages; global $allowcustompages, $customsummarypages;
if ($rig === null) if ($rig === null)
@ -1819,10 +1878,12 @@ function pagebuttons($rig, $pg)
if ($userlist === null || isset($_SESSION[$ses])) if ($userlist === null || isset($_SESSION[$ses]))
{ {
if ($prev !== null) if ($prev !== null)
echo riginput($prev, 'Prev').'&nbsp;'; echo riginput($prev, 'Prev', true).'&nbsp;';
echo "<input type=button value='Refresh' onclick='pr(\"$refresh\",null)'>&nbsp;"; echo "<input type=button value='Refresh' onclick='pr(\"$refresh\",null)'>&nbsp;";
if ($next !== null) if ($next !== null)
echo riginput($next, 'Next').'&nbsp;'; echo riginput($next, 'Next', true).'&nbsp;';
echo '&nbsp;'; echo '&nbsp;';
if (count($rigs) > 1) if (count($rigs) > 1)
echo "<input type=button value='Summary' onclick='pr(\"\",null)'>&nbsp;"; echo "<input type=button value='Summary' onclick='pr(\"\",null)'>&nbsp;";
@ -2184,6 +2245,8 @@ function secmatch($section, $field)
# #
function customset($showfields, $sum, $section, $rig, $isbutton, $result, $total) function customset($showfields, $sum, $section, $rig, $isbutton, $result, $total)
{ {
global $rigbuttons;
foreach ($result as $sec => $row) foreach ($result as $sec => $row)
{ {
$secname = preg_replace('/\d/', '', $sec); $secname = preg_replace('/\d/', '', $sec);
@ -2200,7 +2263,7 @@ function customset($showfields, $sum, $section, $rig, $isbutton, $result, $total
if ($isbutton) if ($isbutton)
echo rigbutton($rig, $rig, $when, $row); echo rigbutton($rig, $rig, $when, $row, $rigbuttons);
else else
{ {
list($ignore, $class) = fmt('total', '', '', $when, $row); list($ignore, $class) = fmt('total', '', '', $when, $row);
@ -2535,10 +2598,13 @@ function processcustompage($pagename, $sections, $sum, $ext, $namemap)
foreach ($rigs as $num => $rig) foreach ($rigs as $num => $rig)
{ {
$parts = explode(':', $rig, 3); $parts = explode(':', $rig, 3);
if (count($parts) >= 2) if (count($parts) >= 1)
{ {
$miner = $parts[0]; $miner = $parts[0];
$port = $parts[1]; if (count($parts) >= 2)
$port = $parts[1];
else
$port = '';
if (count($parts) > 2) if (count($parts) > 2)
$name = $parts[2]; $name = $parts[2];
@ -2896,10 +2962,13 @@ function display()
if ($rig != null and $rig != '' and $rig >= 0 and $rig < count($rigs)) if ($rig != null and $rig != '' and $rig >= 0 and $rig < count($rigs))
{ {
$parts = explode(':', $rigs[$rig], 3); $parts = explode(':', $rigs[$rig], 3);
if (count($parts) >= 2) if (count($parts) >= 1)
{ {
$miner = $parts[0]; $miner = $parts[0];
$port = $parts[1]; if (count($parts) >= 2)
$port = $parts[1];
else
$port = '';
if ($readonly !== true) if ($readonly !== true)
$preprocess = $arg; $preprocess = $arg;
@ -2948,10 +3017,13 @@ function display()
if (count($rigs) == 1) if (count($rigs) == 1)
{ {
$parts = explode(':', $rigs[0], 3); $parts = explode(':', $rigs[0], 3);
if (count($parts) >= 2) if (count($parts) >= 1)
{ {
$miner = $parts[0]; $miner = $parts[0];
$port = $parts[1]; if (count($parts) >= 2)
$port = $parts[1];
else
$port = '';
htmlhead($mcerr, true, 0); htmlhead($mcerr, true, 0);
doOne(0, $preprocess); doOne(0, $preprocess);
@ -2968,10 +3040,13 @@ function display()
if ($rig != null and $rig != '' and $rig >= 0 and $rig < count($rigs)) if ($rig != null and $rig != '' and $rig >= 0 and $rig < count($rigs))
{ {
$parts = explode(':', $rigs[$rig], 3); $parts = explode(':', $rigs[$rig], 3);
if (count($parts) >= 2) if (count($parts) >= 1)
{ {
$miner = $parts[0]; $miner = $parts[0];
$port = $parts[1]; if (count($parts) >= 2)
$port = $parts[1];
else
$port = '';
htmlhead($mcerr, true, 0); htmlhead($mcerr, true, 0);
doOne($rig, $preprocess); doOne($rig, $preprocess);

217
sgminer.c

@ -82,6 +82,29 @@ static char packagename[256];
bool opt_work_update; bool opt_work_update;
bool opt_protocol; bool opt_protocol;
static struct benchfile_layout {
int length;
char *name;
} benchfile_data[] = {
{ 1, "Version" },
{ 64, "MerkleRoot" },
{ 64, "PrevHash" },
{ 8, "DifficultyBits" },
{ 10, "NonceTime" } // 10 digits
};
enum benchwork {
BENCHWORK_VERSION = 0,
BENCHWORK_MERKLEROOT,
BENCHWORK_PREVHASH,
BENCHWORK_DIFFBITS,
BENCHWORK_NONCETIME,
BENCHWORK_COUNT
};
static char *opt_benchfile;
static bool opt_benchfile_display;
static FILE *benchfile_in;
static int benchfile_line;
static int benchfile_work;
static bool opt_benchmark; static bool opt_benchmark;
bool have_longpoll; bool have_longpoll;
bool want_per_device_stats; bool want_per_device_stats;
@ -1141,6 +1164,12 @@ static struct opt_table opt_config_table[] = {
OPT_WITHOUT_ARG("--balance", OPT_WITHOUT_ARG("--balance",
set_balance, &pool_strategy, set_balance, &pool_strategy,
"Change multipool strategy from failover to even share balance"), "Change multipool strategy from failover to even share balance"),
OPT_WITH_ARG("--benchfile",
opt_set_charp, NULL, &opt_benchfile,
"Run cgminer in benchmark mode using a work file - produces no shares"),
OPT_WITHOUT_ARG("--benchfile-display",
opt_set_bool, &opt_benchfile_display,
"Display each benchfile nonce found"),
OPT_WITHOUT_ARG("--benchmark", OPT_WITHOUT_ARG("--benchmark",
opt_set_bool, &opt_benchmark, opt_set_bool, &opt_benchmark,
"Run sgminer in benchmark mode - produces no shares"), "Run sgminer in benchmark mode - produces no shares"),
@ -3069,6 +3098,154 @@ static void get_benchmark_work(struct work *work)
calc_diff(work, 0); calc_diff(work, 0);
} }
static void benchfile_dspwork(struct work *work, uint32_t nonce)
{
char buf[1024];
uint32_t dn;
int i;
dn = 0;
for (i = 0; i < 4; i++) {
dn *= 0x100;
dn += nonce & 0xff;
nonce /= 0x100;
}
if ((sizeof(work->data) * 2 + 1) > sizeof(buf))
quithere(1, "BENCHFILE Invalid buf size");
__bin2hex(buf, work->data, sizeof(work->data));
applog(LOG_ERR, "BENCHFILE nonce %u=0x%08x for work=%s",
(unsigned int)dn, (unsigned int)dn, buf);
}
static bool benchfile_get_work(struct work *work)
{
char buf[1024];
char item[1024];
bool got = false;
if (!benchfile_in) {
if (opt_benchfile)
benchfile_in = fopen(opt_benchfile, "r");
else
quit(1, "BENCHFILE Invalid benchfile NULL");
if (!benchfile_in)
quit(1, "BENCHFILE Failed to open benchfile '%s'", opt_benchfile);
benchfile_line = 0;
if (!fgets(buf, 1024, benchfile_in))
quit(1, "BENCHFILE Failed to read benchfile '%s'", opt_benchfile);
got = true;
benchfile_work = 0;
}
if (!got) {
if (!fgets(buf, 1024, benchfile_in)) {
if (benchfile_work == 0)
quit(1, "BENCHFILE No work in benchfile '%s'", opt_benchfile);
fclose(benchfile_in);
benchfile_in = NULL;
return benchfile_get_work(work);
}
}
do {
benchfile_line++;
// Empty lines and lines starting with '#' or '/' are ignored
if (*buf != '\0' && *buf != '#' && *buf != '/') {
char *commas[BENCHWORK_COUNT];
int i, j, len;
long nonce_time;
commas[0] = buf;
for (i = 1; i < BENCHWORK_COUNT; i++) {
commas[i] = strchr(commas[i-1], ',');
if (!commas[i]) {
quit(1, "BENCHFILE Invalid input file line %d"
" - field count is %d but should be %d",
benchfile_line, i, BENCHWORK_COUNT);
}
len = commas[i] - commas[i-1];
if (benchfile_data[i-1].length &&
(len != benchfile_data[i-1].length)) {
quit(1, "BENCHFILE Invalid input file line %d "
"field %d (%s) length is %d but should be %d",
benchfile_line, i,
benchfile_data[i-1].name,
len, benchfile_data[i-1].length);
}
*(commas[i]++) = '\0';
}
// NonceTime may have LF's etc
len = strlen(commas[BENCHWORK_NONCETIME]);
if (len < benchfile_data[BENCHWORK_NONCETIME].length) {
quit(1, "BENCHFILE Invalid input file line %d field %d"
" (%s) length is %d but should be least %d",
benchfile_line, BENCHWORK_NONCETIME+1,
benchfile_data[BENCHWORK_NONCETIME].name, len,
benchfile_data[BENCHWORK_NONCETIME].length);
}
sprintf(item, "0000000%c", commas[BENCHWORK_VERSION][0]);
j = strlen(item);
for (i = benchfile_data[BENCHWORK_PREVHASH].length-8; i >= 0; i -= 8) {
sprintf(&(item[j]), "%.8s", &commas[BENCHWORK_PREVHASH][i]);
j += 8;
}
for (i = benchfile_data[BENCHWORK_MERKLEROOT].length-8; i >= 0; i -= 8) {
sprintf(&(item[j]), "%.8s", &commas[BENCHWORK_MERKLEROOT][i]);
j += 8;
}
nonce_time = atol(commas[BENCHWORK_NONCETIME]);
sprintf(&(item[j]), "%08lx", nonce_time);
j += 8;
strcpy(&(item[j]), commas[BENCHWORK_DIFFBITS]);
j += benchfile_data[BENCHWORK_DIFFBITS].length;
memset(work, 0, sizeof(*work));
hex2bin(work->data, item, j >> 1);
calc_midstate(work);
benchfile_work++;
return true;
}
} while (fgets(buf, 1024, benchfile_in));
if (benchfile_work == 0)
quit(1, "BENCHFILE No work in benchfile '%s'", opt_benchfile);
fclose(benchfile_in);
benchfile_in = NULL;
return benchfile_get_work(work);
}
static void get_benchfile_work(struct work *work)
{
benchfile_get_work(work);
work->mandatory = true;
work->pool = pools[0];
cgtime(&work->tv_getwork);
copy_time(&work->tv_getwork_reply, &work->tv_getwork);
work->getwork_mode = GETWORK_MODE_BENCHMARK;
calc_diff(work, 0);
}
#ifdef HAVE_CURSES #ifdef HAVE_CURSES
static void disable_curses_windows(void) static void disable_curses_windows(void)
{ {
@ -3577,7 +3754,7 @@ static bool stale_work(struct work *work, bool share)
struct pool *pool; struct pool *pool;
int getwork_delay; int getwork_delay;
if (opt_benchmark) if (opt_benchmark || opt_benchfile)
return false; return false;
if (work->work_block != work_block) { if (work->work_block != work_block) {
@ -6159,6 +6336,9 @@ bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
return false; return false;
} }
if (opt_benchfile && opt_benchfile_display)
benchfile_dspwork(work, nonce);
return true; return true;
} }
@ -6179,6 +6359,10 @@ bool submit_noffset_nonce(struct thr_info *thr, struct work *work_in, uint32_t n
} }
ret = true; ret = true;
update_work_stats(thr, work); update_work_stats(thr, work);
if (opt_benchfile && opt_benchfile_display)
benchfile_dspwork(work, nonce);
if (!fulltest(work->hash, work->target)) { if (!fulltest(work->hash, work->target)) {
applog(LOG_INFO, "%s %d: Share above target", thr->cgpu->drv->name, applog(LOG_INFO, "%s %d: Share above target", thr->cgpu->drv->name,
thr->cgpu->device_id); thr->cgpu->device_id);
@ -7000,11 +7184,12 @@ static void *watchpool_thread(void __maybe_unused *userdata)
for (i = 0; i < total_pools; i++) { for (i = 0; i < total_pools; i++) {
struct pool *pool = pools[i]; struct pool *pool = pools[i];
if (!opt_benchmark) if (!opt_benchmark && !opt_benchfile)
reap_curl(pool); reap_curl(pool);
/* Get a rolling utility per pool over 10 mins */ /* Get a rolling utility per pool over 10 mins */
if (intervals > 19) { if (intervals > 19) {
applog(LOG_DEBUG, "Getting rolling utility for %s", pool->poolname);
int shares = pool->diff1 - pool->last_shares; int shares = pool->diff1 - pool->last_shares;
pool->last_shares = pool->diff1; pool->last_shares = pool->diff1;
@ -7012,18 +7197,22 @@ static void *watchpool_thread(void __maybe_unused *userdata)
pool->shares = pool->utility; pool->shares = pool->utility;
} }
if (pool->state == POOL_DISABLED) if (pool->state == POOL_DISABLED) {
applog(LOG_DEBUG, "Skipping disabled %s", pool->poolname);
continue; continue;
}
/* Don't start testing any pools if the test threads /* Don't start testing any pools if the test threads
* from startup are still doing their first attempt. */ * from startup are still doing their first attempt. */
if (unlikely(pool->testing)) { if (unlikely(pool->testing)) {
applog(LOG_DEBUG, "Testing %s", pool->poolname);
pthread_join(pool->test_thread, NULL); pthread_join(pool->test_thread, NULL);
pool->testing = false; pool->testing = false;
} }
/* Test pool is idle once every minute */ /* Test pool is idle once every minute */
if (pool->idle && now.tv_sec - pool->tv_idle.tv_sec > 30) { if (pool->idle && now.tv_sec - pool->tv_idle.tv_sec > 30) {
applog(LOG_DEBUG, "Testing idle %s", pool->poolname);
cgtime(&pool->tv_idle); cgtime(&pool->tv_idle);
if (pool_active(pool, true) && pool_tclear(pool, &pool->idle)) if (pool_active(pool, true) && pool_tclear(pool, &pool->idle))
pool_resus(pool); pool_resus(pool);
@ -7040,8 +7229,10 @@ static void *watchpool_thread(void __maybe_unused *userdata)
} }
} }
if (current_pool()->idle) if (current_pool()->idle) {
applog(LOG_DEBUG, "%s is idle, switching pools", current_pool()->poolname);
switch_pools(NULL); switch_pools(NULL);
}
if (pool_strategy == POOL_ROTATE && now.tv_sec - rotate_tv.tv_sec > 60 * opt_rotate_period) { if (pool_strategy == POOL_ROTATE && now.tv_sec - rotate_tv.tv_sec > 60 * opt_rotate_period) {
cgtime(&rotate_tv); cgtime(&rotate_tv);
@ -7917,14 +8108,19 @@ int main(int argc, char *argv[])
if (!config_loaded) if (!config_loaded)
load_default_config(); load_default_config();
if (opt_benchmark) { if (opt_benchmark || opt_benchfile) {
struct pool *pool; struct pool *pool;
// FIXME: executes always (leftover from SHA256d days) // FIXME: executes always (leftover from SHA256d days)
quit(1, "Cannot use benchmark mode with scrypt"); quit(1, "Cannot use benchmark mode with scrypt");
pool = add_pool(); pool = add_pool();
pool->rpc_url = (char *)malloc(255); pool->rpc_url = (char *)malloc(255);
strcpy(pool->rpc_url, "Benchmark"); if (opt_benchfile)
strcpy(pool->rpc_url, "Benchfile");
else
strcpy(pool->rpc_url, "Benchmark");
pool->rpc_user = pool->rpc_url; pool->rpc_user = pool->rpc_url;
pool->rpc_pass = pool->rpc_url; pool->rpc_pass = pool->rpc_url;
enable_pool(pool); enable_pool(pool);
@ -8109,7 +8305,7 @@ int main(int argc, char *argv[])
} }
} }
if (opt_benchmark) if (opt_benchmark || opt_benchfile)
goto begin_bench; goto begin_bench;
/* Set pool state */ /* Set pool state */
@ -8302,7 +8498,12 @@ retry:
continue; continue;
} }
if (opt_benchmark) { if (opt_benchfile) {
get_benchfile_work(work);
applog(LOG_DEBUG, "Generated benchfile work");
stage_work(work);
continue;
} else if (opt_benchmark) {
get_benchmark_work(work); get_benchmark_work(work);
applog(LOG_DEBUG, "Generated benchmark work"); applog(LOG_DEBUG, "Generated benchmark work");
stage_work(work); stage_work(work);

Loading…
Cancel
Save