Browse Source

Split part of minerloop_async into do_job_prepare and do_job_start

Luke Dashjr 13 years ago
parent
commit
e8090899bf
3 changed files with 61 additions and 47 deletions
  1. 3 4
      driver-x6500.c
  2. 56 43
      miner.c
  3. 2 0
      miner.h

+ 3 - 4
driver-x6500.c

@@ -672,22 +672,21 @@ void x6500_job_start(struct thr_info *thr)
 	ft232r_flush(jp->a->ftdi);
 	ft232r_flush(jp->a->ftdi);
 
 
 	gettimeofday(&tv_now, NULL);
 	gettimeofday(&tv_now, NULL);
-	if (!thr->work)
+	if (!thr->prev_work)
 		fpga->tv_hashstart = tv_now;
 		fpga->tv_hashstart = tv_now;
 	else
 	else
-	if (thr->work != thr->next_work)
+	if (thr->prev_work != thr->work)
 		calc_hashes(thr, &tv_now);
 		calc_hashes(thr, &tv_now);
 	fpga->hashes_left = 0x100000000;
 	fpga->hashes_left = 0x100000000;
 
 
 	if (x6500_all_idle(x6500))
 	if (x6500_all_idle(x6500))
 	{
 	{
 		pthread_mutex_t *mutexp = &x6500->device->device_mutex;
 		pthread_mutex_t *mutexp = &x6500->device->device_mutex;
-		thr->work = (void*)1;  // HACK: Should be replaced immediately upon return
 		mutex_unlock(mutexp);
 		mutex_unlock(mutexp);
 	}
 	}
 	
 	
 	if (opt_debug) {
 	if (opt_debug) {
-		char *xdata = bin2hex(thr->next_work->data, 80);
+		char *xdata = bin2hex(thr->work->data, 80);
 		applog(LOG_DEBUG, "%"PRIprepr": Started work: %s",
 		applog(LOG_DEBUG, "%"PRIprepr": Started work: %s",
 		       x6500->proc_repr, xdata);
 		       x6500->proc_repr, xdata);
 		free(xdata);
 		free(xdata);

+ 56 - 43
miner.c

@@ -6767,23 +6767,69 @@ disabled:
 	}
 	}
 }
 }
 
 
