From 8bc469e916fc8a4e770df585726066d0fe085c2f Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Mon, 12 Aug 2013 11:16:46 +1000 Subject: [PATCH] Reuse just the one pool coinbase variable in stratum, avoiding more string functions and storage in gen_stratum_work on each work generation. --- cgminer.c | 16 +++------------- miner.h | 7 ------- util.c | 44 ++++++++++++++++++++++++++------------------ 3 files changed, 29 insertions(+), 38 deletions(-) diff --git a/cgminer.c b/cgminer.c index 37e393b1..fa0d1746 100644 --- a/cgminer.c +++ b/cgminer.c @@ -5586,33 +5586,23 @@ void set_target(unsigned char *dest_target, double diff) * other means to detect when the pool has died in stratum_thread */ static void gen_stratum_work(struct pool *pool, struct work *work) { - unsigned char *coinbase, merkle_root[32], merkle_sha[64]; + unsigned char merkle_root[32], merkle_sha[64]; char *header, *merkle_hash; uint32_t *data32, *swap32; - size_t alloc_len; int i; cg_wlock(&pool->data_lock); /* Generate coinbase */ work->nonce2 = bin2hex((const unsigned char *)&pool->nonce2, pool->n2size); + hex2bin(pool->coinbase + pool->nonce2_offset, work->nonce2, pool->n2size); pool->nonce2++; /* Downgrade to a read lock to read off the pool variables */ cg_dwlock(&pool->data_lock); - alloc_len = pool->swork.cb_len; - align_len(&alloc_len); - coinbase = calloc(alloc_len, 1); - if (unlikely(!coinbase)) - quit(1, "Failed to calloc coinbase in gen_stratum_work"); - memcpy(coinbase, pool->swork.cb1, pool->swork.cb1_len); - memcpy(coinbase + pool->swork.cb1_len, pool->nonce1bin, pool->n1_len); - hex2bin(coinbase + pool->nonce2_offset, work->nonce2, pool->n2size); - memcpy(coinbase + pool->swork.cb1_len + pool->n1_len + pool->n2size, pool->swork.cb2, pool->swork.cb2_len); /* Generate merkle root */ - gen_hash(coinbase, merkle_root, pool->swork.cb_len); - free(coinbase); + gen_hash(pool->coinbase, merkle_root, pool->swork.cb_len); memcpy(merkle_sha, merkle_root, 32); for (i = 0; i < pool->swork.merkles; i++) { unsigned char merkle_bin[32]; diff --git a/miner.h b/miner.h index 915b2443..fd15e20b 100644 --- a/miner.h +++ b/miner.h @@ -1088,20 +1088,13 @@ enum pool_enable { struct stratum_work { char *job_id; char *prev_hash; - char *coinbase1; - char *coinbase2; char **merkle; char *bbversion; char *nbit; char *ntime; bool clean; - unsigned char *cb1; - unsigned char *cb2; - size_t cb1_len; - size_t cb2_len; size_t cb_len; - size_t header_len; int merkles; double diff; diff --git a/util.c b/util.c index 1f7fbe61..93c20545 100644 --- a/util.c +++ b/util.c @@ -1200,6 +1200,8 @@ static char *json_array_string(json_t *val, unsigned int entry) static bool parse_notify(struct pool *pool, json_t *val) { char *job_id, *prev_hash, *coinbase1, *coinbase2, *bbversion, *nbit, *ntime; + size_t cb1_len, cb2_len, alloc_len; + unsigned char *cb1, *cb2; bool clean, ret = false; int merkles, i; json_t *arr; @@ -1241,23 +1243,19 @@ static bool parse_notify(struct pool *pool, json_t *val) cg_wlock(&pool->data_lock); free(pool->swork.job_id); free(pool->swork.prev_hash); - free(pool->swork.coinbase1); - free(pool->swork.coinbase2); free(pool->swork.bbversion); free(pool->swork.nbit); free(pool->swork.ntime); pool->swork.job_id = job_id; pool->swork.prev_hash = prev_hash; - pool->swork.coinbase1 = coinbase1; - pool->swork.cb1_len = strlen(coinbase1) / 2; - pool->swork.coinbase2 = coinbase2; - pool->swork.cb2_len = strlen(coinbase2) / 2; + cb1_len = strlen(coinbase1) / 2; + cb2_len = strlen(coinbase2) / 2; pool->swork.bbversion = bbversion; pool->swork.nbit = nbit; pool->swork.ntime = ntime; pool->swork.clean = clean; - pool->swork.cb_len = pool->swork.cb1_len + pool->n1_len + pool->n2size + pool->swork.cb2_len; - pool->nonce2_offset = pool->swork.cb1_len + pool->n1_len; + alloc_len = pool->swork.cb_len = cb1_len + pool->n1_len + pool->n2size + cb2_len; + pool->nonce2_offset = cb1_len + pool->n1_len; for (i = 0; i < pool->swork.merkles; i++) free(pool->swork.merkle[i]); @@ -1279,16 +1277,22 @@ static bool parse_notify(struct pool *pool, json_t *val) pool->swork.header_len = pool->swork.header_len * 2 + 1; align_len(&pool->swork.header_len); - free(pool->swork.cb1); - free(pool->swork.cb2); - pool->swork.cb1 = calloc(pool->swork.cb1_len, 1); - if (unlikely(!pool->swork.cb1)) - quithere(1, "Failed to calloc swork cb1"); - hex2bin(pool->swork.cb1, pool->swork.coinbase1, pool->swork.cb1_len); - pool->swork.cb2 = calloc(pool->swork.cb2_len, 1); - if (unlikely(!pool->swork.cb2)) - quithere(1, "Failed to calloc swork cb2"); - hex2bin(pool->swork.cb2, pool->swork.coinbase2, pool->swork.cb2_len); + cb1 = calloc(cb1_len, 1); + if (unlikely(!cb1)) + quithere(1, "Failed to calloc cb1 in parse_notify"); + hex2bin(cb1, coinbase1, cb1_len); + cb2 = calloc(cb2_len, 1); + if (unlikely(!cb2)) + quithere(1, "Failed to calloc cb2 in parse_notify"); + hex2bin(cb2, coinbase2, cb2_len); + free(pool->coinbase); + align_len(&alloc_len); + pool->coinbase = calloc(alloc_len, 1); + if (unlikely(!pool->coinbase)) + quit(1, "Failed to calloc pool coinbase in parse_notify"); + memcpy(pool->coinbase, cb1, cb1_len); + memcpy(pool->coinbase + cb1_len, pool->nonce1bin, pool->n1_len); + memcpy(pool->coinbase + cb1_len + pool->n1_len + pool->n2size, cb2, cb2_len); cg_wunlock(&pool->data_lock); if (opt_protocol) { @@ -1303,6 +1307,10 @@ static bool parse_notify(struct pool *pool, json_t *val) applog(LOG_DEBUG, "ntime: %s", ntime); applog(LOG_DEBUG, "clean: %s", clean ? "yes" : "no"); } + free(coinbase1); + free(coinbase2); + free(cb1); + free(cb2); /* A notify message is the closest stratum gets to a getwork */ pool->getwork_requested++;