Browse Source

Add time-limit option and exit codes

based on cudaminer implementation...
2upstream
Tanguy Pruvot 9 years ago
parent
commit
c6a94c9998
  1. 15
      README.txt
  2. 120
      ccminer.cpp
  3. 9
      miner.h

15
README.txt

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
ccMiner release 1.6.1-tpruvot (Apr 2015) - "Skein512 Chainsaw"
ccMiner release 1.6.2-tpruvot (May 2015) - "Scrypt algos (dev)"
---------------------------------------------------------------
***************************************************************
@ -78,7 +78,8 @@ its command line interface and options. @@ -78,7 +78,8 @@ its command line interface and options.
penta use to mine Joincoin / Pentablake
pluck use to mine Supcoin
quark use to mine Quarkcoin
qubit use to mine Qubit Algo
qubit use to mine Qubit
scrypt use to mine Scrypt
s3 use to mine 1coin
skein use to mine Skeincoin
skein2 use to mine Woodcoin
@ -108,6 +109,7 @@ its command line interface and options. @@ -108,6 +109,7 @@ its command line interface and options.
-r, --retries=N number of times to retry if a network call fails
(default: retry indefinitely)
-R, --retry-pause=N time to pause between retries, in seconds (default: 15)
--time-limit maximum time [s] to mine before exiting the program.
-T, --timeout=N network timeout, in seconds (default: 270)
-s, --scantime=N upper bound on time spent scanning current work when
long polling is unavailable, in seconds (default: 5)
@ -132,6 +134,15 @@ its command line interface and options. @@ -132,6 +134,15 @@ its command line interface and options.
-h, --help display this help text and exit
Scrypt specific options:
-l, --launch-config gives the launch configuration for each kernel
in a comma separated list, one per device.
-L, --lookup-gap Divides the per-hash memory requirement by this factor
by storing only every N'th value in the scratchpad.
Default is 1.
--no-autotune disable auto-tuning of kernel launch parameters
>>> Examples <<<

120
ccminer.cpp

