mirror of
https://github.com/GOSTSec/sgminer
synced 2025-02-02 01:44:23 +00:00
Implement a completely curses based display and don't output to stderr when log is enabled unless it's redirected away from the terminal.
This commit is contained in:
parent
f12edd2fb8
commit
90839cdf5a
@ -22,7 +22,7 @@ cgminer_SOURCES = elist.h miner.h compat.h \
|
||||
sha256_cryptopp.c sha256_sse2_amd64.c
|
||||
|
||||
cgminer_LDFLAGS = $(PTHREAD_FLAGS)
|
||||
cgminer_LDADD = @LIBCURL@ @JANSSON_LIBS@ @PTHREAD_LIBS@ @OPENCL_LIBS@ lib/libgnu.a ccan/libccan.a
|
||||
cgminer_LDADD = @LIBCURL@ @JANSSON_LIBS@ @PTHREAD_LIBS@ @OPENCL_LIBS@ @NCURSES_LIBS@ lib/libgnu.a ccan/libccan.a
|
||||
cgminer_CPPFLAGS = @LIBCURL_CPPFLAGS@ -I$(top_builddir)/lib -I$(top_srcdir)/lib
|
||||
|
||||
if HAVE_x86_64
|
||||
|
1
README
1
README
@ -7,6 +7,7 @@ Dependencies:
|
||||
libcurl http://curl.haxx.se/libcurl/
|
||||
jansson http://www.digip.org/jansson/
|
||||
(jansson is included in-tree and an installed one may conflict)
|
||||
libncurses5-dev (or libpdcurses on WIN32)
|
||||
|
||||
Basic *nix build instructions:
|
||||
To build with GPU mining support:
|
||||
|
@ -60,6 +60,7 @@ LIBS=$SAVED_LIBS
|
||||
|
||||
AC_CHECK_LIB(jansson, json_loads, request_jansson=false, request_jansson=true)
|
||||
AC_CHECK_LIB(pthread, pthread_create, PTHREAD_LIBS=-lpthread)
|
||||
AC_CHECK_LIB(ncurses, addstr, NCURSES_LIBS=-lncurses)
|
||||
|
||||
AM_CONDITIONAL([WANT_JANSSON], [test x$request_jansson = xtrue])
|
||||
AM_CONDITIONAL([HAVE_WINDOWS], [test x$have_win32 = xtrue])
|
||||
@ -148,6 +149,7 @@ AC_SUBST(OPENCL_LIBS)
|
||||
AC_SUBST(JANSSON_LIBS)
|
||||
AC_SUBST(PTHREAD_FLAGS)
|
||||
AC_SUBST(PTHREAD_LIBS)
|
||||
AC_SUBST(NCURSES_LIBS)
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
|
165
main.c
165
main.c
@ -28,6 +28,7 @@
|
||||
#include <ccan/opt/opt.h>
|
||||
#include <jansson.h>
|
||||
#include <curl/curl.h>
|
||||
#include <curses.h>
|
||||
#include "compat.h"
|
||||
#include "miner.h"
|
||||
#include "findnonce.h"
|
||||
@ -507,13 +508,108 @@ err_out:
|
||||
return false;
|
||||
}
|
||||
|
||||
static double total_secs;
|
||||
static char statusline[256];
|
||||
|
||||
static inline void print_status(void)
|
||||
static inline int gpu_from_thr_id(int thr_id)
|
||||
{
|
||||
printf("%s\r", statusline);
|
||||
fflush(stdout);
|
||||
return thr_id % nDevs;
|
||||
}
|
||||
|
||||
static inline int cpu_from_thr_id(int thr_id)
|
||||
{
|
||||
return (thr_id - gpu_threads) % num_processors;
|
||||
}
|
||||
|
||||
static WINDOW * mainwin;
|
||||
static double total_secs = 0.1;
|
||||
static char statusline[256];
|
||||
static int cpucursor, gpucursor, logstart, logcursor;
|
||||
static bool curses_active = false;
|
||||
static struct cgpu_info *gpus, *cpus;
|
||||
|
||||
static inline void print_status(int thr_id)
|
||||
{
|
||||
int x;
|
||||
|
||||
if (unlikely(!curses_active))
|
||||
return;
|
||||
getyx(mainwin, logcursor, x);
|
||||
|
||||
move(2,0);
|
||||
printw("Totals: %s", statusline);
|
||||
clrtoeol();
|
||||
|
||||
if (thr_id && thr_id < gpu_threads) {
|
||||
int gpu = gpu_from_thr_id(thr_id);
|
||||
struct cgpu_info *cgpu = &gpus[gpu];
|
||||
|
||||
move(gpucursor + gpu, 0);
|
||||
printw("GPU %d: [%.1f Mh/s] [Q:%d A:%d R:%d HW:%d E:%.0f%% U:%.2f/m] ",
|
||||
gpu, cgpu->total_mhashes / total_secs,
|
||||
cgpu->getworks, cgpu->accepted, cgpu->rejected, cgpu->hw_errors,
|
||||
cgpu->efficiency, cgpu->utility);
|
||||
clrtoeol();
|
||||
} else if (thr_id && thr_id >= gpu_threads) {
|
||||
int cpu = cpu_from_thr_id(thr_id);
|
||||
struct cgpu_info *cgpu = &cpus[cpu];
|
||||
|
||||
move(cpucursor + cpu, 0);
|
||||
printw("CPU %d: [%.1f Mh/s] [Q:%d A:%d R:%d HW:%d E:%.0f%% U:%.2f/m]",
|
||||
cpu, cgpu->total_mhashes / total_secs,
|
||||
cgpu->getworks, cgpu->accepted, cgpu->rejected, cgpu->hw_errors,
|
||||
cgpu->efficiency, cgpu->utility);
|
||||
clrtoeol();
|
||||
}
|
||||
|
||||
move(logcursor, 0);
|
||||
refresh();
|
||||
}
|
||||
|
||||
static void refresh_display(void)
|
||||
{
|
||||
int i, x, maxy;
|
||||
|
||||
if (unlikely(!curses_active))
|
||||
return;
|
||||
getyx(mainwin, logcursor, x);
|
||||
|
||||
move(0,0);
|
||||
attron(A_BOLD);
|
||||
printw(PROGRAM_NAME " version " VERSION);
|
||||
attroff(A_BOLD);
|
||||
clrtoeol();
|
||||
move(1, 0);
|
||||
clrtoeol();
|
||||
hline('-', 80);
|
||||
move(3, 0);
|
||||
clrtoeol();
|
||||
hline('-', 80);
|
||||
move(logstart, 0);
|
||||
clrtoeol();
|
||||
hline('-', 80);
|
||||
move(logcursor, 0);
|
||||
|
||||
for (i = 0; i < mining_threads; i++)
|
||||
print_status(i);
|
||||
|
||||
move(logcursor, 0);
|
||||
redrawwin(mainwin);
|
||||
}
|
||||
|
||||
void log_curses(const char *f, va_list ap)
|
||||
{
|
||||
int i, x, maxy;
|
||||
|
||||
if (unlikely(!curses_active))
|
||||
return;
|
||||
vwprintw(mainwin, f, ap);
|
||||
clrtoeol();
|
||||
getyx(mainwin, logcursor, x);
|
||||
|
||||
/* Scroll log output downwards */
|
||||
getmaxyx(mainwin, maxy, x);
|
||||
if (logcursor >= maxy - 1)
|
||||
refresh_display();
|
||||
else
|
||||
refresh();
|
||||
}
|
||||
|
||||
static bool submit_fail = false;
|
||||
@ -526,7 +622,6 @@ static bool submit_upstream_work(const struct work *work)
|
||||
bool rc = false;
|
||||
struct cgpu_info *cgpu = thr_info[work->thr_id].cgpu;
|
||||
CURL *curl = curl_easy_init();
|
||||
double utility, efficiency;
|
||||
|
||||
if (unlikely(!curl)) {
|
||||
applog(LOG_ERR, "CURL initialisation failed");
|
||||
@ -573,29 +668,26 @@ static bool submit_upstream_work(const struct work *work)
|
||||
if (opt_debug)
|
||||
applog(LOG_DEBUG, "PROOF OF WORK RESULT: true (yay!!!)");
|
||||
if (!opt_quiet)
|
||||
printf("[Accepted] ");
|
||||
applog(LOG_WARNING, "Share accepted from %sPU %d",
|
||||
cgpu->is_gpu? "G" : "C", cgpu->cpu_gpu);
|
||||
} else {
|
||||
cgpu->rejected++;
|
||||
rejected++;
|
||||
if (opt_debug)
|
||||
applog(LOG_DEBUG, "PROOF OF WORK RESULT: false (booooo)");
|
||||
if (!opt_quiet)
|
||||
printf("[Rejected] ");
|
||||
applog(LOG_WARNING, "Share rejected from %sPU %d",
|
||||
cgpu->is_gpu? "G" : "C", cgpu->cpu_gpu);
|
||||
}
|
||||
|
||||
utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60;
|
||||
efficiency = cgpu->getworks ? cgpu->accepted * 100.0 / cgpu->getworks : 0.0;
|
||||
cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60;
|
||||
cgpu->efficiency = cgpu->getworks ? cgpu->accepted * 100.0 / cgpu->getworks : 0.0;
|
||||
|
||||
if (!opt_quiet) {
|
||||
printf("[%sPU %d] [%.1f Mh/s] [Q:%d A:%d R:%d HW:%d E:%.0f%% U:%.2f/m] \n",
|
||||
cgpu->is_gpu? "G" : "C", cgpu->cpu_gpu, cgpu->total_mhashes / total_secs,
|
||||
cgpu->getworks, cgpu->accepted, cgpu->rejected, cgpu->hw_errors,
|
||||
efficiency, utility);
|
||||
print_status();
|
||||
}
|
||||
if (!opt_quiet)
|
||||
print_status(work->thr_id);
|
||||
applog(LOG_INFO, "%sPU %d Requested:%d Accepted:%d Rejected:%d HW errors:%d Efficiency:%.0f%% Utility:%.2f/m",
|
||||
cgpu->is_gpu? "G" : "C", cgpu->cpu_gpu, cgpu->getworks, cgpu->accepted, cgpu->rejected, cgpu->hw_errors, efficiency, utility
|
||||
);
|
||||
cgpu->is_gpu? "G" : "C", cgpu->cpu_gpu, cgpu->getworks, cgpu->accepted,
|
||||
cgpu->rejected, cgpu->hw_errors, cgpu->efficiency, cgpu->utility);
|
||||
|
||||
json_decref(val);
|
||||
|
||||
@ -960,7 +1052,7 @@ static void hashmeter(int thr_id, struct timeval *diff,
|
||||
sprintf(statusline, "[(%ds):%.1f (avg):%.1f Mh/s] [Q:%d A:%d R:%d HW:%d E:%.0f%% U:%.2f/m] ",
|
||||
opt_log_interval, rolling_local / local_secs, total_mhashes_done / total_secs,
|
||||
getwork_requested, accepted, rejected, hw_errors, efficiency, utility);
|
||||
print_status();
|
||||
print_status(thr_id);
|
||||
applog(LOG_INFO, "[Rate (%ds):%.1f (avg):%.2f Mhash/s] [Requested:%d Accepted:%d Rejected:%d HW errors:%d Efficiency:%.0f%% Utility:%.2f/m]",
|
||||
opt_log_interval, rolling_local / local_secs, total_mhashes_done / total_secs,
|
||||
getwork_requested, accepted, rejected, hw_errors, efficiency, utility);
|
||||
@ -1183,11 +1275,6 @@ bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
|
||||
return submit_work_sync(thr, work);
|
||||
}
|
||||
|
||||
static inline int cpu_from_thr_id(int thr_id)
|
||||
{
|
||||
return (thr_id - gpu_threads) % num_processors;
|
||||
}
|
||||
|
||||
static void *miner_thread(void *userdata)
|
||||
{
|
||||
struct thr_info *mythr = userdata;
|
||||
@ -1404,11 +1491,6 @@ static inline cl_int queue_kernel_parameters(_clState *clState, dev_blk_ctx *blk
|
||||
return status;
|
||||
}
|
||||
|
||||
static inline int gpu_from_thr_id(int thr_id)
|
||||
{
|
||||
return thr_id % nDevs;
|
||||
}
|
||||
|
||||
static void *gpuminer_thread(void *userdata)
|
||||
{
|
||||
const unsigned long cycle = opt_log_interval / 5 ? : 1;
|
||||
@ -1661,7 +1743,6 @@ int main (int argc, char *argv[])
|
||||
struct thr_info *thr;
|
||||
unsigned int i, j = 0;
|
||||
char name[32];
|
||||
struct cgpu_info *gpus = NULL, *cpus = NULL;
|
||||
|
||||
if (unlikely(pthread_mutex_init(&time_lock, NULL)))
|
||||
return 1;
|
||||
@ -1726,7 +1807,12 @@ int main (int argc, char *argv[])
|
||||
opt_n_threads = num_processors;
|
||||
}
|
||||
|
||||
logcursor = 4;
|
||||
mining_threads = opt_n_threads + gpu_threads;
|
||||
gpucursor = logcursor;
|
||||
cpucursor = gpucursor + total_devices + 1;
|
||||
logstart = cpucursor + (opt_n_threads ? num_processors : 0);
|
||||
logcursor = logstart + 1;
|
||||
|
||||
if (!rpc_userpass) {
|
||||
if (!rpc_user || !rpc_pass) {
|
||||
@ -1907,6 +1993,17 @@ int main (int argc, char *argv[])
|
||||
total_mhashes_done = 0;
|
||||
pthread_mutex_unlock(&hash_lock);
|
||||
|
||||
/* Set up the ncurses interface */
|
||||
if ((mainwin = initscr()) == NULL) {
|
||||
applog(LOG_ERR, "Failed to initscr");
|
||||
return 1;
|
||||
}
|
||||
idlok(mainwin, true);
|
||||
scrollok(mainwin, true);
|
||||
curses_active = true;
|
||||
move(logcursor, 0);
|
||||
refresh_display();
|
||||
|
||||
/* main loop - simply wait for workio thread to exit */
|
||||
pthread_join(thr_info[work_thr_id].pth, NULL);
|
||||
curl_global_cleanup();
|
||||
@ -1917,6 +2014,10 @@ int main (int argc, char *argv[])
|
||||
|
||||
applog(LOG_INFO, "workio thread dead, exiting.");
|
||||
|
||||
delwin(mainwin);
|
||||
endwin();
|
||||
refresh();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
3
miner.h
3
miner.h
@ -135,6 +135,8 @@ struct cgpu_info {
|
||||
double local_mhashes;
|
||||
double total_mhashes;
|
||||
unsigned int getworks;
|
||||
double efficiency;
|
||||
double utility;
|
||||
};
|
||||
|
||||
struct thr_info {
|
||||
@ -267,6 +269,7 @@ struct work {
|
||||
|
||||
bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce);
|
||||
|
||||
extern void log_curses(const char *f, va_list ap);
|
||||
extern void vapplog(int prio, const char *fmt, va_list ap);
|
||||
extern void applog(int prio, const char *fmt, ...);
|
||||
extern struct thread_q *tq_new(void);
|
||||
|
20
util.c
20
util.c
@ -20,6 +20,7 @@
|
||||
#include <jansson.h>
|
||||
#include <curl/curl.h>
|
||||
#include <time.h>
|
||||
#include <curses.h>
|
||||
#include "miner.h"
|
||||
#include "elist.h"
|
||||
|
||||
@ -68,7 +69,7 @@ void vapplog(int prio, const char *fmt, va_list ap)
|
||||
#endif
|
||||
else if (opt_log_output || prio == LOG_WARNING || prio == LOG_ERR) {
|
||||
char *f;
|
||||
int len, i, extra = 0;
|
||||
int len;
|
||||
struct timeval tv = { };
|
||||
struct tm tm, *tm_p;
|
||||
|
||||
@ -80,10 +81,8 @@ void vapplog(int prio, const char *fmt, va_list ap)
|
||||
pthread_mutex_unlock(&time_lock);
|
||||
|
||||
len = 40 + strlen(fmt) + 2;
|
||||
if (len < 80)
|
||||
extra = 80 - len;
|
||||
f = alloca(len + extra);
|
||||
sprintf(f, "[%d-%02d-%02d %02d:%02d:%02d] %s",
|
||||
f = alloca(len);
|
||||
sprintf(f, "[%d-%02d-%02d %02d:%02d:%02d] %s\n",
|
||||
tm.tm_year + 1900,
|
||||
tm.tm_mon + 1,
|
||||
tm.tm_mday,
|
||||
@ -91,11 +90,12 @@ void vapplog(int prio, const char *fmt, va_list ap)
|
||||
tm.tm_min,
|
||||
tm.tm_sec,
|
||||
fmt);
|
||||
vfprintf(stderr, f, ap); /* atomic write to stderr */
|
||||
for (i = 0; i < extra; i++)
|
||||
fprintf(stderr, " ");
|
||||
fprintf(stderr, "\n");
|
||||
fflush(stderr);
|
||||
/* Only output to stderr if it's not going to the screen as well */
|
||||
if (opt_log_output && !isatty(fileno((FILE *)stderr))) {
|
||||
vfprintf(stderr, f, ap); /* atomic write to stderr */
|
||||
fflush(stderr);
|
||||
}
|
||||
log_curses(f, ap);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user