/*
* Copyright 2010 Jeff Garzik
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version. See COPYING for more details.
*/
#include "cpuminer-config.h"
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/time.h>
#include <time.h>
#ifndef WIN32
#include <sys/resource.h>
#endif
#include <getopt.h>
#include <jansson.h>
#include <curl/curl.h>
#include "compat.h"
#include "miner.h"
#define PROGRAM_NAME "minerd"
#define DEF_RPC_URL "http://127.0.0.1:8332/"
#define DEF_RPC_USERNAME "rpcuser"
#define DEF_RPC_PASSWORD "rpcpass"
#define DEF_RPC_USERPASS DEF_RPC_USERNAME ":" DEF_RPC_PASSWORD
#ifdef __linux /* Linux specific policy and affinity management */
#include <sched.h>
static inline void drop_policy(void)
{
struct sched_param param;
if (unlikely(sched_setscheduler(0, SCHED_IDLE, ¶m) == -1))
sched_setscheduler(0, SCHED_BATCH, ¶m);
}
static inline void affine_to_cpu(int id, int cpu)
{
cpu_set_t set;
CPU_ZERO(&set);
CPU_SET(cpu, &set);
sched_setaffinity(0, sizeof(&set), &set);
applog(LOG_INFO, "Binding thread %d to cpu %d", id, cpu);
}
#else
static inline void drop_policy(void)
{
}
static inline void affine_to_cpu(int id, int cpu)
{
}
#endif
enum workio_commands {
WC_GET_WORK,
WC_SUBMIT_WORK,
};
struct workio_cmd {
enum workio_commands cmd;
struct thr_info *thr;
union {
struct work *work;
} u;
};
enum sha256_algos {
ALGO_C, /* plain C */
ALGO_4WAY, /* parallel SSE2 */
ALGO_VIA, /* VIA padlock */
ALGO_CRYPTOPP, /* Crypto++ (C) */
ALGO_CRYPTOPP_ASM32, /* Crypto++ 32-bit assembly */
ALGO_SSE2_64, /* SSE2 for x86_64 */
};
static const char *algo_names[] = {
[ALGO_C] = "c",
#ifdef WANT_SSE2_4WAY
[ALGO_4WAY] = "4way",
#endif
#ifdef WANT_VIA_PADLOCK
[ALGO_VIA] = "via",
#endif
[ALGO_CRYPTOPP] = "cryptopp",
#ifdef WANT_CRYPTOPP_ASM32
[ALGO_CRYPTOPP_ASM32] = "cryptopp_asm32",
#endif
#ifdef WANT_X8664_SSE2
[ALGO_SSE2_64] = "sse2_64",
#endif
};
bool opt_debug = false;
bool opt_protocol = false;
bool want_longpoll = true;
bool have_longpoll = false;
bool use_syslog = false;
static bool opt_quiet = false;
static int opt_retries = 10;
static int opt_fail_pause = 30;
int opt_scantime = 5;
static json_t *opt_config;
static const bool opt_time = true;
#ifdef WANT_X8664_SSE2
static enum sha256_algos opt_algo = ALGO_SSE2_64;
#else
static enum sha256_algos opt_algo = ALGO_C;
#endif
static int opt_n_threads;
static int num_processors;
static char *rpc_url;
static char *rpc_userpass;
static char *rpc_user, *rpc_pass;
struct thr_info *thr_info;
static int work_thr_id;
int longpoll_thr_id;
struct work_restart *work_restart = NULL;
pthread_mutex_t time_lock;
struct option_help {
const char *name;
const char *helptext;
};
static struct option_help options_help[] = {
{ "help",
"(-h) Display this help text" },
{ "config FILE",
"(-c FILE) JSON-format configuration file (default: none)\n"
"See example-cfg.json for an example configuration." },
{ "algo XXX",
"(-a XXX) Specify sha256 implementation:\n"
"\tc\t\tLinux kernel sha256, implemented in C (default)"
#ifdef WANT_SSE2_4WAY
"\n\t4way\t\ttcatm's 4-way SSE2 implementation"
#endif
#ifdef WANT_VIA_PADLOCK
"\n\tvia\t\tVIA padlock implementation"
#endif
"\n\tcryptopp\tCrypto++ C/C++ implementation"
#ifdef WANT_CRYPTOPP_ASM32
"\n\tcryptopp_asm32\tCrypto++ 32-bit assembler implementation"
#endif
#ifdef WANT_X8664_SSE2
"\n\tsse2_64\t\tSSE2 implementation for x86_64 machines"
#endif
},
{ "quiet",
"(-q) Disable per-thread hashmeter output (default: off)" },
{ "debug",
"(-D) Enable debug output (default: off)" },
{ "no-longpoll",
"Disable X-Long-Polling support (default: enabled)" },
{ "protocol-dump",
"(-P) Verbose dump of protocol-level activities (default: off)" },
{ "retries N",
"(-r N) Number of times to retry, if JSON-RPC call fails\n"
"\t(default: 10; use -1 for \"never\")" },
{ "retry-pause N",
"(-R N) Number of seconds to pause, between retries\n"
"\t(default: 30)" },
{ "scantime N",
"(-s N) Upper bound on time spent scanning current work,\n"
"\tin seconds. (default: 5)" },
#ifdef HAVE_SYSLOG_H
{ "syslog&