Browse Source

Clone cgminer's submit_noffset_nonce interface

Luke Dashjr 12 years ago
parent
commit
f1922540cc
2 changed files with 40 additions and 8 deletions
  1. 37 8
      miner.c
  2. 3 0
      miner.h

+ 37 - 8
miner.c

@@ -4819,7 +4819,7 @@ static void roll_work(struct work *work)
 
 
 /* Duplicates any dynamically allocated arrays within the work struct to
 /* Duplicates any dynamically allocated arrays within the work struct to
  * prevent a copied work struct from freeing ram belonging to another struct */
  * prevent a copied work struct from freeing ram belonging to another struct */
-void __copy_work(struct work *work, const struct work *base_work)
+static void _copy_work(struct work *work, const struct work *base_work, int noffset)
 {
 {
 	int id = work->id;
 	int id = work->id;
 
 
@@ -4840,6 +4840,15 @@ void __copy_work(struct work *work, const struct work *base_work)
 		++*work->tmpl_refcount;
 		++*work->tmpl_refcount;
 		mutex_unlock(&pool->pool_lock);
 		mutex_unlock(&pool->pool_lock);
 	}
 	}
+	
+	if (noffset)
+	{
+		uint32_t *work_ntime = (uint32_t *)(work->data + 68);
+		uint32_t ntime = be32toh(*work_ntime);
+
+		ntime += noffset;
+		*work_ntime = htobe32(ntime);
+	}
 }
 }
 
 
 /* Generates a copy of an existing work struct, creating fresh heap allocations
 /* Generates a copy of an existing work struct, creating fresh heap allocations
@@ -4848,11 +4857,16 @@ struct work *copy_work(const struct work *base_work)
 {
 {
 	struct work *work = make_work();
 	struct work *work = make_work();
 
 
-	__copy_work(work, base_work);
+	_copy_work(work, base_work, 0);
 
 
 	return work;
 	return work;
 }
 }
 
 
+void __copy_work(struct work *work, const struct work *base_work)
+{
+	_copy_work(work, base_work, 0);
+}
+
 static struct work *make_clone(struct work *work)
 static struct work *make_clone(struct work *work)
 {
 {
 	struct work *work_clone = copy_work(work);
 	struct work *work_clone = copy_work(work);
@@ -8496,6 +8510,8 @@ void gen_stratum_work2(struct work *work, struct stratum_work *swork, const char
 	work->id = total_work++;
 	work->id = total_work++;
 	work->longpoll = false;
 	work->longpoll = false;
 	work->getwork_mode = GETWORK_MODE_STRATUM;
 	work->getwork_mode = GETWORK_MODE_STRATUM;
+	/* Nominally allow a driver to ntime roll 60 seconds */
+	work->drv_rolllimit = 60;
 	calc_diff(work, 0);
 	calc_diff(work, 0);
 }
 }
 
 
@@ -8590,10 +8606,9 @@ void _submit_work_async(struct work *work)
 	notifier_wake(submit_waiting_notifier);
 	notifier_wake(submit_waiting_notifier);
 }
 }
 
 
-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_async2(struct work *work, struct timeval *tv_work_found)
 {
 {
-	struct work *work = copy_work(work_in);
-
 	if (tv_work_found)
 	if (tv_work_found)
 		copy_time(&work->tv_work_found, tv_work_found);
 		copy_time(&work->tv_work_found, tv_work_found);
 	
 	
@@ -8662,8 +8677,20 @@ enum test_nonce2_result _test_nonce2(struct work *work, uint32_t nonce, bool che
 /* Returns true if nonce for work was a valid share */
 /* Returns true if nonce for work was a valid share */
 bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
 bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
 {
 {
+	return submit_noffset_nonce(thr, work, nonce, 0);
+}
+
+/* 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). 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)
+{
+	struct work *work = make_work();
+	_copy_work(work, work_in, noffset);
+	
 	uint32_t *work_nonce = (uint32_t *)(work->data + 64 + 12);
 	uint32_t *work_nonce = (uint32_t *)(work->data + 64 + 12);
-	uint32_t bak_nonce = *work_nonce;
 	struct timeval tv_work_found;
 	struct timeval tv_work_found;
 	enum test_nonce2_result res;
 	enum test_nonce2_result res;
 	bool ret = true;
 	bool ret = true;
@@ -8704,9 +8731,11 @@ bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
 			goto out;
 			goto out;
 	}
 	}
 	
 	
-	submit_work_async(work, &tv_work_found);
+	submit_work_async2(work, &tv_work_found);
+	work = NULL;  // Taken by submit_work_async2
 out:
 out:
-	*work_nonce = bak_nonce;
+	if (work)
+		free_work(work);
 	thread_reportin(thr);
 	thread_reportin(thr);
 
 
 	return ret;
 	return ret;

+ 3 - 0
miner.h

@@ -1341,6 +1341,7 @@ struct work {
 	uint64_t	share_diff;
 	uint64_t	share_diff;
 
 
 	int		rolls;
 	int		rolls;
+	int		drv_rolllimit; /* How much the driver can roll ntime */
 
 
 	dev_blk_ctx	blk;
 	dev_blk_ctx	blk;
 
 
@@ -1413,6 +1414,8 @@ extern enum test_nonce2_result _test_nonce2(struct work *, uint32_t nonce, bool
 #define test_nonce(work, nonce, checktarget)  (_test_nonce2(work, nonce, checktarget) == TNR_GOOD)
 #define test_nonce(work, nonce, checktarget)  (_test_nonce2(work, nonce, checktarget) == TNR_GOOD)
 #define test_nonce2(work, nonce)  (_test_nonce2(work, nonce, true))
 #define test_nonce2(work, nonce)  (_test_nonce2(work, nonce, true))
 extern bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce);
 extern bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce);
+extern bool submit_noffset_nonce(struct thr_info *thr, struct work *work, uint32_t nonce,
+			  int noffset);
 extern void __add_queued(struct cgpu_info *cgpu, struct work *work);
 extern void __add_queued(struct cgpu_info *cgpu, struct work *work);
 extern struct work *get_queued(struct cgpu_info *cgpu);
 extern struct work *get_queued(struct cgpu_info *cgpu);
 extern void add_queued(struct cgpu_info *cgpu, struct work *work);
 extern void add_queued(struct cgpu_info *cgpu, struct work *work);