Browse Source

Bugfix: minerloop_async: Intelligently handle work updates and device disables during transitions

api->job_get_results ... job_results_fetched
	If work updated: prepare it (atomic), DON'T trigger start or get results
	If device disabled: ensure job is not started when get results completes
api->job_start ... job_start_complete
	If work updated: delay action until job start completed
	If device disabled: delay action until job start completed
Luke Dashjr 13 years ago
parent
commit
68769d06cd
2 changed files with 20 additions and 1 deletions
  1. 13 1
      deviceapi.c
  2. 7 0
      miner.h

+ 13 - 1
deviceapi.c

@@ -171,6 +171,8 @@ bool do_job_prepare(struct thr_info *mythr, struct timeval *tvp_now)
 
 void job_prepare_complete(struct thr_info *mythr)
 {
+	if (unlikely(mythr->busy_state == TBS_GETTING_RESULTS))
+		return;
 	if (mythr->work)
 	{
 		if (true /* TODO: job is near complete */ || unlikely(mythr->work_restart))
@@ -298,6 +300,11 @@ void minerloop_async(struct thr_info *mythr)
 		for (proc = cgpu; proc; proc = proc->next_proc)
 		{
 			mythr = proc->thr[0];
+			
+			// Nothing should happen while we're starting a job
+			if (unlikely(mythr->busy_state == TBS_STARTING_JOB))
+				goto defer_events;
+			
 			is_running = mythr->work;
 			should_be_running = (proc->deven == DEV_ENABLED && !mythr->pause);
 			
@@ -317,7 +324,11 @@ void minerloop_async(struct thr_info *mythr)
 				{
 disabled: ;
 					mythr->tv_morework.tv_sec = -1;
-					do_get_results(mythr, false);
+					if (mythr->busy_state != TBS_GETTING_RESULTS)
+						do_get_results(mythr, false);
+					else
+						// Avoid starting job when pending result fetch completes
+						mythr->_proceed_with_new_job = false;
 				}
 			}
 			
@@ -328,6 +339,7 @@ djp: ;
 					goto disabled;
 			}
 			
+defer_events:
 			if (timer_passed(&mythr->tv_poll, &tv_now))
 				api->poll(mythr);
 			

+ 7 - 0
miner.h

@@ -534,6 +534,12 @@ struct thread_q {
 	pthread_cond_t		cond;
 };
 
+enum thr_busy_state {
+	TBS_IDLE,
+	TBS_GETTING_RESULTS,
+	TBS_STARTING_JOB,
+};
+
 struct thr_info {
 	int		id;
 	int		device_thread;
@@ -559,6 +565,7 @@ struct thr_info {
 	struct work *prev_work;
 	struct work *work;
 	struct work *next_work;
+	enum thr_busy_state busy_state;
 	struct timeval tv_morework;
 	struct work *results_work;
 	bool _job_transition_in_progress;