@ -70,6 +70,7 @@ nvml_handle *hnvml = NULL; @@ -70,6 +70,7 @@ nvml_handle *hnvml = NULL;
enum workio_commands {
WC_GET_WORK,
WC_SUBMIT_WORK,
WC_ABORT,
};
struct workio_cmd {
@ -171,6 +172,7 @@ static bool opt_background = false; @@ -171,6 +172,7 @@ static bool opt_background = false;
bool opt_quiet = false;
static int opt_retries = -1;
static int opt_fail_pause = 30;
static int opt_time_limit = 0;
int opt_timeout = 270;
static int opt_scantime = 10;
static json_t *opt_config;
@ -220,6 +222,7 @@ int stratum_thr_id = -1; @@ -220,6 +222,7 @@ int stratum_thr_id = -1;
int api_thr_id = -1;
bool stratum_need_reset = false;
struct work_restart *work_restart = NULL;
static int app_exit_code = EXIT_CODE_OK;
struct stratum_ctx stratum = { 0 };
uint32_t zr5_pok = 0;
@ -306,6 +309,7 @@ Options:\n\ @@ -306,6 +309,7 @@ Options:\n\
-r, --retries=N number of times to retry if a network call fails\n\
(default: retry indefinitely)\n\
-R, --retry-pause=N time to pause between retries, in seconds (default: 30)\n\
--time-limit maximum time [s] to mine before exiting the program.\n\
-T, --timeout=N network timeout, in seconds (default: 270)\n\
-s, --scantime=N upper bound on time spent scanning current work when\n\
long polling is unavailable, in seconds (default: 10)\n\
@ -383,8 +387,9 @@ static struct option const options[] = { @@ -383,8 +387,9 @@ static struct option const options[] = {
{ "statsavg", 1, NULL, 'N' },
#ifdef HAVE_SYSLOG_H
{ "syslog", 0, NULL, 'S' },
{ "syslog-prefix", 1, NULL, 1008 },
{ "syslog-prefix", 1, NULL, 1018 },
#endif
{ "time-limit", 1, NULL, 1008 },
{ "threads", 1, NULL, 't' },
{ "vote", 1, NULL, 'v' },
{ "trust-pool", 0, NULL, 'm' },
@ -475,8 +480,13 @@ void get_currentalgo(char* buf, int sz) @@ -475,8 +480,13 @@ void get_currentalgo(char* buf, int sz)
void proper_exit(int reason)
{
abort_flag = true;
usleep(200 * 1000);
cuda_devicereset();
if (reason == EXIT_CODE_OK && app_exit_code != EXIT_CODE_OK) {
reason = app_exit_code;
}
if (check_dups)
hashlog_purge_all();
stats_purge_all();
@ -947,6 +957,23 @@ static void workio_cmd_free(struct workio_cmd *wc) @@ -947,6 +957,23 @@ static void workio_cmd_free(struct workio_cmd *wc)
free(wc);
}
static void workio_abort()
{
struct workio_cmd *wc;
/* fill out work request message */
wc = (struct workio_cmd *)calloc(1, sizeof(*wc));
if (!wc)
return;
wc->cmd = WC_ABORT;
/* send work request to workio thread */
if (!tq_push(thr_info[work_thr_id].q, wc)) {
workio_cmd_free(wc);
}
}
static bool workio_get_work(struct workio_cmd *wc, CURL *curl)
{
struct work *ret_work;
@ -1028,7 +1055,7 @@ static void *workio_thread(void *userdata) @@ -1028,7 +1055,7 @@ static void *workio_thread(void *userdata)
case WC_SUBMIT_WORK:
ok = workio_submit_work(wc, curl);
break;
case WC_ABORT:
default: /* should never happen */
ok = false;
break;
@ -1245,6 +1272,7 @@ static void *miner_thread(void *userdata) @@ -1245,6 +1272,7 @@ static void *miner_thread(void *userdata)
uint64_t loopcnt = 0;
uint32_t max_nonce;
uint32_t end_nonce = UINT32_MAX / opt_n_threads * (thr_id + 1) - (thr_id + 1);
time_t firstwork_time = 0;
bool work_done = false;
bool extrajob = false;
char s[16];
@ -1399,6 +1427,20 @@ static void *miner_thread(void *userdata) @@ -1399,6 +1427,20 @@ static void *miner_thread(void *userdata)
else
max64 = max(1, scan_time + g_work_time - time(NULL));
/* time limit */
if (opt_time_limit && firstwork_time) {
int passed = (int)(time(NULL) - firstwork_time);
int remain = (int)(opt_time_limit - passed);
if (remain < 0) {
app_exit_code = EXIT_CODE_TIME_LIMIT;
abort_flag = true;
applog(LOG_NOTICE, "Mining timeout of %ds reached, exiting...", opt_time_limit);
workio_abort();
break;
}
if (remain < max64) max64 = remain;
}
max64 *= (uint32_t)thr_hashrates[thr_id];
/* on start, max64 should not be 0,
@ -1640,6 +1682,9 @@ static void *miner_thread(void *userdata) @@ -1640,6 +1682,9 @@ static void *miner_thread(void *userdata)
/* record scanhash elapsed time */
gettimeofday(&tv_end, NULL);
if (firstwork_time == 0)
firstwork_time = time(NULL);
if (rc && opt_debug)
applog(LOG_NOTICE, CL_CYN "found => %08x" CL_GRN " %08x", nonceptr[0], swab32(nonceptr[0])); // data[19]
if (rc > 1 && opt_debug)
@ -1972,7 +2017,7 @@ static void show_version_and_exit(void) @@ -1972,7 +2017,7 @@ static void show_version_and_exit(void)
PTW32_VERSION_STRING,
#endif
curl_version());
proper_exit(0);
proper_exit(EXIT_CODE_OK);
}
static void show_usage_and_exit(int status)
@ -2057,7 +2102,7 @@ void parse_arg(int key, char *arg) @@ -2057,7 +2102,7 @@ void parse_arg(int key, char *arg)
#endif
if (!json_is_object(opt_config)) {
applog(LOG_ERR, "JSON decode of %s failed", arg);
proper_exit(1);
proper_exit(EXIT_CODE_USAGE);
}
break;
}
@ -2114,7 +2159,7 @@ void parse_arg(int key, char *arg) @@ -2114,7 +2159,7 @@ void parse_arg(int key, char *arg)
break;
case 'n': /* --ndevs */
cuda_print_devices();
proper_exit(0);
proper_exit(EXIT_CODE_OK);
break;
case 'q':
opt_quiet = true;
@ -2281,7 +2326,7 @@ void parse_arg(int key, char *arg) @@ -2281,7 +2326,7 @@ void parse_arg(int key, char *arg)
break;
case 1006:
print_hash_tests();
proper_exit(0);
proper_exit(EXIT_CODE_OK);
break;
case 1003:
want_longpoll = false;
@ -2289,11 +2334,14 @@ void parse_arg(int key, char *arg) @@ -2289,11 +2334,14 @@ void parse_arg(int key, char *arg)
case 1007:
want_stratum = false;
break;
case 1008:
opt_time_limit = atoi(arg);
break;
case 1011:
allow_gbt = false;
break;
case 'S':
case 1008:
case 1018:
applog(LOG_INFO, "Now logging to syslog...");
use_syslog = true;
if (arg && strlen(arg)) {
@ -2327,7 +2375,7 @@ void parse_arg(int key, char *arg) @@ -2327,7 +2375,7 @@ void parse_arg(int key, char *arg)
device_map[opt_n_threads++] = atoi(pch);
else {
applog(LOG_ERR, "Non-existant CUDA device #%d specified in -d option", atoi(pch));
proper_exit(1);
proper_exit(EXIT_CODE_CUDA_NODEVICE);
}
} else {
int device = cuda_finddevice(pch);
@ -2335,7 +2383,7 @@ void parse_arg(int key, char *arg) @@ -2335,7 +2383,7 @@ void parse_arg(int key, char *arg)
device_map[opt_n_threads++] = device;
else {
applog(LOG_ERR, "Non-existant CUDA device '%s' specified in -d option", pch);
proper_exit(1);
proper_exit(EXIT_CODE_CUDA_NODEVICE);
}
}
// set number of active gpus
@ -2451,11 +2499,11 @@ static void signal_handler(int sig) @@ -2451,11 +2499,11 @@ static void signal_handler(int sig)
case SIGINT:
signal(sig, SIG_IGN);
applog(LOG_INFO, "SIGINT received, exiting");
proper_exit(0);
proper_exit(EXIT_CODE_KILLED);
break;
case SIGTERM:
applog(LOG_INFO, "SIGTERM received, exiting");
proper_exit(0);
proper_exit(EXIT_CODE_KILLED);
break;
}
}
@ -2465,11 +2513,23 @@ BOOL WINAPI ConsoleHandler(DWORD dwType) @@ -2465,11 +2513,23 @@ BOOL WINAPI ConsoleHandler(DWORD dwType)
switch (dwType) {
case CTRL_C_EVENT:
applog(LOG_INFO, "CTRL_C_EVENT received, exiting");
proper_exit(0);
proper_exit(EXIT_CODE_KILLED);
break;
case CTRL_BREAK_EVENT:
applog(LOG_INFO, "CTRL_BREAK_EVENT received, exiting");
proper_exit(0);
proper_exit(EXIT_CODE_KILLED);
break;
case CTRL_CLOSE_EVENT:
applog(LOG_INFO, "CTRL_CLOSE_EVENT received, exiting");
proper_exit(EXIT_CODE_KILLED);
break;
case CTRL_LOGOFF_EVENT:
applog(LOG_INFO, "CTRL_LOGOFF_EVENT received, exiting");
proper_exit(EXIT_CODE_KILLED);
break;
case CTRL_SHUTDOWN_EVENT:
applog(LOG_INFO, "CTRL_SHUTDOWN_EVENT received, exiting");
proper_exit(EXIT_CODE_KILLED);
break;
default:
return false;
@ -2582,14 +2642,14 @@ int main(int argc, char *argv[]) @@ -2582,14 +2642,14 @@ int main(int argc, char *argv[])
: CURL_GLOBAL_ALL;
if (curl_global_init(flags)) {
applog(LOG_ERR, "CURL initialization failed");
return 1;
return EXIT_CODE_SW_INIT_ERROR;
}
#ifndef WIN32
if (opt_background) {
i = fork();
if (i < 0) exit(1);
if (i > 0) exit(0);
if (i < 0) proper_exit(EXIT_CODE_SW_INIT_ERROR);
if (i > 0) proper_exit(EXIT_CODE_OK);
i = setsid();
if (i < 0)
applog(LOG_ERR, "setsid() failed (errno = %d)", errno);
@ -2643,15 +2703,15 @@ int main(int argc, char *argv[]) @@ -2643,15 +2703,15 @@ int main(int argc, char *argv[])
work_restart = (struct work_restart *)calloc(opt_n_threads, sizeof(*work_restart));
if (!work_restart)
return 1;
return EXIT_CODE_SW_INIT_ERROR;
thr_info = (struct thr_info *)calloc(opt_n_threads + 4, sizeof(*thr));
if (!thr_info)
return 1;
return EXIT_CODE_SW_INIT_ERROR;
thr_hashrates = (double *) calloc(opt_n_threads, sizeof(double));
if (!thr_hashrates)
return 1;
return EXIT_CODE_SW_INIT_ERROR;
/* init workio thread info */
work_thr_id = opt_n_threads;
@ -2659,12 +2719,12 @@ int main(int argc, char *argv[]) @@ -2659,12 +2719,12 @@ int main(int argc, char *argv[])
thr->id = work_thr_id;
thr->q = tq_new();
if (!thr->q)
return 1;
return EXIT_CODE_SW_INIT_ERROR;
/* start work I/O thread */
if (pthread_create(&thr->pth, NULL, workio_thread, thr)) {
applog(LOG_ERR, "workio thread create failed");
return 1;
return EXIT_CODE_SW_INIT_ERROR;
}
if (want_longpoll && !have_stratum) {
@ -2674,12 +2734,12 @@ int main(int argc, char *argv[]) @@ -2674,12 +2734,12 @@ int main(int argc, char *argv[])
thr->id = longpoll_thr_id;
thr->q = tq_new();
if (!thr->q)
return 1;
return EXIT_CODE_SW_INIT_ERROR;
/* start longpoll thread */
if (unlikely(pthread_create(&thr->pth, NULL, longpoll_thread, thr))) {
applog(LOG_ERR, "longpoll thread create failed");
return 1;
return EXIT_CODE_SW_INIT_ERROR;
}
}
@ -2690,12 +2750,12 @@ int main(int argc, char *argv[]) @@ -2690,12 +2750,12 @@ int main(int argc, char *argv[])
thr->id = stratum_thr_id;
thr->q = tq_new();
if (!thr->q)
return 1;
return EXIT_CODE_SW_INIT_ERROR;
/* start stratum thread */
if (unlikely(pthread_create(&thr->pth, NULL, stratum_thread, thr))) {
applog(LOG_ERR, "stratum thread create failed");
return 1;
return EXIT_CODE_SW_INIT_ERROR;
}
if (have_stratum)
@ -2723,12 +2783,12 @@ int main(int argc, char *argv[]) @@ -2723,12 +2783,12 @@ int main(int argc, char *argv[])
thr->id = api_thr_id;
thr->q = tq_new();
if (!thr->q)
return 1;
return EXIT_CODE_SW_INIT_ERROR;
/* start stratum thread */
if (unlikely(pthread_create(&thr->pth, NULL, api_thread, thr))) {
applog(LOG_ERR, "api thread create failed");
return 1;
return EXIT_CODE_SW_INIT_ERROR;
}
}
@ -2742,11 +2802,11 @@ int main(int argc, char *argv[]) @@ -2742,11 +2802,11 @@ int main(int argc, char *argv[])
thr->gpu.gpu_arch = (uint16_t) device_sm[device_map[i]];
thr->q = tq_new();
if (!thr->q)
return 1;
return EXIT_CODE_SW_INIT_ERROR;
if (unlikely(pthread_create(&thr->pth, NULL, miner_thread, thr))) {
applog(LOG_ERR, "thread %d create failed", i);
return 1;
return EXIT_CODE_SW_INIT_ERROR;
}
}
@ -2764,7 +2824,7 @@ int main(int argc, char *argv[]) @@ -2764,7 +2824,7 @@ int main(int argc, char *argv[])
applog(LOG_INFO, "workio thread dead, exiting.");
proper_exit(0);
proper_exit(EXIT_CODE_OK);
return 0;
}

9
miner.h

@ -657,6 +657,15 @@ extern void *tq_pop(struct thread_q *tq, const struct timespec *abstime); @@ -657,6 +657,15 @@ extern void *tq_pop(struct thread_q *tq, const struct timespec *abstime);
extern void tq_freeze(struct thread_q *tq);
extern void tq_thaw(struct thread_q *tq);
#define EXIT_CODE_OK 0
#define EXIT_CODE_USAGE 1
#define EXIT_CODE_POOL_TIMEOUT 2
#define EXIT_CODE_SW_INIT_ERROR 3
#define EXIT_CODE_CUDA_NODEVICE 4
#define EXIT_CODE_CUDA_ERROR 5
#define EXIT_CODE_TIME_LIMIT 0
#define EXIT_CODE_KILLED 7
void parse_arg(int key, char *arg);
void proper_exit(int reason);
void restart_threads(void);

Loading…
Cancel
Save