Submitting an ntime offset nonce needs to be done on a copy of the work instead of the original so abstract out shared components as much as possible, minimising strdups in copy_work and make submit_work_async work take copied work, cleaning up code in the process.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
diff --git a/cgminer.c b/cgminer.c
index 5d0667d..650db80 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -3511,9 +3511,23 @@ static void *submit_work_thread(void __maybe_unused *userdata)
}
#endif /* HAVE_LIBCURL */
+/* Return an adjusted ntime if we're submitting work that a device has
+ * internally offset the ntime. */
+static char *offset_ntime(const char *ntime, int noffset)
+{
+ unsigned char bin[4];
+ uint32_t h32, *be32 = (uint32_t *)bin;
+
+ hex2bin(bin, ntime, 4);
+ h32 = be32toh(*be32) + noffset;
+ *be32 = htobe32(h32);
+
+ return bin2hex(bin, 4);
+}
+
/* Duplicates any dynamically allocated arrays within the work struct to
* prevent a copied work struct from freeing ram belonging to another struct */
-void __copy_work(struct work *work, struct work *base_work)
+static void _copy_work(struct work *work, const struct work *base_work, int noffset)
{
int id = work->id;
@@ -3526,8 +3540,12 @@ void __copy_work(struct work *work, struct work *base_work)
work->job_id = strdup(base_work->job_id);
if (base_work->nonce1)
work->nonce1 = strdup(base_work->nonce1);
- if (base_work->ntime)
- work->ntime = strdup(base_work->ntime);
+ if (base_work->ntime) {
+ if (noffset)
+ work->ntime = offset_ntime(base_work->ntime, noffset);
+ else
+ work->ntime = strdup(base_work->ntime);
+ }
if (base_work->coinbase)
work->coinbase = strdup(base_work->coinbase);
}
@@ -3538,7 +3556,7 @@ struct work *copy_work(struct work *base_work)
{
struct work *work = make_work();
- __copy_work(work, base_work);
+ _copy_work(work, base_work, 0);
return work;
}
@@ -5972,14 +5990,13 @@ static struct work *get_work(struct thr_info *thr, const int thr_id)
return work;
}
-static void submit_work_async(struct work *work_in, struct timeval *tv_work_found)
+/* Submit a copy of the tested, statistic recorded work item asynchronously */
+static void submit_work_async(struct work *work)
{
- struct work *work = copy_work(work_in);
struct pool *pool = work->pool;
pthread_t submit_thread;
- if (tv_work_found)
- copy_time(&work->tv_work_found, tv_work_found);
+ cgtime(&work->tv_work_found);
if (stale_work(work, true)) {
if (opt_submit_stale)
@@ -6018,6 +6035,9 @@ static void submit_work_async(struct work *work_in, struct timeval *tv_work_foun
void inc_hw_errors(struct thr_info *thr)
{
+ applog(LOG_INFO, "%s%d: invalid nonce - HW error", thr->cgpu->drv->name,
+ thr->cgpu->device_id);
+
mutex_lock(&stats_lock);
hw_errors++;
thr->cgpu->hw_errors++;
@@ -6042,12 +6062,8 @@ bool test_nonce(struct work *work, uint32_t nonce)
return (be32toh(hash2_32[7]) <= diff1targ);
}
-/* To be used once the work has been tested to be meet diff1 and has had its
- * nonce adjusted. */
-void submit_tested_work(struct thr_info *thr, struct work *work)
+static void update_work_stats(struct thr_info *thr, struct work *work)
{
- struct timeval tv_work_found;
-
work->share_diff = share_diff(work);
mutex_lock(&stats_lock);
@@ -6056,50 +6072,63 @@ void submit_tested_work(struct thr_info *thr, struct work *work)
work->pool->diff1 += work->device_diff;
thr->cgpu->last_device_valid_work = time(NULL);
mutex_unlock(&stats_lock);
+}
+
+/* To be used once the work has been tested to be meet diff1 and has had its
+ * nonce adjusted. */
+void submit_tested_work(struct thr_info *thr, struct work *work)
+{
+ struct work *work_out;
+ update_work_stats(thr, work);
if (!fulltest(work->hash2, work->target)) {
applog(LOG_INFO, "Share below target");
return;
}
-
- cgtime(&tv_work_found);
- submit_work_async(work, &tv_work_found);
+ work_out = copy_work(work);
+ submit_work_async(work_out);
}
/* Returns true if nonce for work was a valid share */
bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
{
- bool ret = true;
-
if (test_nonce(work, nonce))
submit_tested_work(thr, work);
else {
- applog(LOG_INFO, "%s%d: invalid nonce - HW error",
- thr->cgpu->drv->name, thr->cgpu->device_id);
-
inc_hw_errors(thr);
- ret = false;
+ return false;
}
- return ret;
+ return true;
}
/* Allows drivers to submit work items where the driver has changed the ntime
* value by noffset. Must be only used with a work protocol that does not ntime
- * roll itself intrinsically to generate work (eg stratum). */
-bool submit_noffset_nonce(struct thr_info *thr, struct work *work, uint32_t nonce,
+ * roll itself intrinsically to generate work (eg stratum). We do not touch
+ * the original work struct, but the copy of it only. */
+bool submit_noffset_nonce(struct thr_info *thr, struct work *work_in, uint32_t nonce,
int noffset)
{
- unsigned char bin[4];
- uint32_t h32, *be32 = (uint32_t *)bin;
+ struct work *work = make_work();
+ bool ret = false;
- hex2bin(bin, work->ntime, 4);
- h32 = be32toh(*be32) + noffset;
- *be32 = htobe32(h32);
- free(work->ntime);
- work->ntime = bin2hex(bin, 4);
+ _copy_work(work, work_in, noffset);
+ if (!test_nonce(work, nonce)) {
+ inc_hw_errors(thr);
+ goto out;
+ }
+ ret = true;
+ update_work_stats(thr, work);
+ if (!fulltest(work->hash2, work->target)) {
+ applog(LOG_INFO, "Share below target");
+ goto out;
+ }
+ submit_work_async(work);
- return submit_nonce(thr, work, nonce);
+out:
+ if (!ret)
+ free_work(work);
+ return ret;
}
static inline bool abandon_work(struct work *work, struct timeval *wdiff, uint64_t hashes)
diff --git a/miner.h b/miner.h
index 9c49a35..87cb808 100644
--- a/miner.h
+++ b/miner.h
@@ -1419,7 +1419,6 @@ extern void adl(void);
extern void app_restart(void);
extern void clean_work(struct work *work);
extern void free_work(struct work *work);
-extern void __copy_work(struct work *work, struct work *base_work);
extern struct work *copy_work(struct work *base_work);
extern struct thr_info *get_thread(int thr_id);
extern struct cgpu_info *get_devices(int id);