From d9b3037e4b7b2fc6ab532cce627a5cbcf43d96dc Mon Sep 17 00:00:00 2001 From: ckolivas Date: Wed, 6 Nov 2013 10:22:38 +1100 Subject: [PATCH 1/8] Fix build for no libcurl --- cgminer.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/cgminer.c b/cgminer.c index 38b646a2..c18294f7 100644 --- a/cgminer.c +++ b/cgminer.c @@ -2416,25 +2416,6 @@ share_result(json_t *val, json_t *res, json_t *err, const struct work *work, } } -#ifdef HAVE_LIBCURL -static void text_print_status(int thr_id) -{ - struct cgpu_info *cgpu; - char logline[256]; - - cgpu = get_thr_cgpu(thr_id); - if (cgpu) { - get_statline(logline, sizeof(logline), cgpu); - printf("%s\n", logline); - } -} - -static void print_status(int thr_id) -{ - if (!curses_active) - text_print_status(thr_id); -} - static void show_hash(struct work *work, char *hashshow) { unsigned char rhash[32]; @@ -2456,6 +2437,25 @@ static void show_hash(struct work *work, char *hashshow) work->block? " BLOCK!" : ""); } +#ifdef HAVE_LIBCURL +static void text_print_status(int thr_id) +{ + struct cgpu_info *cgpu; + char logline[256]; + + cgpu = get_thr_cgpu(thr_id); + if (cgpu) { + get_statline(logline, sizeof(logline), cgpu); + printf("%s\n", logline); + } +} + +static void print_status(int thr_id) +{ + if (!curses_active) + text_print_status(thr_id); +} + static bool submit_upstream_work(struct work *work, CURL *curl, bool resubmit) { char *hexstr = NULL; From c9bf06d19bdfa620f4b3074d18acfb9c3ade5b2d Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Thu, 7 Nov 2013 22:27:21 +1100 Subject: [PATCH 2/8] Break out of the hash work loops when a failure is detected instead of dropping into mt disable. --- cgminer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cgminer.c b/cgminer.c index c18294f7..1ac8d7fa 100644 --- a/cgminer.c +++ b/cgminer.c @@ -6311,7 +6311,7 @@ void hash_queued_work(struct thr_info *mythr) applog(LOG_ERR, "%s %d failure, disabling!", drv->name, cgpu->device_id); cgpu->deven = DEV_DISABLED; dev_error(cgpu, REASON_THREAD_ZERO_HASH); - mt_disable(mythr, thr_id, drv); + break; } hashes_done += hashes; @@ -6358,7 +6358,7 @@ void hash_driver_work(struct thr_info *mythr) applog(LOG_ERR, "%s %d failure, disabling!", drv->name, cgpu->device_id); cgpu->deven = DEV_DISABLED; dev_error(cgpu, REASON_THREAD_ZERO_HASH); - mt_disable(mythr, thr_id, drv); + break; } hashes_done += hashes; From d38802a68f0d80532c1eea9da3226f0af0686019 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 8 Nov 2013 13:32:55 +1100 Subject: [PATCH 3/8] Get rid of the stage thread since all work can be asynchronously added now via hash_push anyway. Conflicts: cgminer.c --- cgminer.c | 69 ++++++++----------------------------------------------- 1 file changed, 9 insertions(+), 60 deletions(-) diff --git a/cgminer.c b/cgminer.c index 1ac8d7fa..b6980a40 100644 --- a/cgminer.c +++ b/cgminer.c @@ -149,7 +149,6 @@ char *cgminer_path; struct thr_info *control_thr; struct thr_info **mining_thr; static int gwsched_thr_id; -static int stage_thr_id; static int watchpool_thr_id; static int watchdog_thr_id; #ifdef HAVE_CURSES @@ -3006,11 +3005,7 @@ static void __kill_work(void) cg_completion_timeout(&kill_mining, NULL, 3000); - forcelog(LOG_DEBUG, "Killing off stage thread"); /* Stop the others */ - thr = &control_thr[stage_thr_id]; - kill_timeout(thr); - forcelog(LOG_DEBUG, "Killing off API thread"); thr = &control_thr[api_thr_id]; kill_timeout(thr); @@ -3912,42 +3907,6 @@ static bool hash_push(struct work *work) return rc; } -static void *stage_thread(void *userdata) -{ - struct thr_info *mythr = userdata; - bool ok = true; - - pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); - - RenameThread("stage"); - - while (ok) { - struct work *work = NULL; - - applog(LOG_DEBUG, "Popping work to stage thread"); - - work = tq_pop(mythr->q, NULL); - if (unlikely(!work)) { - applog(LOG_ERR, "Failed to tq_pop in stage_thread"); - ok = false; - break; - } - work->work_block = work_block; - - test_work_current(work); - - applog(LOG_DEBUG, "Pushing work to getwork queue"); - - if (unlikely(!hash_push(work))) { - applog(LOG_WARNING, "Failed to hash_push in stage_thread"); - continue; - } - } - - tq_freeze(mythr->q); - return NULL; -} - static void stage_work(struct work *work) { applog(LOG_DEBUG, "Pushing work from pool %d to hash queue", work->pool->pool_no); @@ -5488,7 +5447,7 @@ retry_stratum: calc_diff(work, 0); applog(LOG_DEBUG, "Pushing pooltest work to base pool"); - tq_push(control_thr[stage_thr_id].q, work); + stage_work(work); total_getworks++; pool->getwork_requested++; ret = true; @@ -7630,7 +7589,7 @@ int main(int argc, char *argv[]) if (opt_scantime < 0) opt_scantime = 30; - total_control_threads = 9; + total_control_threads = 8; control_thr = calloc(total_control_threads, sizeof(*thr)); if (!control_thr) quit(1, "Failed to calloc control_thr"); @@ -7745,16 +7704,6 @@ int main(int argc, char *argv[]) quit(1, "Failed to calloc mining_thr[%d]", i); } - stage_thr_id = 2; - thr = &control_thr[stage_thr_id]; - thr->q = tq_new(); - if (!thr->q) - quit(1, "Failed to tq_new"); - /* start stage thread */ - if (thr_info_create(thr, NULL, stage_thread, thr)) - quit(1, "stage thread create failed"); - pthread_detach(thr->pth); - /* Create a unique get work queue */ getq = tq_new(); if (!getq) @@ -7857,14 +7806,14 @@ begin_bench: cgtime(&total_tv_start); cgtime(&total_tv_end); - watchpool_thr_id = 3; + watchpool_thr_id = 2; thr = &control_thr[watchpool_thr_id]; /* start watchpool thread */ if (thr_info_create(thr, NULL, watchpool_thread, NULL)) quit(1, "watchpool thread create failed"); pthread_detach(thr->pth); - watchdog_thr_id = 4; + watchdog_thr_id = 3; thr = &control_thr[watchdog_thr_id]; /* start watchdog thread */ if (thr_info_create(thr, NULL, watchdog_thread, NULL)) @@ -7872,7 +7821,7 @@ begin_bench: pthread_detach(thr->pth); /* Create reinit gpu thread */ - gpur_thr_id = 5; + gpur_thr_id = 4; thr = &control_thr[gpur_thr_id]; thr->q = tq_new(); if (!thr->q) @@ -7881,7 +7830,7 @@ begin_bench: quit(1, "reinit_gpu thread create failed"); /* Create API socket thread */ - api_thr_id = 6; + api_thr_id = 5; thr = &control_thr[api_thr_id]; if (thr_info_create(thr, NULL, api_thread, thr)) quit(1, "API thread create failed"); @@ -7890,7 +7839,7 @@ begin_bench: /* Create curses input thread for keyboard input. Create this last so * that we know all threads are created since this can call kill_work * to try and shut down all previous threads. */ - input_thr_id = 8; + input_thr_id = 7; thr = &control_thr[input_thr_id]; if (thr_info_create(thr, NULL, input_thread, thr)) quit(1, "input thread create failed"); @@ -7898,8 +7847,8 @@ begin_bench: #endif /* Just to be sure */ - if (total_control_threads != 9) - quit(1, "incorrect total_control_threads (%d) should be 9", total_control_threads); + if (total_control_threads != 8) + quit(1, "incorrect total_control_threads (%d) should be 8", total_control_threads); /* Once everything is set up, main() becomes the getwork scheduler */ while (42) { From 75c5ac0457b65b85419dcfa2916bdeb99f4e6d0f Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 8 Nov 2013 14:23:18 +1100 Subject: [PATCH 4/8] Only check for the stratum clean message if we have had a valid message. --- cgminer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cgminer.c b/cgminer.c index b6980a40..bb42458d 100644 --- a/cgminer.c +++ b/cgminer.c @@ -5157,8 +5157,7 @@ static void *stratum_rthread(void *userdata) if (!parse_method(pool, s) && !parse_stratum_response(pool, s)) applog(LOG_INFO, "Unknown stratum msg: %s", s); - free(s); - if (pool->swork.clean) { + else if (pool->swork.clean) { struct work *work = make_work(); /* Generate a single work item to update the current @@ -5171,6 +5170,7 @@ static void *stratum_rthread(void *userdata) test_work_current(work); free_work(work); } + free(s); } out: From cd03fcdf2d62f9bff66ec4edecccae6313b4a4de Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 8 Nov 2013 17:28:10 +1100 Subject: [PATCH 5/8] Reset the work_restart bool after the scanwork loop in case the driver flushes work synchronously. --- cgminer.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/cgminer.c b/cgminer.c index bb42458d..bb5baa46 100644 --- a/cgminer.c +++ b/cgminer.c @@ -6260,12 +6260,16 @@ void hash_queued_work(struct thr_info *mythr) struct timeval diff; int64_t hashes; - mythr->work_restart = mythr->work_update = false; + mythr->work_update = false; fill_queue(mythr, cgpu, drv, thr_id); hashes = drv->scanwork(mythr); + /* Reset the bool here in case the driver looks for it + * synchronously in the scanwork loop. */ + mythr->work_restart = false; + if (unlikely(hashes == -1 )) { applog(LOG_ERR, "%s %d failure, disabling!", drv->name, cgpu->device_id); cgpu->deven = DEV_DISABLED; @@ -6309,10 +6313,14 @@ void hash_driver_work(struct thr_info *mythr) struct timeval diff; int64_t hashes; - mythr->work_restart = mythr->work_update = false; + mythr->work_update = false; hashes = drv->scanwork(mythr); + /* Reset the bool here in case the driver looks for it + * synchronously in the scanwork loop. */ + mythr->work_restart = false; + if (unlikely(hashes == -1 )) { applog(LOG_ERR, "%s %d failure, disabling!", drv->name, cgpu->device_id); cgpu->deven = DEV_DISABLED; From 694a98ece3a624928d2f2592b6613bf350c88759 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Mon, 11 Nov 2013 08:57:32 +1100 Subject: [PATCH 6/8] --shares should be scaled to diff1 not absolute number of shares --- cgminer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cgminer.c b/cgminer.c index bb5baa46..b74a152d 100644 --- a/cgminer.c +++ b/cgminer.c @@ -2324,7 +2324,7 @@ share_result(json_t *val, json_t *res, json_t *err, const struct work *work, hashshow, cgpu->drv->name, cgpu->device_id, resubmit ? "(resubmit)" : "", worktime); } sharelog("accept", work); - if (opt_shares && total_accepted >= opt_shares) { + if (opt_shares && total_diff_accepted >= opt_shares) { applog(LOG_WARNING, "Successfully mined %d accepted shares as requested and exiting.", opt_shares); kill_work(); return; @@ -6970,9 +6970,9 @@ void print_summary(void) } if (opt_shares) { - applog(LOG_WARNING, "Mined %d accepted shares of %d requested\n", total_accepted, opt_shares); - if (opt_shares > total_accepted) - applog(LOG_WARNING, "WARNING - Mined only %d shares of %d requested.", total_accepted, opt_shares); + applog(LOG_WARNING, "Mined %.0f accepted shares of %d requested\n", total_diff_accepted, opt_shares); + if (opt_shares > total_diff_accepted) + applog(LOG_WARNING, "WARNING - Mined only %.0f shares of %d requested.", total_diff_accepted, opt_shares); } applog(LOG_WARNING, " "); From cd7f6ed56a38030b63cd81885aea4561988d5f18 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 13 Nov 2013 20:01:41 +1100 Subject: [PATCH 7/8] Initialise the stgd lock mutex earlier to prevent dereferences when pool testing occurs before it. Conflicts: cgminer.c --- cgminer.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cgminer.c b/cgminer.c index b74a152d..e0607392 100644 --- a/cgminer.c +++ b/cgminer.c @@ -7494,6 +7494,13 @@ int main(int argc, char *argv[]) if (unlikely(pthread_cond_init(&gws_cond, NULL))) quit(1, "Failed to pthread_cond_init gws_cond"); + /* Create a unique get work queue */ + getq = tq_new(); + if (!getq) + quit(1, "Failed to create getq"); + /* We use the getq mutex as the staged lock */ + stgd_lock = &getq->mutex; + snprintf(packagename, sizeof(packagename), "%s %s", PACKAGE, VERSION); handler.sa_handler = &sighandler; @@ -7712,13 +7719,6 @@ int main(int argc, char *argv[]) quit(1, "Failed to calloc mining_thr[%d]", i); } - /* Create a unique get work queue */ - getq = tq_new(); - if (!getq) - quit(1, "Failed to create getq"); - /* We use the getq mutex as the staged lock */ - stgd_lock = &getq->mutex; - if (opt_benchmark) goto begin_bench; From 8fa5ddfd2ca581d30ec21ade08332294b481d31c Mon Sep 17 00:00:00 2001 From: Maksym Borodin Date: Wed, 13 Nov 2013 11:57:29 +0100 Subject: [PATCH 8/8] util.c: Decreasing reference count on allocated JSON obects to prevent memory leak --- util.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/util.c b/util.c index 8097eb8d..3a7c61a0 100644 --- a/util.c +++ b/util.c @@ -1736,8 +1736,10 @@ bool parse_method(struct pool *pool, char *s) } method = json_object_get(val, "method"); - if (!method) + if (!method) { + json_decref(val); return ret; + } err_val = json_object_get(val, "error"); params = json_object_get(val, "params"); @@ -1751,42 +1753,51 @@ bool parse_method(struct pool *pool, char *s) applog(LOG_INFO, "JSON-RPC method decode failed: %s", ss); + json_decref(val); free(ss); return ret; } buf = (char *)json_string_value(method); - if (!buf) + if (!buf) { + json_decref(val); return ret; + } if (!strncasecmp(buf, "mining.notify", 13)) { if (parse_notify(pool, params)) pool->stratum_notify = ret = true; else pool->stratum_notify = ret = false; + json_decref(val); return ret; } if (!strncasecmp(buf, "mining.set_difficulty", 21) && parse_diff(pool, params)) { ret = true; + json_decref(val); return ret; } if (!strncasecmp(buf, "client.reconnect", 16) && parse_reconnect(pool, params)) { ret = true; + json_decref(val); return ret; } if (!strncasecmp(buf, "client.get_version", 18) && send_version(pool, val)) { ret = true; + json_decref(val); return ret; } if (!strncasecmp(buf, "client.show_message", 19) && show_message(pool, params)) { ret = true; + json_decref(val); return ret; } + json_decref(val); return ret; } @@ -1829,13 +1840,16 @@ bool auth_stratum(struct pool *pool) applog(LOG_WARNING, "pool %d JSON stratum auth failed: %s", pool->pool_no, ss); free(ss); - return ret; + goto out; } ret = true; applog(LOG_INFO, "Stratum authorisation success for pool %d", pool->pool_no); pool->probed = true; successful_connect = true; + +out: + json_decref(val); return ret; } @@ -2381,6 +2395,7 @@ out: applog(LOG_DEBUG, "Failed to resume stratum, trying afresh"); noresume = true; + json_decref(val); goto resend; } applog(LOG_DEBUG, "Initiate stratum failed"); @@ -2388,6 +2403,7 @@ out: suspend_stratum(pool); } + json_decref(val); return ret; }