From d342bcbe8127443c3e19aabc344c0f8918548c59 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 25 Oct 2013 11:56:32 +1100 Subject: [PATCH] Provide a mechanism for informing drivers of updated work templates for stratum and gbt mining. --- cgminer.c | 30 +++++++++++++++++++++++++++--- miner.h | 5 +++++ util.c | 2 ++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/cgminer.c b/cgminer.c index d7d91ef0..cb4fa45c 100644 --- a/cgminer.c +++ b/cgminer.c @@ -90,6 +90,7 @@ struct strategies strategies[] = { static char packagename[256]; +bool opt_work_update; bool opt_protocol; static bool opt_benchmark; bool have_longpoll; @@ -1842,6 +1843,8 @@ static void update_gbt(struct pool *pool) applog(LOG_DEBUG, "Successfully retrieved and updated GBT from pool %u %s", pool->pool_no, pool->rpc_url); cgtime(&pool->tv_idle); + if (pool == current_pool()) + opt_work_update = true; } else { applog(LOG_DEBUG, "Successfully retrieved but FAILED to decipher GBT from pool %u %s", pool->pool_no, pool->rpc_url); @@ -3938,6 +3941,18 @@ static void restart_threads(void) #endif } +static void signal_work_update(void) +{ + int i; + + applog(LOG_INFO, "Work update message received"); + + rd_lock(&mining_thr_lock); + for (i = 0; i < mining_threads; i++) + mining_thr[i]->work_update = true; + rd_unlock(&mining_thr_lock); +} + static void set_curblock(char *hexstr, unsigned char *hash) { unsigned char hash_swap[32]; @@ -6502,7 +6517,7 @@ void hash_queued_work(struct thr_info *mythr) struct timeval diff; int64_t hashes; - mythr->work_restart = false; + mythr->work_restart = mythr->work_update = false; fill_queue(mythr, cgpu, drv, thr_id); @@ -6532,7 +6547,8 @@ void hash_queued_work(struct thr_info *mythr) if (unlikely(mythr->work_restart)) { flush_queue(cgpu); drv->flush_work(cgpu); - } + } else if (mythr->work_update) + drv->update_work(cgpu); } cgpu->deven = DEV_DISABLED; } @@ -6553,7 +6569,7 @@ void hash_driver_work(struct thr_info *mythr) struct timeval diff; int64_t hashes; - mythr->work_restart = false; + mythr->work_restart = mythr->work_update = false; hashes = drv->scanwork(mythr); @@ -6580,6 +6596,8 @@ void hash_driver_work(struct thr_info *mythr) if (unlikely(mythr->work_restart)) drv->flush_work(cgpu); + else if (mythr->work_update) + drv->update_work(cgpu); } cgpu->deven = DEV_DISABLED; } @@ -7560,6 +7578,7 @@ static void noop_detect(bool __maybe_unused hotplug) { } #define noop_flush_work noop_reinit_device +#define noop_update_work noop_reinit_device #define noop_queue_full noop_get_stats /* Fill missing driver drv functions with noops */ @@ -7593,6 +7612,8 @@ void fill_device_drv(struct device_drv *drv) drv->hash_work = &hash_sole_work; if (!drv->flush_work) drv->flush_work = &noop_flush_work; + if (!drv->update_work) + drv->update_work = &noop_update_work; if (!drv->queue_full) drv->queue_full = &noop_queue_full; if (!drv->max_diff) @@ -8316,6 +8337,9 @@ begin_bench: bool lagging = false; struct work *work; + if (opt_work_update) + signal_work_update(); + opt_work_update = false; cp = current_pool(); /* If the primary pool is a getwork pool and cannot roll work, diff --git a/miner.h b/miner.h index 4e3b5a17..9087c27e 100644 --- a/miner.h +++ b/miner.h @@ -363,7 +363,10 @@ struct device_drv { * the main loop that it should not add any further work to the table. */ bool (*queue_full)(struct cgpu_info *); + /* Tell the driver of a block change */ void (*flush_work)(struct cgpu_info *); + /* Tell the driver of an updated work template for eg. stratum */ + void (*update_work)(struct cgpu_info *); void (*hw_error)(struct thr_info *); void (*thread_shutdown)(struct thr_info *); @@ -611,6 +614,7 @@ struct thr_info { double rolling; bool work_restart; + bool work_update; }; struct string_elist { @@ -989,6 +993,7 @@ struct pool; #define API_MCAST_CODE "FTW" #define API_MCAST_ADDR "224.0.0.75" +extern bool opt_work_update; extern bool opt_protocol; extern bool have_longpoll; extern char *opt_kernel_path; diff --git a/util.c b/util.c index 87d7bac6..363c73c4 100644 --- a/util.c +++ b/util.c @@ -1610,6 +1610,8 @@ static bool parse_notify(struct pool *pool, json_t *val) pool->getwork_requested++; total_getworks++; ret = true; + if (pool == current_pool()) + opt_work_update = true; out: return ret; }