+bool do_job_prepare(struct thr_info *mythr, struct timeval *tvp_now)
+{
+	struct cgpu_info *proc = mythr->cgpu;
+	const struct device_api *api = proc->api;
+	struct timeval tv_worktime;
+	
+	if (mythr->work)
+		timersub(tvp_now, &mythr->work->tv_work_start, &tv_worktime);
+	if ((!mythr->work) || abandon_work(mythr->work, &tv_worktime, proc->max_hashes))
+	{
+		mythr->work_restart = false;
+		request_work(mythr);
+		// FIXME: Allow get_work to return NULL to retry on notification
+		mythr->next_work = get_work(mythr);
+		if (api->prepare_work && !api->prepare_work(mythr, mythr->next_work)) {
+			applog(LOG_ERR, "%"PRIpreprv": Work prepare failed, disabling!", proc->proc_repr);
+			proc->deven = DEV_RECOVER_ERR;
+			return false;
+		}
+		mythr->starting_next_work = true;
+		api->job_prepare(mythr, mythr->next_work, mythr->_max_nonce);
+	}
+	else
+	{
+		mythr->starting_next_work = false;
+		api->job_prepare(mythr, mythr->work, mythr->_max_nonce);
+	}
+	return true;
+}
+
+void do_job_start(struct thr_info *mythr, struct timeval *tvp_now)
+{
+	struct cgpu_info *proc = mythr->cgpu;
+	const struct device_api *api = proc->api;
+	
+	if (mythr->starting_next_work)
+	{
+		mythr->next_work->tv_work_start = *tvp_now;
+		if (mythr->prev_work)
+			free_work(mythr->prev_work);
+		mythr->prev_work = mythr->work;
+		mythr->work = mythr->next_work;
+		mythr->next_work = NULL;
+	}
+	mythr->tv_jobstart = *tvp_now;
+	api->job_start(mythr);
+}
+
 void minerloop_async(struct thr_info *mythr)
 void minerloop_async(struct thr_info *mythr)
 {
 {
 	const int thr_id = mythr->id;
 	const int thr_id = mythr->id;
 	struct cgpu_info *cgpu = mythr->cgpu;
 	struct cgpu_info *cgpu = mythr->cgpu;
 	const struct device_api *api = cgpu->api;
 	const struct device_api *api = cgpu->api;
 	struct timeval tv_start, tv_end;
 	struct timeval tv_start, tv_end;
-	struct timeval tv_hashes, tv_worktime;
+	struct timeval tv_hashes;
 	struct timeval tv_now;
 	struct timeval tv_now;
 	struct timeval tv_timeout, *tvp_timeout;
 	struct timeval tv_timeout, *tvp_timeout;
-	uint32_t max_nonce = api->can_limit_work ? api->can_limit_work(mythr) : 0xffffffff;
 	int64_t hashes;
 	int64_t hashes;
 	struct work *work;
 	struct work *work;
 	const bool primary = (!mythr->device_thread) || mythr->primary_thread;
 	const bool primary = (!mythr->device_thread) || mythr->primary_thread;
 	struct cgpu_info *proc;
 	struct cgpu_info *proc;
-	bool starting_new_work;
 	// NOTE: prev_job_work/new_job_work are distinct from mythr->prev_work/next_work (job v work boundary)
 	// NOTE: prev_job_work/new_job_work are distinct from mythr->prev_work/next_work (job v work boundary)
-	struct work *prev_job_work, *new_job_work;
+	struct work *prev_job_work;
 	int proc_thr_no;
 	int proc_thr_no;
 	int maxfd;
 	int maxfd;
 	fd_set rfds;
 	fd_set rfds;
@@ -6813,30 +6859,8 @@ disabled: ;
 				prev_job_work = mythr->work;
 				prev_job_work = mythr->work;
 				tv_start = mythr->tv_jobstart;
 				tv_start = mythr->tv_jobstart;
 				if (likely(keepgoing))
 				if (likely(keepgoing))
-				{
-					if (prev_job_work)
-						timersub(&tv_now, &mythr->work->tv_work_start, &tv_worktime);
-					if ((!prev_job_work) || abandon_work(mythr->work, &tv_worktime, cgpu->max_hashes))
-					{
-						mythr->work_restart = false;
-						request_work(mythr);
-						// FIXME: Allow get_work to return NULL to retry on notification
-						mythr->next_work = get_work(mythr);
-						if (api->prepare_work && !api->prepare_work(mythr, mythr->next_work)) {
-							applog(LOG_ERR, "%"PRIpreprv": Work prepare failed, disabling!");
-							proc->deven = DEV_RECOVER_ERR;
-							goto disabled;
-						}
-						starting_new_work = true;
-						new_job_work = mythr->next_work;
-					}
-					else
-					{
-						starting_new_work = false;
-						new_job_work = mythr->work;
-					}
-					api->job_prepare(mythr, new_job_work, max_nonce);
-				}
+					if (!do_job_prepare(mythr, &tv_now))
+						goto disabled;
 				if (likely(prev_job_work))
 				if (likely(prev_job_work))
 				{
 				{
 					hashes = -101;
 					hashes = -101;
@@ -6845,20 +6869,7 @@ disabled: ;
 				}
 				}
 				gettimeofday(&tv_now, NULL);  // NOTE: Can go away when fully async
 				gettimeofday(&tv_now, NULL);  // NOTE: Can go away when fully async
 				if (likely(keepgoing))
 				if (likely(keepgoing))
-				{
-					if (starting_new_work)
-						mythr->next_work->tv_work_start = tv_now;
-					mythr->tv_jobstart = tv_now;
-					api->job_start(mythr);
-					if (starting_new_work)
-					{
-						if (mythr->prev_work)
-							free_work(mythr->prev_work);
-						mythr->prev_work = prev_job_work;
-						mythr->work = mythr->next_work;
-						mythr->next_work = NULL;
-					}
-				}
+					do_job_start(mythr, &tv_now);
 				else
 				else
 				{
 				{
 					mythr->prev_work = mythr->work;
 					mythr->prev_work = mythr->work;
@@ -6874,7 +6885,7 @@ disabled: ;
 					if (hashes != -101)
 					if (hashes != -101)
 					{
 					{
 						timersub(&tv_now, &tv_start, &tv_hashes);
 						timersub(&tv_now, &tv_start, &tv_hashes);
-						if (!hashes_done(mythr, hashes, &tv_hashes, api->can_limit_work ? &max_nonce : NULL))
+						if (!hashes_done(mythr, hashes, &tv_hashes, api->can_limit_work ? &mythr->_max_nonce : NULL))
 							goto disabled;
 							goto disabled;
 					}
 					}
 				}
 				}
@@ -8475,6 +8486,7 @@ begin_bench:
 	k = 0;
 	k = 0;
 	for (i = 0; i < total_devices; ++i) {
 	for (i = 0; i < total_devices; ++i) {
 		struct cgpu_info *cgpu = devices[i];
 		struct cgpu_info *cgpu = devices[i];
+		const struct device_api *api = cgpu->api;
 		int threadobj = cgpu->threads;
 		int threadobj = cgpu->threads;
 		if (!threadobj)
 		if (!threadobj)
 			// Create a fake thread object to handle hashmeter etc
 			// Create a fake thread object to handle hashmeter etc
@@ -8499,6 +8511,7 @@ begin_bench:
 			timerclear(&thr->tv_hashes_done);
 			timerclear(&thr->tv_hashes_done);
 			gettimeofday(&thr->tv_lastupdate, NULL);
 			gettimeofday(&thr->tv_lastupdate, NULL);
 			thr->tv_poll.tv_sec = -1;
 			thr->tv_poll.tv_sec = -1;
+			thr->_max_nonce = api->can_limit_work ? api->can_limit_work(thr) : 0xffffffff;
 
 
 			cgpu->thr[j] = thr;
 			cgpu->thr[j] = thr;
 		}
 		}

+ 2 - 0
miner.h

@@ -563,6 +563,8 @@ struct thr_info {
 	struct timeval tv_jobstart;
 	struct timeval tv_jobstart;
 	struct timeval tv_poll;
 	struct timeval tv_poll;
 	int notifier[2];
 	int notifier[2];
+	bool starting_next_work;
+	uint32_t _max_nonce;
 
 
 	bool	work_restart;
 	bool	work_restart;
 	int		work_restart_fd;
 	int		work_restart_fd;