|
|
@@ -421,7 +421,7 @@ static bool should_run(void)
|
|
|
return within_range;
|
|
|
}
|
|
|
|
|
|
-void get_datestamp(char *f, time_t tt)
|
|
|
+void get_datestamp(char *f, size_t fsiz, time_t tt)
|
|
|
{
|
|
|
struct tm _tm;
|
|
|
struct tm *tm = &_tm;
|
|
|
@@ -430,7 +430,7 @@ void get_datestamp(char *f, time_t tt)
|
|
|
tt = time(NULL);
|
|
|
|
|
|
localtime_r(&tt, tm);
|
|
|
- sprintf(f, "[%d-%02d-%02d %02d:%02d:%02d]",
|
|
|
+ snprintf(f, fsiz, "[%d-%02d-%02d %02d:%02d:%02d]",
|
|
|
tm->tm_year + 1900,
|
|
|
tm->tm_mon + 1,
|
|
|
tm->tm_mday,
|
|
|
@@ -439,13 +439,14 @@ void get_datestamp(char *f, time_t tt)
|
|
|
tm->tm_sec);
|
|
|
}
|
|
|
|
|
|
-void get_timestamp(char *f, time_t tt)
|
|
|
+static
|
|
|
+void get_timestamp(char *f, size_t fsiz, time_t tt)
|
|
|
{
|
|
|
struct tm _tm;
|
|
|
struct tm *tm = &_tm;
|
|
|
|
|
|
localtime_r(&tt, tm);
|
|
|
- sprintf(f, "[%02d:%02d:%02d]",
|
|
|
+ snprintf(f, fsiz, "[%02d:%02d:%02d]",
|
|
|
tm->tm_hour,
|
|
|
tm->tm_min,
|
|
|
tm->tm_sec);
|
|
|
@@ -1507,10 +1508,18 @@ static struct opt_table opt_config_table[] = {
|
|
|
OPT_WITH_ARG("--lookup-gap",
|
|
|
set_lookup_gap, NULL, NULL,
|
|
|
"Set GPU lookup gap for scrypt mining, comma separated"),
|
|
|
-#endif
|
|
|
OPT_WITH_ARG("--intensity|-I",
|
|
|
set_intensity, NULL, NULL,
|
|
|
- "Intensity of GPU scanning (d or " _MIN_INTENSITY_STR " -> " _MAX_INTENSITY_STR ", default: d to maintain desktop interactivity)"),
|
|
|
+ "Intensity of GPU scanning (d or " MIN_SHA_INTENSITY_STR
|
|
|
+ " -> " MAX_SCRYPT_INTENSITY_STR
|
|
|
+ ",default: d to maintain desktop interactivity)"),
|
|
|
+#else
|
|
|
+ OPT_WITH_ARG("--intensity|-I",
|
|
|
+ set_intensity, NULL, NULL,
|
|
|
+ "Intensity of GPU scanning (d or " MIN_SHA_INTENSITY_STR
|
|
|
+ " -> " MAX_SHA_INTENSITY_STR
|
|
|
+ ",default: d to maintain desktop interactivity)"),
|
|
|
+#endif
|
|
|
#endif
|
|
|
#if defined(HAVE_OPENCL) || defined(USE_MODMINER) || defined(USE_X6500) || defined(USE_ZTEX)
|
|
|
OPT_WITH_ARG("--kernel-path|-K",
|
|
|
@@ -1851,7 +1860,7 @@ static char *parse_config(json_t *config, bool fileconf)
|
|
|
applog(LOG_ERR, "Invalid config option %s: %s", p, err);
|
|
|
fileconf_load = -1;
|
|
|
} else {
|
|
|
- sprintf(err_buf, "Parsing JSON option %s: %s",
|
|
|
+ snprintf(err_buf, sizeof(err_buf), "Parsing JSON option %s: %s",
|
|
|
p, err);
|
|
|
return err_buf;
|
|
|
}
|
|
|
@@ -1874,6 +1883,7 @@ static char *load_config(const char *arg, void __maybe_unused *unused)
|
|
|
json_error_t err;
|
|
|
json_t *config;
|
|
|
char *json_error;
|
|
|
+ size_t siz;
|
|
|
|
|
|
if (!cnfbuf)
|
|
|
cnfbuf = strdup(arg);
|
|
|
@@ -1887,11 +1897,12 @@ static char *load_config(const char *arg, void __maybe_unused *unused)
|
|
|
config = json_load_file(arg, &err);
|
|
|
#endif
|
|
|
if (!json_is_object(config)) {
|
|
|
- json_error = malloc(JSON_LOAD_ERROR_LEN + strlen(arg) + strlen(err.text));
|
|
|
+ siz = JSON_LOAD_ERROR_LEN + strlen(arg) + strlen(err.text);
|
|
|
+ json_error = malloc(siz);
|
|
|
if (!json_error)
|
|
|
quit(1, "Malloc failure in json error");
|
|
|
|
|
|
- sprintf(json_error, JSON_LOAD_ERROR, arg, err.text);
|
|
|
+ snprintf(json_error, siz, JSON_LOAD_ERROR, arg, err.text);
|
|
|
return json_error;
|
|
|
}
|
|
|
|
|
|
@@ -2083,7 +2094,8 @@ void __update_block_title(const unsigned char *hash_swap)
|
|
|
free(current_hash);
|
|
|
current_hash = malloc(3 /* ... */ + 16 /* block hash segment */ + 1);
|
|
|
bin2hex(tmp, &hash_swap[24], 8);
|
|
|
- sprintf(current_hash, "...%s", tmp);
|
|
|
+ memset(current_hash, '.', 3);
|
|
|
+ memcpy(¤t_hash[3], tmp, 17);
|
|
|
known_blkheight_current = false;
|
|
|
} else if (likely(known_blkheight_current)) {
|
|
|
return;
|
|
|
@@ -2092,7 +2104,7 @@ void __update_block_title(const unsigned char *hash_swap)
|
|
|
// FIXME: The block number will overflow this sometime around AD 2025-2027
|
|
|
if (known_blkheight < 1000000) {
|
|
|
memmove(¤t_hash[3], ¤t_hash[11], 8);
|
|
|
- sprintf(¤t_hash[11], " #%6u", known_blkheight);
|
|
|
+ snprintf(¤t_hash[11], 20-11, " #%6u", known_blkheight);
|
|
|
}
|
|
|
known_blkheight_current = true;
|
|
|
}
|
|
|
@@ -2291,24 +2303,15 @@ int dev_from_id(int thr_id)
|
|
|
return cgpu->device_id;
|
|
|
}
|
|
|
|
|
|
-/* Make the change in the recent value adjust dynamically when the difference
|
|
|
- * is large, but damp it when the values are closer together. This allows the
|
|
|
- * value to change quickly, but not fluctuate too dramatically when it has
|
|
|
- * stabilised. */
|
|
|
-void decay_time(double *f, double fadd)
|
|
|
+/* Create an exponentially decaying average over the opt_log_interval */
|
|
|
+void decay_time(double *f, double fadd, double fsecs)
|
|
|
{
|
|
|
- double ratio = 0;
|
|
|
-
|
|
|
- if (likely(*f > 0)) {
|
|
|
- ratio = fadd / *f;
|
|
|
- if (ratio > 1)
|
|
|
- ratio = 1 / ratio;
|
|
|
- }
|
|
|
+ double ftotal, fprop;
|
|
|
|
|
|
- if (ratio > 0.63)
|
|
|
- *f = (fadd * 0.58 + *f) / 1.58;
|
|
|
- else
|
|
|
- *f = (fadd + *f * 0.58) / 1.58;
|
|
|
+ fprop = 1.0 - 1 / (exp(fsecs / (double)opt_log_interval));
|
|
|
+ ftotal = 1.0 + fprop;
|
|
|
+ *f += (fadd * fprop);
|
|
|
+ *f /= ftotal;
|
|
|
}
|
|
|
|
|
|
static int __total_staged(void)
|
|
|
@@ -2382,12 +2385,13 @@ int my_cancellable_getch(void)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-void tailsprintf(char *f, const char *fmt, ...)
|
|
|
+void tailsprintf(char *buf, size_t bufsz, const char *fmt, ...)
|
|
|
{
|
|
|
va_list ap;
|
|
|
-
|
|
|
+ size_t presz = strlen(buf);
|
|
|
+
|
|
|
va_start(ap, fmt);
|
|
|
- vsprintf(f + strlen(f), fmt, ap);
|
|
|
+ vsnprintf(&buf[presz], bufsz - presz, fmt, ap);
|
|
|
va_end(ap);
|
|
|
}
|
|
|
|
|
|
@@ -2428,7 +2432,7 @@ double cgpu_utility(struct cgpu_info *cgpu)
|
|
|
|
|
|
/* Convert a uint64_t value into a truncated string for displaying with its
|
|
|
* associated suitable for Mega, Giga etc. Buf array needs to be long enough */
|
|
|
-static void suffix_string(uint64_t val, char *buf, int sigdigits)
|
|
|
+static void suffix_string(uint64_t val, char *buf, size_t bufsiz, int sigdigits)
|
|
|
{
|
|
|
const double dkilo = 1000.0;
|
|
|
const uint64_t kilo = 1000ull;
|
|
|
@@ -2444,26 +2448,26 @@ static void suffix_string(uint64_t val, char *buf, int sigdigits)
|
|
|
if (val >= exa) {
|
|
|
val /= peta;
|
|
|
dval = (double)val / dkilo;
|
|
|
- sprintf(suffix, "E");
|
|
|
+ strcpy(suffix, "E");
|
|
|
} else if (val >= peta) {
|
|
|
val /= tera;
|
|
|
dval = (double)val / dkilo;
|
|
|
- sprintf(suffix, "P");
|
|
|
+ strcpy(suffix, "P");
|
|
|
} else if (val >= tera) {
|
|
|
val /= giga;
|
|
|
dval = (double)val / dkilo;
|
|
|
- sprintf(suffix, "T");
|
|
|
+ strcpy(suffix, "T");
|
|
|
} else if (val >= giga) {
|
|
|
val /= mega;
|
|
|
dval = (double)val / dkilo;
|
|
|
- sprintf(suffix, "G");
|
|
|
+ strcpy(suffix, "G");
|
|
|
} else if (val >= mega) {
|
|
|
val /= kilo;
|
|
|
dval = (double)val / dkilo;
|
|
|
- sprintf(suffix, "M");
|
|
|
+ strcpy(suffix, "M");
|
|
|
} else if (val >= kilo) {
|
|
|
dval = (double)val / dkilo;
|
|
|
- sprintf(suffix, "k");
|
|
|
+ strcpy(suffix, "k");
|
|
|
} else {
|
|
|
dval = val;
|
|
|
decimal = false;
|
|
|
@@ -2471,15 +2475,15 @@ static void suffix_string(uint64_t val, char *buf, int sigdigits)
|
|
|
|
|
|
if (!sigdigits) {
|
|
|
if (decimal)
|
|
|
- sprintf(buf, "%.3g%s", dval, suffix);
|
|
|
+ snprintf(buf, bufsiz, "%.3g%s", dval, suffix);
|
|
|
else
|
|
|
- sprintf(buf, "%d%s", (unsigned int)dval, suffix);
|
|
|
+ snprintf(buf, bufsiz, "%d%s", (unsigned int)dval, suffix);
|
|
|
} else {
|
|
|
/* Always show sigdigits + 1, padded on right with zeroes
|
|
|
* followed by suffix */
|
|
|
int ndigits = sigdigits - 1 - (dval > 0.0 ? floor(log10(dval)) : 0);
|
|
|
|
|
|
- sprintf(buf, "%*.*f%s", sigdigits + 1, ndigits, dval, suffix);
|
|
|
+ snprintf(buf, bufsiz, "%*.*f%s", sigdigits + 1, ndigits, dval, suffix);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -2514,9 +2518,12 @@ enum h2bs_fmt {
|
|
|
static const size_t h2bs_fmt_size[] = {6, 10, 11};
|
|
|
|
|
|
static
|
|
|
-char *format_unit(char *buf, bool floatprec, const char *measurement, enum h2bs_fmt fmt, float hashrate, signed char unitin)
|
|
|
+int format_unit2(char *buf, size_t sz, bool floatprec, const char *measurement, enum h2bs_fmt fmt, float hashrate, signed char unitin)
|
|
|
{
|
|
|
+ char *s = buf;
|
|
|
unsigned char prec, i, unit;
|
|
|
+ int rv = 0;
|
|
|
+
|
|
|
if (unitin == -1)
|
|
|
{
|
|
|
unit = 0;
|
|
|
@@ -2534,35 +2541,31 @@ char *format_unit(char *buf, bool floatprec, const char *measurement, enum h2bs_
|
|
|
prec = 1;
|
|
|
else
|
|
|
prec = 2;
|
|
|
- sprintf(buf, "%5.*f", prec, hashrate);
|
|
|
- i = 5;
|
|
|
+ _SNP("%5.*f", prec, hashrate);
|
|
|
}
|
|
|
else
|
|
|
- {
|
|
|
- sprintf(buf, "%3d", (int)hashrate);
|
|
|
- i = 3;
|
|
|
- }
|
|
|
+ _SNP("%3d", (int)hashrate);
|
|
|
|
|
|
switch (fmt) {
|
|
|
case H2B_SPACED:
|
|
|
- buf[i++] = ' ';
|
|
|
+ _SNP(" ");
|
|
|
case H2B_SHORT:
|
|
|
- buf[i++] = _unitchar[unit];
|
|
|
- strcpy(&buf[i], measurement);
|
|
|
+ _SNP("%c%s", _unitchar[unit], measurement);
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- return buf;
|
|
|
+ return rv;
|
|
|
}
|
|
|
|
|
|
static
|
|
|
-char *_multi_format_unit(char **buflist, bool floatprec, const char *measurement, enum h2bs_fmt fmt, const char *delim, int count, const float *numbers, bool isarray)
|
|
|
+char *_multi_format_unit(char **buflist, size_t *bufszlist, bool floatprec, const char *measurement, enum h2bs_fmt fmt, const char *delim, int count, const float *numbers, bool isarray)
|
|
|
{
|
|
|
unsigned char unit = 0;
|
|
|
int i;
|
|
|
size_t delimsz;
|
|
|
char *buf = buflist[0];
|
|
|
+ size_t bufsz = bufszlist[0];
|
|
|
size_t itemwidth = (floatprec ? 5 : 3);
|
|
|
|
|
|
if (!isarray)
|
|
|
@@ -2574,43 +2577,59 @@ char *_multi_format_unit(char **buflist, bool floatprec, const char *measurement
|
|
|
--count;
|
|
|
for (i = 0; i < count; ++i)
|
|
|
{
|
|
|
- format_unit(buf, floatprec, NULL, H2B_NOUNIT, numbers[i], unit);
|
|
|
+ format_unit2(buf, bufsz, floatprec, NULL, H2B_NOUNIT, numbers[i], unit);
|
|
|
if (isarray)
|
|
|
+ {
|
|
|
buf = buflist[i + 1];
|
|
|
+ bufsz = bufszlist[i + 1];
|
|
|
+ }
|
|
|
else
|
|
|
{
|
|
|
buf += itemwidth;
|
|
|
+ bufsz -= itemwidth;
|
|
|
+ if (delimsz > bufsz)
|
|
|
+ delimsz = bufsz;
|
|
|
memcpy(buf, delim, delimsz);
|
|
|
buf += delimsz;
|
|
|
+ bufsz -= delimsz;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Last entry has the unit
|
|
|
- format_unit(buf, floatprec, measurement, fmt, numbers[count], unit);
|
|
|
+ format_unit2(buf, bufsz, floatprec, measurement, fmt, numbers[count], unit);
|
|
|
|
|
|
return buflist[0];
|
|
|
}
|
|
|
-#define multi_format_unit(buf, floatprec, measurement, fmt, delim, count, ...) _multi_format_unit((char *[]){buf}, floatprec, measurement, fmt, delim, count, (float[]){ __VA_ARGS__ }, false)
|
|
|
-#define multi_format_unit_array(buflist, floatprec, measurement, fmt, count, ...) (void)_multi_format_unit(buflist, floatprec, measurement, fmt, NULL, count, (float[]){ __VA_ARGS__ }, true)
|
|
|
+#define multi_format_unit2(buf, bufsz, floatprec, measurement, fmt, delim, count, ...) _multi_format_unit((char *[]){buf}, (size_t[]){bufsz}, floatprec, measurement, fmt, delim, count, (float[]){ __VA_ARGS__ }, false)
|
|
|
+#define multi_format_unit_array2(buflist, bufszlist, floatprec, measurement, fmt, count, ...) (void)_multi_format_unit(buflist, bufszlist, floatprec, measurement, fmt, NULL, count, (float[]){ __VA_ARGS__ }, true)
|
|
|
|
|
|
-static const char *
|
|
|
-percentf2(double p, double t, char *buf)
|
|
|
+static
|
|
|
+int percentf3(char * const buf, size_t sz, double p, const double t)
|
|
|
{
|
|
|
+ char *s = buf;
|
|
|
+ int rv = 0;
|
|
|
if (!p)
|
|
|
- return "none";
|
|
|
+ _SNP("none");
|
|
|
+ else
|
|
|
if (t <= p)
|
|
|
- return "100%";
|
|
|
+ _SNP("100%%");
|
|
|
+ else
|
|
|
+ {
|
|
|
+
|
|
|
p /= t;
|
|
|
if (p < 0.01)
|
|
|
- sprintf(buf, ".%02.0f%%", p * 10000); // ".01%"
|
|
|
+ _SNP(".%02.0f%%", p * 10000); // ".01%"
|
|
|
else
|
|
|
if (p < 0.1)
|
|
|
- sprintf(buf, "%.1f%%", p * 100); // "9.1%"
|
|
|
+ _SNP("%.1f%%", p * 100); // "9.1%"
|
|
|
else
|
|
|
- sprintf(buf, "%3.0f%%", p * 100); // " 99%"
|
|
|
- return buf;
|
|
|
+ _SNP("%3.0f%%", p * 100); // " 99%"
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return rv;
|
|
|
}
|
|
|
-#define percentf(p, t, buf) percentf2(p, p + t, buf)
|
|
|
+#define percentf4(buf, bufsz, p, t) percentf3(buf, bufsz, p, p + t)
|
|
|
|
|
|
#ifdef HAVE_CURSES
|
|
|
static void adj_width(int var, int *length);
|
|
|
@@ -2620,7 +2639,7 @@ static void adj_width(int var, int *length);
|
|
|
static int awidth = 1, rwidth = 1, swidth = 1, hwwidth = 1;
|
|
|
|
|
|
static
|
|
|
-void format_statline(char *buf, const char *cHr, const char *aHr, const char *uHr, int accepted, int rejected, int stale, int wnotaccepted, int waccepted, int hwerrs, int badnonces, int allnonces)
|
|
|
+void format_statline(char *buf, size_t bufsz, const char *cHr, const char *aHr, const char *uHr, int accepted, int rejected, int stale, int wnotaccepted, int waccepted, int hwerrs, int badnonces, int allnonces)
|
|
|
{
|
|
|
char rejpcbuf[6];
|
|
|
char bnbuf[6];
|
|
|
@@ -2629,40 +2648,42 @@ void format_statline(char *buf, const char *cHr, const char *aHr, const char *uH
|
|
|
adj_width(rejected, &rwidth);
|
|
|
adj_width(stale, &swidth);
|
|
|
adj_width(hwerrs, &hwwidth);
|
|
|
+ percentf4(rejpcbuf, sizeof(rejpcbuf), wnotaccepted, waccepted);
|
|
|
+ percentf3(bnbuf, sizeof(bnbuf), badnonces, allnonces);
|
|
|
|
|
|
- tailsprintf(buf, "%s/%s/%s | A:%*d R:%*d+%*d(%s) HW:%*d/%s",
|
|
|
+ tailsprintf(buf, bufsz, "%s/%s/%s | A:%*d R:%*d+%*d(%s) HW:%*d/%s",
|
|
|
cHr, aHr, uHr,
|
|
|
awidth, accepted,
|
|
|
rwidth, rejected,
|
|
|
swidth, stale,
|
|
|
- percentf(wnotaccepted, waccepted, rejpcbuf),
|
|
|
+ rejpcbuf,
|
|
|
hwwidth, hwerrs,
|
|
|
- percentf2(badnonces, allnonces, bnbuf)
|
|
|
+ bnbuf
|
|
|
);
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
static inline
|
|
|
-void temperature_column_tail(char *buf, bool maybe_unicode, const float * const temp)
|
|
|
+void temperature_column(char *buf, size_t bufsz, bool maybe_unicode, const float * const temp)
|
|
|
{
|
|
|
if (!(use_unicode && have_unicode_degrees))
|
|
|
maybe_unicode = false;
|
|
|
if (temp && *temp > 0.)
|
|
|
if (maybe_unicode)
|
|
|
- sprintf(buf, "%4.1f\xb0""C", *temp);
|
|
|
+ snprintf(buf, bufsz, "%4.1f\xb0""C", *temp);
|
|
|
else
|
|
|
- sprintf(buf, "%4.1fC", *temp);
|
|
|
+ snprintf(buf, bufsz, "%4.1fC", *temp);
|
|
|
else
|
|
|
{
|
|
|
if (temp)
|
|
|
- strcpy(buf, " ");
|
|
|
+ snprintf(buf, bufsz, " ");
|
|
|
if (maybe_unicode)
|
|
|
- strcat(buf, " ");
|
|
|
+ tailsprintf(buf, bufsz, " ");
|
|
|
}
|
|
|
- strcat(buf, " | ");
|
|
|
+ tailsprintf(buf, bufsz, " | ");
|
|
|
}
|
|
|
|
|
|
-void get_statline3(char *buf, struct cgpu_info *cgpu, bool for_curses, bool opt_show_procs)
|
|
|
+void get_statline3(char *buf, size_t bufsz, struct cgpu_info *cgpu, bool for_curses, bool opt_show_procs)
|
|
|
{
|
|
|
#ifndef HAVE_CURSES
|
|
|
assert(for_curses == false);
|
|
|
@@ -2712,8 +2733,9 @@ void get_statline3(char *buf, struct cgpu_info *cgpu, bool for_curses, bool opt_
|
|
|
allnonces += slave->diff1;
|
|
|
}
|
|
|
|
|
|
- multi_format_unit_array(
|
|
|
+ multi_format_unit_array2(
|
|
|
((char*[]){cHr, aHr, uHr}),
|
|
|
+ ((size_t[]){h2bs_fmt_size[H2B_NOUNIT], h2bs_fmt_size[H2B_NOUNIT], h2bs_fmt_size[hashrate_style]}),
|
|
|
true, "h/s", hashrate_style,
|
|
|
3,
|
|
|
1e6*rolling,
|
|
|
@@ -2725,33 +2747,38 @@ void get_statline3(char *buf, struct cgpu_info *cgpu, bool for_curses, bool opt_
|
|
|
if (for_curses)
|
|
|
{
|
|
|
if (opt_show_procs)
|
|
|
- sprintf(buf, " %"PRIprepr": ", cgpu->proc_repr);
|
|
|
+ snprintf(buf, bufsz, " %"PRIprepr": ", cgpu->proc_repr);
|
|
|
else
|
|
|
- sprintf(buf, " %s: ", cgpu->dev_repr);
|
|
|
+ snprintf(buf, bufsz, " %s: ", cgpu->dev_repr);
|
|
|
}
|
|
|
else
|
|
|
#endif
|
|
|
- sprintf(buf, "%s ", opt_show_procs ? cgpu->proc_repr_ns : cgpu->dev_repr_ns);
|
|
|
+ snprintf(buf, bufsz, "%s ", opt_show_procs ? cgpu->proc_repr_ns : cgpu->dev_repr_ns);
|
|
|
|
|
|
if (unlikely(cgpu->status == LIFE_INIT))
|
|
|
{
|
|
|
- tailsprintf(buf, "Initializing...");
|
|
|
+ tailsprintf(buf, bufsz, "Initializing...");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if (likely(cgpu->status != LIFE_DEAD2) && drv->override_statline_temp && drv->override_statline_temp(buf, cgpu, opt_show_procs))
|
|
|
- temperature_column_tail(&buf[strlen(buf)], for_curses, NULL);
|
|
|
- else
|
|
|
{
|
|
|
- float temp = cgpu->temp;
|
|
|
- if (!opt_show_procs)
|
|
|
+ const size_t bufln = strlen(buf);
|
|
|
+ const size_t abufsz = (bufln >= bufsz) ? 0 : (bufsz - bufln);
|
|
|
+
|
|
|
+ if (likely(cgpu->status != LIFE_DEAD2) && drv->override_statline_temp2 && drv->override_statline_temp2(buf, bufsz, cgpu, opt_show_procs))
|
|
|
+ temperature_column(&buf[bufln], abufsz, for_curses, NULL);
|
|
|
+ else
|
|
|
{
|
|
|
- // Find the highest temperature of all processors
|
|
|
- for (struct cgpu_info *proc = cgpu; proc; proc = proc->next_proc)
|
|
|
- if (proc->temp > temp)
|
|
|
- temp = proc->temp;
|
|
|
+ float temp = cgpu->temp;
|
|
|
+ if (!opt_show_procs)
|
|
|
+ {
|
|
|
+ // Find the highest temperature of all processors
|
|
|
+ for (struct cgpu_info *proc = cgpu; proc; proc = proc->next_proc)
|
|
|
+ if (proc->temp > temp)
|
|
|
+ temp = proc->temp;
|
|
|
+ }
|
|
|
+ temperature_column(&buf[bufln], abufsz, for_curses, &temp);
|
|
|
}
|
|
|
- temperature_column_tail(&buf[strlen(buf)], for_curses, &temp);
|
|
|
}
|
|
|
|
|
|
#ifdef HAVE_CURSES
|
|
|
@@ -2795,7 +2822,7 @@ void get_statline3(char *buf, struct cgpu_info *cgpu, bool for_curses, bool opt_
|
|
|
if (unlikely(all_off))
|
|
|
cHrStatsI = 2;
|
|
|
|
|
|
- format_statline(buf,
|
|
|
+ format_statline(buf, bufsz,
|
|
|
cHrStatsOpt[cHrStatsI],
|
|
|
aHr, uHr,
|
|
|
accepted, rejected, stale,
|
|
|
@@ -2806,21 +2833,23 @@ void get_statline3(char *buf, struct cgpu_info *cgpu, bool for_curses, bool opt_
|
|
|
else
|
|
|
#endif
|
|
|
{
|
|
|
- tailsprintf(buf, "%ds:%s avg:%s u:%s | A:%d R:%d+%d(%s) HW:%d/%s",
|
|
|
+ percentf4(rejpcbuf, sizeof(rejpcbuf), wnotaccepted, waccepted);
|
|
|
+ percentf3(bnbuf, sizeof(bnbuf), badnonces, allnonces);
|
|
|
+ tailsprintf(buf, bufsz, "%ds:%s avg:%s u:%s | A:%d R:%d+%d(%s) HW:%d/%s",
|
|
|
opt_log_interval,
|
|
|
cHr, aHr, uHr,
|
|
|
accepted,
|
|
|
rejected,
|
|
|
stale,
|
|
|
- percentf(wnotaccepted, waccepted, rejpcbuf),
|
|
|
+ rejpcbuf,
|
|
|
hwerrs,
|
|
|
- percentf2(badnonces, allnonces, bnbuf)
|
|
|
+ bnbuf
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-#define get_statline(buf, cgpu) get_statline3(buf, cgpu, false, opt_show_procs)
|
|
|
-#define get_statline2(buf, cgpu, for_curses) get_statline3(buf, cgpu, for_curses, opt_show_procs)
|
|
|
+#define get_statline(buf, bufsz, cgpu) get_statline3(buf, bufsz, cgpu, false, opt_show_procs)
|
|
|
+#define get_statline2(buf, bufsz, cgpu, for_curses) get_statline3(buf, bufsz, cgpu, for_curses, opt_show_procs)
|
|
|
|
|
|
static void text_print_status(int thr_id)
|
|
|
{
|
|
|
@@ -2829,7 +2858,7 @@ static void text_print_status(int thr_id)
|
|
|
|
|
|
cgpu = get_thr_cgpu(thr_id);
|
|
|
if (cgpu) {
|
|
|
- get_statline(logline, cgpu);
|
|
|
+ get_statline(logline, sizeof(logline), cgpu);
|
|
|
printf("%s\n", logline);
|
|
|
}
|
|
|
}
|
|
|
@@ -2920,6 +2949,18 @@ void bfg_hline(WINDOW *win, int y)
|
|
|
|
|
|
static int menu_attr = A_REVERSE;
|
|
|
|
|
|
+#define CURBUFSIZ 256
|
|
|
+#define cg_mvwprintw(win, y, x, fmt, ...) do { \
|
|
|
+ char tmp42[CURBUFSIZ]; \
|
|
|
+ snprintf(tmp42, sizeof(tmp42), fmt, ##__VA_ARGS__); \
|
|
|
+ mvwprintw(win, y, x, "%s", tmp42); \
|
|
|
+} while (0)
|
|
|
+#define cg_wprintw(win, fmt, ...) do { \
|
|
|
+ char tmp42[CURBUFSIZ]; \
|
|
|
+ snprintf(tmp42, sizeof(tmp42), fmt, ##__VA_ARGS__); \
|
|
|
+ wprintw(win, "%s", tmp42); \
|
|
|
+} while (0)
|
|
|
+
|
|
|
/* Must be called with curses mutex lock held and curses_active */
|
|
|
static void curses_print_status(void)
|
|
|
{
|
|
|
@@ -2932,7 +2973,7 @@ static void curses_print_status(void)
|
|
|
efficiency = total_bytes_xfer ? total_diff_accepted * 2048. / total_bytes_xfer : 0.0;
|
|
|
|
|
|
wattron(statuswin, A_BOLD);
|
|
|
- mvwprintw(statuswin, 0, 0, " " PACKAGE " version " VERSION " - Started: %s", datestamp);
|
|
|
+ cg_mvwprintw(statuswin, 0, 0, " " PACKAGE " version " VERSION " - Started: %s", datestamp);
|
|
|
timer_set_now(&now);
|
|
|
{
|
|
|
unsigned int days, hours;
|
|
|
@@ -2944,7 +2985,7 @@ static void curses_print_status(void)
|
|
|
d = div(d.rem, 3600);
|
|
|
hours = d.quot;
|
|
|
d = div(d.rem, 60);
|
|
|
- wprintw(statuswin, " - [%3u day%c %02d:%02d:%02d]"
|
|
|
+ cg_wprintw(statuswin, " - [%3u day%c %02d:%02d:%02d]"
|
|
|
, days
|
|
|
, (days == 1) ? ' ' : 's'
|
|
|
, hours
|
|
|
@@ -2960,12 +3001,13 @@ static void curses_print_status(void)
|
|
|
utility = total_accepted / total_secs * 60;
|
|
|
|
|
|
char bwstr[12];
|
|
|
- mvwprintw(statuswin, 4, 0, " ST:%d F:%d NB:%d AS:%d BW:[%s] E:%.2f U:%.1f/m BS:%s",
|
|
|
+ cg_mvwprintw(statuswin, 4, 0, " ST:%d F:%d NB:%d AS:%d BW:[%s] E:%.2f U:%.1f/m BS:%s",
|
|
|
__total_staged(),
|
|
|
total_go + total_ro,
|
|
|
new_blocks,
|
|
|
total_submitting,
|
|
|
- multi_format_unit(bwstr, false, "B/s", H2B_SHORT, "/", 2,
|
|
|
+ multi_format_unit2(bwstr, sizeof(bwstr),
|
|
|
+ false, "B/s", H2B_SHORT, "/", 2,
|
|
|
(float)(total_bytes_rcvd / total_secs),
|
|
|
(float)(total_bytes_sent / total_secs)),
|
|
|
efficiency,
|
|
|
@@ -2973,17 +3015,17 @@ static void curses_print_status(void)
|
|
|
best_share);
|
|
|
wclrtoeol(statuswin);
|
|
|
if ((pool_strategy == POOL_LOADBALANCE || pool_strategy == POOL_BALANCE) && total_pools > 1) {
|
|
|
- mvwprintw(statuswin, 2, 0, " Connected to multiple pools with%s LP",
|
|
|
+ cg_mvwprintw(statuswin, 2, 0, " Connected to multiple pools with%s LP",
|
|
|
have_longpoll ? "": "out");
|
|
|
} else if (pool->has_stratum) {
|
|
|
- mvwprintw(statuswin, 2, 0, " Connected to %s diff %s with stratum as user %s",
|
|
|
+ cg_mvwprintw(statuswin, 2, 0, " Connected to %s diff %s with stratum as user %s",
|
|
|
pool->sockaddr_url, pool->diff, pool->rpc_user);
|
|
|
} else {
|
|
|
- mvwprintw(statuswin, 2, 0, " Connected to %s diff %s with%s LP as user %s",
|
|
|
+ cg_mvwprintw(statuswin, 2, 0, " Connected to %s diff %s with%s LP as user %s",
|
|
|
pool->sockaddr_url, pool->diff, have_longpoll ? "": "out", pool->rpc_user);
|
|
|
}
|
|
|
wclrtoeol(statuswin);
|
|
|
- mvwprintw(statuswin, 3, 0, " Block: %s Diff:%s (%s) Started: %s",
|
|
|
+ cg_mvwprintw(statuswin, 3, 0, " Block: %s Diff:%s (%s) Started: %s",
|
|
|
current_hash, block_diff, net_hashrate, blocktime);
|
|
|
|
|
|
logdiv = statusy - 1;
|
|
|
@@ -3006,7 +3048,7 @@ static void curses_print_status(void)
|
|
|
#endif
|
|
|
|
|
|
wattron(statuswin, menu_attr);
|
|
|
- mvwprintw(statuswin, 1, 0, " [M]anage devices [P]ool management [S]ettings [D]isplay options [H]elp [Q]uit ");
|
|
|
+ cg_mvwprintw(statuswin, 1, 0, " [M]anage devices [P]ool management [S]ettings [D]isplay options [H]elp [Q]uit ");
|
|
|
wattroff(statuswin, menu_attr);
|
|
|
}
|
|
|
|
|
|
@@ -3045,7 +3087,7 @@ static void curses_print_devstatus(struct cgpu_info *cgpu)
|
|
|
if (wmove(statuswin, ypos, 0) == ERR)
|
|
|
return;
|
|
|
|
|
|
- get_statline2(logline, cgpu, true);
|
|
|
+ get_statline2(logline, sizeof(logline), cgpu, true);
|
|
|
if (selecting_device && (opt_show_procs ? (selected_device == cgpu->cgminer_id) : (devices[selected_device]->device == cgpu)))
|
|
|
wattron(statuswin, A_REVERSE);
|
|
|
bfg_waddstr(statuswin, logline);
|
|
|
@@ -3253,11 +3295,11 @@ void share_result_msg(const struct work *work, const char *disp, const char *rea
|
|
|
|
|
|
cgpu = get_thr_cgpu(work->thr_id);
|
|
|
|
|
|
- suffix_string(work->share_diff, shrdiffdisp, 0);
|
|
|
- suffix_string(tgtdiff, tgtdiffdisp, 0);
|
|
|
+ suffix_string(work->share_diff, shrdiffdisp, sizeof(shrdiffdisp), 0);
|
|
|
+ suffix_string(tgtdiff, tgtdiffdisp, sizeof(tgtdiffdisp), 0);
|
|
|
|
|
|
if (total_pools > 1)
|
|
|
- sprintf(where, " pool %d", work->pool->pool_no);
|
|
|
+ snprintf(where, sizeof(where), " pool %d", work->pool->pool_no);
|
|
|
else
|
|
|
where[0] = '\0';
|
|
|
|
|
|
@@ -3385,7 +3427,7 @@ share_result(json_t *val, json_t *res, json_t *err, const struct work *work,
|
|
|
|
|
|
strcpy(reason, "");
|
|
|
if (total_pools > 1)
|
|
|
- sprintf(where, "pool %d", work->pool->pool_no);
|
|
|
+ snprintf(where, sizeof(where), "pool %d", work->pool->pool_no);
|
|
|
else
|
|
|
strcpy(where, "");
|
|
|
|
|
|
@@ -3534,8 +3576,8 @@ static bool submit_upstream_work_completed(struct work *work, bool resubmit, str
|
|
|
memcpy(&tm_submit_reply, tm, sizeof(struct tm));
|
|
|
|
|
|
if (work->clone) {
|
|
|
- sprintf(workclone, "C:%1.3f",
|
|
|
- tdiff((struct timeval *)&(work->tv_cloned),
|
|
|
+ snprintf(workclone, sizeof(workclone), "C:%1.3f",
|
|
|
+ tdiff((struct timeval *)&(work->tv_cloned),
|
|
|
(struct timeval *)&(work->tv_getwork_reply)));
|
|
|
}
|
|
|
else
|
|
|
@@ -3544,7 +3586,8 @@ static bool submit_upstream_work_completed(struct work *work, bool resubmit, str
|
|
|
if (work->work_difficulty < 1)
|
|
|
diffplaces = 6;
|
|
|
|
|
|
- sprintf(worktime, " <-%08lx.%08lx M:%c D:%1.*f G:%02d:%02d:%02d:%1.3f %s (%1.3f) W:%1.3f (%1.3f) S:%1.3f R:%02d:%02d:%02d",
|
|
|
+ snprintf(worktime, sizeof(worktime),
|
|
|
+ " <-%08lx.%08lx M:%c D:%1.*f G:%02d:%02d:%02d:%1.3f %s (%1.3f) W:%1.3f (%1.3f) S:%1.3f R:%02d:%02d:%02d",
|
|
|
(unsigned long)swab32(*(uint32_t *)&(work->data[opt_scrypt ? 32 : 28])),
|
|
|
(unsigned long)swab32(*(uint32_t *)&(work->data[opt_scrypt ? 28 : 24])),
|
|
|
work->getwork_mode, diffplaces, work->work_difficulty,
|
|
|
@@ -3566,7 +3609,7 @@ static bool submit_upstream_work_completed(struct work *work, bool resubmit, str
|
|
|
|
|
|
cgpu = get_thr_cgpu(thr_id);
|
|
|
|
|
|
- get_statline(logline, cgpu);
|
|
|
+ get_statline(logline, sizeof(logline), cgpu);
|
|
|
applog(LOG_INFO, "%s", logline);
|
|
|
}
|
|
|
|
|
|
@@ -3694,7 +3737,7 @@ static void calc_diff(struct work *work, int known)
|
|
|
difficulty = work->work_difficulty;
|
|
|
|
|
|
pool_stats->last_diff = difficulty;
|
|
|
- suffix_string((uint64_t)difficulty, work->pool->diff, 0);
|
|
|
+ suffix_string((uint64_t)difficulty, work->pool->diff, sizeof(work->pool->diff), 0);
|
|
|
|
|
|
if (difficulty == pool_stats->min_diff)
|
|
|
pool_stats->min_diff_count++;
|
|
|
@@ -4159,7 +4202,7 @@ static void push_curl_entry(struct curl_ent *ce, struct pool *pool)
|
|
|
{
|
|
|
mutex_lock(&pool->pool_lock);
|
|
|
if (!ce || !ce->curl)
|
|
|
- quit(1, "Attempted to add NULL in push_curl_entry");
|
|
|
+ quithere(1, "Attempted to add NULL");
|
|
|
LL_PREPEND(pool->curllist, ce);
|
|
|
cgtime(&ce->tv);
|
|
|
pthread_cond_broadcast(&pool->cr_cond);
|
|
|
@@ -4460,7 +4503,7 @@ static uint64_t share_diff(const struct work *work)
|
|
|
if (unlikely(ret > best_diff)) {
|
|
|
new_best = true;
|
|
|
best_diff = ret;
|
|
|
- suffix_string(best_diff, best_share, 0);
|
|
|
+ suffix_string(best_diff, best_share, sizeof(best_share), 0);
|
|
|
}
|
|
|
if (unlikely(ret > work->pool->best_diff))
|
|
|
work->pool->best_diff = ret;
|
|
|
@@ -4798,7 +4841,7 @@ next_write_sws_del:
|
|
|
sshare_id =
|
|
|
sshare->id = swork_id++;
|
|
|
HASH_ADD_INT(stratum_shares, id, sshare);
|
|
|
- sprintf(s, "{\"params\": [\"%s\", \"%s\", \"%s\", \"%s\", \"%s\"], \"id\": %d, \"method\": \"mining.submit\"}",
|
|
|
+ snprintf(s, 1024, "{\"params\": [\"%s\", \"%s\", \"%s\", \"%s\", \"%s\"], \"id\": %d, \"method\": \"mining.submit\"}",
|
|
|
pool->rpc_user, work->job_id, nonce2hex, ntimehex, noncehex, sshare->id);
|
|
|
mutex_unlock(&sshare_lock);
|
|
|
|
|
|
@@ -5204,7 +5247,7 @@ static void set_curblock(char *hexstr, unsigned char *hash)
|
|
|
free(current_fullhash);
|
|
|
current_fullhash = malloc(65);
|
|
|
bin2hex(current_fullhash, hash_swap, 32);
|
|
|
- get_timestamp(blocktime, block_time);
|
|
|
+ get_timestamp(blocktime, sizeof(blocktime), block_time);
|
|
|
cg_wunlock(&ch_lock);
|
|
|
|
|
|
applog(LOG_INFO, "New block: %s diff %s (%s)", current_hash, block_diff, net_hashrate);
|
|
|
@@ -5250,8 +5293,9 @@ static void set_blockdiff(const struct work *work)
|
|
|
diff = target_diff(target);
|
|
|
diff64 = diff;
|
|
|
|
|
|
- suffix_string(diff64, block_diff, 0);
|
|
|
- format_unit(net_hashrate, true, "h/s", H2B_SHORT, diff * 7158278, -1);
|
|
|
+ suffix_string(diff64, block_diff, sizeof(block_diff), 0);
|
|
|
+ format_unit2(net_hashrate, sizeof(net_hashrate),
|
|
|
+ true, "h/s", H2B_SHORT, diff * 7158278, -1);
|
|
|
if (unlikely(current_diff != diff))
|
|
|
applog(LOG_NOTICE, "Network difficulty changed to %s (%s)", block_diff, net_hashrate);
|
|
|
current_diff = diff;
|
|
|
@@ -5486,10 +5530,10 @@ static void display_pool_summary(struct pool *pool)
|
|
|
wlog(" Rejected difficulty shares: %1.f\n", pool->diff_rejected);
|
|
|
pool_secs = timer_elapsed(&pool->cgminer_stats.start_tv, NULL);
|
|
|
wlog(" Network transfer: %s (%s)\n",
|
|
|
- multi_format_unit(xfer, true, "B", H2B_SPACED, " / ", 2,
|
|
|
+ multi_format_unit2(xfer, sizeof(xfer), true, "B", H2B_SPACED, " / ", 2,
|
|
|
(float)pool->cgminer_pool_stats.net_bytes_received,
|
|
|
(float)pool->cgminer_pool_stats.net_bytes_sent),
|
|
|
- multi_format_unit(bw, true, "B/s", H2B_SPACED, " / ", 2,
|
|
|
+ multi_format_unit2(bw, sizeof(bw), true, "B/s", H2B_SPACED, " / ", 2,
|
|
|
(float)(pool->cgminer_pool_stats.net_bytes_received / pool_secs),
|
|
|
(float)(pool->cgminer_pool_stats.net_bytes_sent / pool_secs)));
|
|
|
uint64_t pool_bytes_xfer = pool->cgminer_pool_stats.net_bytes_received + pool->cgminer_pool_stats.net_bytes_sent;
|
|
|
@@ -5795,7 +5839,7 @@ void zero_bestshare(void)
|
|
|
|
|
|
best_diff = 0;
|
|
|
memset(best_share, 0, 8);
|
|
|
- suffix_string(best_diff, best_share, 0);
|
|
|
+ suffix_string(best_diff, best_share, sizeof(best_share), 0);
|
|
|
|
|
|
for (i = 0; i < total_pools; i++) {
|
|
|
struct pool *pool = pools[i];
|
|
|
@@ -6297,7 +6341,7 @@ retry:
|
|
|
char *str, filename[PATH_MAX], prompt[PATH_MAX + 50];
|
|
|
|
|
|
default_save_file(filename);
|
|
|
- sprintf(prompt, "Config filename to write (Enter for default) [%s]", filename);
|
|
|
+ snprintf(prompt, sizeof(prompt), "Config filename to write (Enter for default) [%s]", filename);
|
|
|
str = curses_input(prompt);
|
|
|
if (strcmp(str, "-1")) {
|
|
|
struct stat statbuf;
|
|
|
@@ -6356,7 +6400,7 @@ refresh:
|
|
|
clear_logwin();
|
|
|
wlogprint("Select processor to manage using up/down arrow keys\n");
|
|
|
|
|
|
- get_statline3(logline, cgpu, true, true);
|
|
|
+ get_statline3(logline, sizeof(logline), cgpu, true, true);
|
|
|
wattron(logwin, A_BOLD);
|
|
|
wlogprint("%s", logline);
|
|
|
wattroff(logwin, A_BOLD);
|
|
|
@@ -6640,12 +6684,12 @@ static void hashmeter(int thr_id, struct timeval *diff,
|
|
|
thr_id, hashes_done, hashes_done / 1000 / secs);
|
|
|
|
|
|
/* Rolling average for each thread and each device */
|
|
|
- decay_time(&thr->rolling, local_mhashes / secs);
|
|
|
+ decay_time(&thr->rolling, local_mhashes / secs, secs);
|
|
|
for (i = 0; i < threadobj; i++)
|
|
|
thread_rolling += cgpu->thr[i]->rolling;
|
|
|
|
|
|
mutex_lock(&hash_lock);
|
|
|
- decay_time(&cgpu->rolling, thread_rolling);
|
|
|
+ decay_time(&cgpu->rolling, thread_rolling, secs);
|
|
|
cgpu->total_mhashes += local_mhashes;
|
|
|
mutex_unlock(&hash_lock);
|
|
|
|
|
|
@@ -6663,7 +6707,7 @@ static void hashmeter(int thr_id, struct timeval *diff,
|
|
|
|
|
|
*last_msg_tv = now;
|
|
|
|
|
|
- get_statline(logline, cgpu);
|
|
|
+ get_statline(logline, sizeof(logline), cgpu);
|
|
|
if (!curses_active) {
|
|
|
printf("%s \r", logline);
|
|
|
fflush(stdout);
|
|
|
@@ -6687,15 +6731,16 @@ static void hashmeter(int thr_id, struct timeval *diff,
|
|
|
cgtime(&total_tv_end);
|
|
|
|
|
|
local_secs = (double)total_diff.tv_sec + ((double)total_diff.tv_usec / 1000000.0);
|
|
|
- decay_time(&rolling, local_mhashes_done / local_secs);
|
|
|
+ decay_time(&rolling, local_mhashes_done / local_secs, local_secs);
|
|
|
global_hashrate = roundl(rolling) * 1000000;
|
|
|
|
|
|
timersub(&total_tv_end, &total_tv_start, &total_diff);
|
|
|
total_secs = (double)total_diff.tv_sec +
|
|
|
((double)total_diff.tv_usec / 1000000.0);
|
|
|
|
|
|
- multi_format_unit_array(
|
|
|
+ multi_format_unit_array2(
|
|
|
((char*[]){cHr, aHr, uHr}),
|
|
|
+ ((size_t[]){h2bs_fmt_size[H2B_NOUNIT], h2bs_fmt_size[H2B_NOUNIT], h2bs_fmt_size[H2B_SPACED]}),
|
|
|
true, "h/s", H2B_SHORT,
|
|
|
3,
|
|
|
1e6*rolling,
|
|
|
@@ -6738,9 +6783,9 @@ static void hashmeter(int thr_id, struct timeval *diff,
|
|
|
}
|
|
|
|
|
|
if (working_devs == working_procs)
|
|
|
- sprintf(statusline, "%s%d ", bad ? "\2" : "", working_devs);
|
|
|
+ snprintf(statusline, sizeof(statusline), "%s%d ", bad ? "\2" : "", working_devs);
|
|
|
else
|
|
|
- sprintf(statusline, "%s%d/%d ", bad ? "\2" : "", working_devs, working_procs);
|
|
|
+ snprintf(statusline, sizeof(statusline), "%s%d/%d ", bad ? "\2" : "", working_devs, working_procs);
|
|
|
|
|
|
divx = 7;
|
|
|
if (opt_show_procs && !opt_compact)
|
|
|
@@ -6753,9 +6798,9 @@ static void hashmeter(int thr_id, struct timeval *diff,
|
|
|
++divx;
|
|
|
}
|
|
|
|
|
|
- temperature_column_tail(&statusline[divx], true, &temp);
|
|
|
+ temperature_column(&statusline[divx], sizeof(statusline)-divx, true, &temp);
|
|
|
|
|
|
- format_statline(statusline,
|
|
|
+ format_statline(statusline, sizeof(statusline),
|
|
|
cHr, aHr,
|
|
|
uHr,
|
|
|
total_accepted,
|
|
|
@@ -6771,7 +6816,11 @@ static void hashmeter(int thr_id, struct timeval *diff,
|
|
|
memmove(&uHr[6], &uHr[5], strlen(&uHr[5]) + 1);
|
|
|
uHr[5] = ' ';
|
|
|
|
|
|
- sprintf(logstatusline, "%s%ds:%s avg:%s u:%s | A:%d R:%d+%d(%s) HW:%d/%s",
|
|
|
+ percentf4(rejpcbuf, sizeof(rejpcbuf), total_diff_rejected + total_diff_stale, total_diff_accepted);
|
|
|
+ percentf3(bnbuf, sizeof(bnbuf), total_bad_nonces, total_diff1);
|
|
|
+
|
|
|
+ snprintf(logstatusline, sizeof(logstatusline),
|
|
|
+ "%s%ds:%s avg:%s u:%s | A:%d R:%d+%d(%s) HW:%d/%s",
|
|
|
want_per_device_stats ? "ALL " : "",
|
|
|
opt_log_interval,
|
|
|
cHr, aHr,
|
|
|
@@ -6779,9 +6828,9 @@ static void hashmeter(int thr_id, struct timeval *diff,
|
|
|
total_accepted,
|
|
|
total_rejected,
|
|
|
total_stale,
|
|
|
- percentf(total_diff_rejected + total_diff_stale, total_diff_accepted, rejpcbuf),
|
|
|
+ rejpcbuf,
|
|
|
hw_errors,
|
|
|
- percentf2(total_bad_nonces, total_diff1, bnbuf)
|
|
|
+ bnbuf
|
|
|
);
|
|
|
|
|
|
|
|
|
@@ -6807,7 +6856,8 @@ void hashmeter2(struct thr_info *thr)
|
|
|
cgtime(&tv_now);
|
|
|
timersub(&tv_now, &thr->tv_lastupdate, &tv_elapsed);
|
|
|
/* Update the hashmeter at most 5 times per second */
|
|
|
- if (tv_elapsed.tv_sec > 0 || tv_elapsed.tv_usec > 200) {
|
|
|
+ if ((thr->hashes_done && (tv_elapsed.tv_sec > 0 || tv_elapsed.tv_usec > 200000)) ||
|
|
|
+ tv_elapsed.tv_sec >= opt_log_interval) {
|
|
|
hashmeter(thr->id, &tv_elapsed, thr->hashes_done);
|
|
|
thr->hashes_done = 0;
|
|
|
thr->tv_lastupdate = tv_now;
|
|
|
@@ -7664,8 +7714,7 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
|
|
|
|
|
|
clean_work(work);
|
|
|
|
|
|
- /* Use intermediate lock to update the one pool variable */
|
|
|
- cg_ilock(&pool->data_lock);
|
|
|
+ cg_wlock(&pool->data_lock);
|
|
|
|
|
|
/* Generate coinbase */
|
|
|
bytes_resize(&work->nonce2, pool->n2size);
|
|
|
@@ -7685,7 +7734,7 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
|
|
|
pool->nonce2++;
|
|
|
|
|
|
/* Downgrade to a read lock to read off the pool variables */
|
|
|
- cg_dlock(&pool->data_lock);
|
|
|
+ cg_dwlock(&pool->data_lock);
|
|
|
|
|
|
/* Generate merkle root */
|
|
|
gen_hash(coinbase, merkle_root, bytes_len(&pool->swork.coinbase));
|
|
|
@@ -8796,7 +8845,7 @@ static void log_print_status(struct cgpu_info *cgpu)
|
|
|
{
|
|
|
char logline[255];
|
|
|
|
|
|
- get_statline(logline, cgpu);
|
|
|
+ get_statline(logline, sizeof(logline), cgpu);
|
|
|
applog(LOG_WARNING, "%s", logline);
|
|
|
}
|
|
|
|
|
|
@@ -8838,10 +8887,10 @@ void print_summary(void)
|
|
|
applog(LOG_WARNING, "Rejected difficulty shares: %1.f", total_diff_rejected);
|
|
|
applog(LOG_WARNING, "Hardware errors: %d", hw_errors);
|
|
|
applog(LOG_WARNING, "Network transfer: %s (%s)",
|
|
|
- multi_format_unit(xfer, true, "B", H2B_SPACED, " / ", 2,
|
|
|
+ multi_format_unit2(xfer, sizeof(xfer), true, "B", H2B_SPACED, " / ", 2,
|
|
|
(float)total_bytes_rcvd,
|
|
|
(float)total_bytes_sent),
|
|
|
- multi_format_unit(bw, true, "B/s", H2B_SPACED, " / ", 2,
|
|
|
+ multi_format_unit2(bw, sizeof(bw), true, "B/s", H2B_SPACED, " / ", 2,
|
|
|
(float)(total_bytes_rcvd / total_secs),
|
|
|
(float)(total_bytes_sent / total_secs)));
|
|
|
applog(LOG_WARNING, "Efficiency (accepted shares * difficulty / 2 KB): %.2f", efficiency);
|
|
|
@@ -8869,10 +8918,10 @@ void print_summary(void)
|
|
|
applog(LOG_WARNING, " Rejected difficulty shares: %1.f", pool->diff_rejected);
|
|
|
pool_secs = timer_elapsed(&pool->cgminer_stats.start_tv, NULL);
|
|
|
applog(LOG_WARNING, " Network transfer: %s (%s)",
|
|
|
- multi_format_unit(xfer, true, "B", H2B_SPACED, " / ", 2,
|
|
|
+ multi_format_unit2(xfer, sizeof(xfer), true, "B", H2B_SPACED, " / ", 2,
|
|
|
(float)pool->cgminer_pool_stats.net_bytes_received,
|
|
|
(float)pool->cgminer_pool_stats.net_bytes_sent),
|
|
|
- multi_format_unit(bw, true, "B/s", H2B_SPACED, " / ", 2,
|
|
|
+ multi_format_unit2(bw, sizeof(bw), true, "B/s", H2B_SPACED, " / ", 2,
|
|
|
(float)(pool->cgminer_pool_stats.net_bytes_received / pool_secs),
|
|
|
(float)(pool->cgminer_pool_stats.net_bytes_sent / pool_secs)));
|
|
|
uint64_t pool_bytes_xfer = pool->cgminer_pool_stats.net_bytes_received + pool->cgminer_pool_stats.net_bytes_sent;
|
|
|
@@ -9008,13 +9057,16 @@ static void *test_pool_thread(void *arg)
|
|
|
* active it returns false. */
|
|
|
bool add_pool_details(struct pool *pool, bool live, char *url, char *user, char *pass)
|
|
|
{
|
|
|
+ size_t siz;
|
|
|
+
|
|
|
pool->rpc_url = url;
|
|
|
pool->rpc_user = user;
|
|
|
pool->rpc_pass = pass;
|
|
|
- pool->rpc_userpass = malloc(strlen(pool->rpc_user) + strlen(pool->rpc_pass) + 2);
|
|
|
+ siz = strlen(pool->rpc_user) + strlen(pool->rpc_pass) + 2;
|
|
|
+ pool->rpc_userpass = malloc(siz);
|
|
|
if (!pool->rpc_userpass)
|
|
|
quit(1, "Failed to malloc userpass");
|
|
|
- sprintf(pool->rpc_userpass, "%s:%s", pool->rpc_user, pool->rpc_pass);
|
|
|
+ snprintf(pool->rpc_userpass, siz, "%s:%s", pool->rpc_user, pool->rpc_pass);
|
|
|
|
|
|
pool->testing = true;
|
|
|
pool->idle = true;
|
|
|
@@ -9641,7 +9693,7 @@ int main(int argc, char *argv[])
|
|
|
|
|
|
notifier_init(submit_waiting_notifier);
|
|
|
|
|
|
- sprintf(packagename, "%s %s", PACKAGE, VERSION);
|
|
|
+ snprintf(packagename, sizeof(packagename), "%s %s", PACKAGE, VERSION);
|
|
|
|
|
|
#ifdef WANT_CPUMINE
|
|
|
init_max_name_len();
|
|
|
@@ -9727,6 +9779,8 @@ int main(int argc, char *argv[])
|
|
|
if (opt_benchmark) {
|
|
|
struct pool *pool;
|
|
|
|
|
|
+ if (opt_scrypt)
|
|
|
+ quit(1, "Cannot use benchmark mode with scrypt");
|
|
|
want_longpoll = false;
|
|
|
pool = add_pool();
|
|
|
pool->rpc_url = malloc(255);
|
|
|
@@ -9885,6 +9939,7 @@ int main(int argc, char *argv[])
|
|
|
|
|
|
for (i = 0; i < total_pools; i++) {
|
|
|
struct pool *pool = pools[i];
|
|
|
+ size_t siz;
|
|
|
|
|
|
pool->cgminer_stats.getwork_wait_min.tv_sec = MIN_SEC_UNSET;
|
|
|
pool->cgminer_pool_stats.getwork_wait_min.tv_sec = MIN_SEC_UNSET;
|
|
|
@@ -9895,10 +9950,11 @@ int main(int argc, char *argv[])
|
|
|
if (!pool->rpc_userpass) {
|
|
|
if (!pool->rpc_user || !pool->rpc_pass)
|
|
|
quit(1, "No login credentials supplied for pool %u %s", i, pool->rpc_url);
|
|
|
- pool->rpc_userpass = malloc(strlen(pool->rpc_user) + strlen(pool->rpc_pass) + 2);
|
|
|
+ siz = strlen(pool->rpc_user) + strlen(pool->rpc_pass) + 2;
|
|
|
+ pool->rpc_userpass = malloc(siz);
|
|
|
if (!pool->rpc_userpass)
|
|
|
quit(1, "Failed to malloc userpass");
|
|
|
- sprintf(pool->rpc_userpass, "%s:%s", pool->rpc_user, pool->rpc_pass);
|
|
|
+ snprintf(pool->rpc_userpass, siz, "%s:%s", pool->rpc_user, pool->rpc_pass);
|
|
|
}
|
|
|
}
|
|
|
/* Set the currentpool to pool with priority 0 */
|
|
|
@@ -10021,7 +10077,7 @@ begin_bench:
|
|
|
localtime_r(&miner_start_ts, &schedstart.tm);
|
|
|
if (schedstop.tm.tm_sec)
|
|
|
localtime_r(&miner_start_ts, &schedstop .tm);
|
|
|
- get_datestamp(datestamp, miner_start_ts);
|
|
|
+ get_datestamp(datestamp, sizeof(datestamp), miner_start_ts);
|
|
|
|
|
|
// Initialise processors and threads
|
|
|
k = 0;
|