From 24afd61775b957009619e0d3a5948492bdf5539e Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Fri, 18 Mar 2011 17:24:16 -0400 Subject: [PATCH] Introduce more standardized logging (incl. optional syslog). Also, improve portability of alloca. --- configure.ac | 3 +++ cpu-miner.c | 46 +++++++++++++++++++++++++++++++--------------- miner.h | 38 ++++++++++++++++++++++++++++++++++++++ util.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 15 deletions(-) diff --git a/configure.ac b/configure.ac index 8991cc4..e3d9df1 100644 --- a/configure.ac +++ b/configure.ac @@ -16,6 +16,9 @@ AC_PROG_RANLIB dnl Checks for header files. AC_HEADER_STDC +AC_CHECK_HEADERS(syslog.h) + +AC_FUNC_ALLOCA case $host in *-*-mingw*) diff --git a/cpu-miner.c b/cpu-miner.c index b521ea7..2b0ebe2 100644 --- a/cpu-miner.c +++ b/cpu-miner.c @@ -74,6 +74,7 @@ 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; @@ -88,6 +89,7 @@ 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 { @@ -145,6 +147,11 @@ static struct option_help options_help[] = { "(-s N) Upper bound on time spent scanning current work,\n" "\tin seconds. (default: 5)" }, +#ifdef HAVE_SYSLOG_H + { "syslog", + "Use system log for output messages (default: standard error)" }, +#endif + { "threads N", "(-t N) Number of miner threads (default: 1)" }, @@ -171,6 +178,11 @@ static struct option options[] = { { "url", 1, NULL, 1001 }, { "userpass", 1, NULL, 1002 }, { "no-longpoll", 0, NULL, 1003 }, + +#ifdef HAVE_SYSLOG_H + { "syslog", 0, NULL, 1004 }, +#endif + { } }; @@ -240,13 +252,9 @@ static bool submit_upstream_work(CURL *curl, const struct work *work) { char *hexstr = NULL; json_t *val, *res; - char s[345], timestr[64]; - time_t now; - struct tm *tm; + char s[345]; bool rc = false; - now = time(NULL); - /* build hex string */ hexstr = bin2hex(work->data, sizeof(work->data)); if (!hexstr) { @@ -271,11 +279,8 @@ static bool submit_upstream_work(CURL *curl, const struct work *work) res = json_object_get(val, "result"); - tm = localtime(&now); - strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", tm); - - printf("[%s] PROOF OF WORK RESULT: %s\n", - timestr, json_is_true(res) ? "true (yay!!!)" : "false (booooo)"); + applog(LOG_INFO, "PROOF OF WORK RESULT: %s", + json_is_true(res) ? "true (yay!!!)" : "false (booooo)"); json_decref(val); @@ -429,7 +434,7 @@ static void hashmeter(int thr_id, const struct timeval *diff, secs = (double)diff->tv_sec + ((double)diff->tv_usec / 1000000.0); if (!opt_quiet) - printf("HashMeter(%d): %lu hashes, %.2f khash/sec\n", + applog(LOG_INFO, "thread %d: %lu hashes, %.2f khash/sec\n", thr_id, hashes_done, khashes / secs); } @@ -625,7 +630,7 @@ static void *longpoll_thread(void *userdata) sprintf(lp_url, "%s%s%s", rpc_url, need_slash ? "/" : "", copy_start); - fprintf(stderr, "Long-polling activated for %s\n", lp_url); + applog(LOG_INFO, "Long-polling activated for %s", lp_url); curl = curl_easy_init(); if (!curl) { @@ -641,7 +646,8 @@ static void *longpoll_thread(void *userdata) if (val) { failures = 0; json_decref(val); - fprintf(stderr, "LONGPOLL detected new block\n"); + + applog(LOG_INFO, "LONGPOLL detected new block"); restart_threads(); } else { if (failures++ < 10) { @@ -764,6 +770,9 @@ static void parse_arg (int key, char *arg) case 1003: want_longpoll = false; break; + case 1004: + use_syslog = true; + break; default: show_usage(); } @@ -827,6 +836,13 @@ int main (int argc, char *argv[]) /* parse command line */ parse_cmdline(argc, argv); + pthread_mutex_init(&time_lock, NULL); + +#ifdef HAVE_SYSLOG_H + if (use_syslog) + openlog("cpuminer", LOG_PID, LOG_USER); +#endif + /* set our priority to the highest (aka "nicest, least intrusive") */ if (setpriority(PRIO_PROCESS, 0, 19)) perror("setpriority"); @@ -887,7 +903,7 @@ int main (int argc, char *argv[]) sleep(1); /* don't pound RPC server all at once */ } - fprintf(stderr, "%d miner threads started, " + applog(LOG_INFO, "%d miner threads started, " "using SHA256 '%s' algorithm.\n", opt_n_threads, algo_names[opt_algo]); @@ -895,7 +911,7 @@ int main (int argc, char *argv[]) /* main loop - simply wait for workio thread to exit */ pthread_join(thr_info[work_thr_id].pth, NULL); - fprintf(stderr, "workio thread dead, exiting.\n"); + applog(LOG_INFO, "workio thread dead, exiting."); return 0; } diff --git a/miner.h b/miner.h index dd32ee7..4021a69 100644 --- a/miner.h +++ b/miner.h @@ -8,6 +8,33 @@ #include #include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif defined __GNUC__ +# define alloca __builtin_alloca +#elif defined _AIX +# define alloca __alloca +#elif defined _MSC_VER +# include +# define alloca _alloca +#else +# ifndef HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + + #ifdef __SSE2__ #define WANT_SSE2_4WAY 1 #endif @@ -26,6 +53,14 @@ #include #endif +#ifdef HAVE_SYSLOG_H +#include +#else +enum { + LOG_INFO, +}; +#endif + #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) #undef unlikely #define unlikely(expr) (__builtin_expect((expr), 0)) @@ -126,10 +161,13 @@ struct work_restart { char padding[128 - sizeof(unsigned long)]; }; +extern pthread_mutex_t time_lock; +extern bool use_syslog; extern struct thr_info *thr_info; extern int longpoll_thr_id; extern struct work_restart *work_restart; +extern void applog(int prio, const char *fmt, ...); extern struct thread_q *tq_new(void); extern void tq_free(struct thread_q *tq); extern bool tq_push(struct thread_q *tq, void *data); diff --git a/util.c b/util.c index 5b02e83..62cf422 100644 --- a/util.c +++ b/util.c @@ -14,9 +14,11 @@ #include #include #include +#include #include #include #include +#include #include "miner.h" #include "elist.h" @@ -48,6 +50,47 @@ struct thread_q { pthread_cond_t cond; }; +void applog(int prio, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + +#ifdef HAVE_SYSLOG_H + if (use_syslog) { + vsyslog(prio, fmt, ap); + } +#else + if (0) {} +#endif + else { + char *f; + int len; + struct timeval tv = { }; + struct tm tm, *tm_p; + + gettimeofday(&tv, NULL); + + pthread_mutex_lock(&time_lock); + tm_p = localtime(&tv.tv_sec); + memcpy(&tm, tm_p, sizeof(tm)); + pthread_mutex_unlock(&time_lock); + + len = 40 + strlen(fmt) + 2; + f = alloca(len); + sprintf(f, "[%d-%02d-%02d %02d:%02d:%02d] %s\n", + tm.tm_year + 1900, + tm.tm_mon, + tm.tm_mday, + tm.tm_hour, + tm.tm_min, + tm.tm_sec, + fmt); + vfprintf(stderr, f, ap); /* atomic write to stderr */ + } + va_end(ap); +} + static void databuf_free(struct data_buffer *db) { if (!db)