Browse Source

Core support for managing multiple processors from a single thread

Luke Dashjr 13 years ago
parent
commit
b604f8fd76
1 changed files with 22 additions and 15 deletions
  1. 22 15
      miner.c

+ 22 - 15
miner.c

@@ -5535,6 +5535,7 @@ static void hashmeter(int thr_id, struct timeval *diff,
 	if (thr_id >= 0) {
 		struct thr_info *thr = &thr_info[thr_id];
 		struct cgpu_info *cgpu = thr_info[thr_id].cgpu;
+		int threadobj = cgpu->threads ?: 1;
 		double thread_rolling = 0.0;
 		int i;
 
@@ -5543,7 +5544,7 @@ static void hashmeter(int thr_id, struct timeval *diff,
 
 		/* Rolling average for each thread and each device */
 		decay_time(&thr->rolling, local_mhashes / secs);
-		for (i = 0; i < cgpu->threads; i++)
+		for (i = 0; i < threadobj; i++)
 			thread_rolling += cgpu->thr[i]->rolling;
 
 		mutex_lock(&hash_lock);
@@ -6748,8 +6749,9 @@ void *miner_thread(void *userdata)
 	RenameThread(threadname);
 
 	if (api->thread_init && !api->thread_init(mythr)) {
-		// FIXME: Should affect all processors managed
 		dev_error(cgpu, REASON_THREAD_FAIL_INIT);
+		for (struct cgpu_info *slave = cgpu->next_proc; slave && !slave->threads; slave = slave->next_proc)
+			dev_error(slave, REASON_THREAD_FAIL_INIT);
 		goto out;
 	}
 
@@ -8293,25 +8295,40 @@ begin_bench:
 	k = 0;
 	for (i = 0; i < total_devices; ++i) {
 		struct cgpu_info *cgpu = devices[i];
-		cgpu->thr = calloc(cgpu->threads+1, sizeof(*cgpu->thr));
-		cgpu->thr[cgpu->threads] = NULL;
+		int threadobj = cgpu->threads;
+		if (!threadobj)
+			// Create a fake thread object to handle hashmeter etc
+			threadobj = 1;
+		cgpu->thr = calloc(threadobj + 1, sizeof(*cgpu->thr));
+		cgpu->thr[threadobj] = NULL;
 		cgpu->status = LIFE_INIT;
 
 		cgpu->max_hashes = 0;
 
 		// Setup thread structs before starting any of the threads, in case they try to interact
-		for (j = 0; j < cgpu->threads; ++j, ++k) {
+		for (j = 0; j < threadobj; ++j, ++k) {
 			thr = &thr_info[k];
 			thr->id = k;
 			thr->cgpu = cgpu;
 			thr->device_thread = j;
 			thr->work_restart_fd = thr->_work_restart_fd_w = -1;
+			timerclear(&thr->tv_morework);
 
 			thr->scanhash_working = true;
 			thr->hashes_done = 0;
 			timerclear(&thr->tv_hashes_done);
 			gettimeofday(&thr->tv_lastupdate, NULL);
 
+			cgpu->thr[j] = thr;
+		}
+	}
+
+	// Start threads
+	for (i = 0; i < total_devices; ++i) {
+		struct cgpu_info *cgpu = devices[i];
+		for (j = 0; j < cgpu->threads; ++j) {
+			thr = cgpu->thr[j];
+
 			thr->q = tq_new();
 			if (!thr->q)
 				quit(1, "tq_new failed in starting %"PRIpreprv" mining thread (#%d)", cgpu->proc_repr, i);
@@ -8324,16 +8341,6 @@ begin_bench:
 				tq_push(thr->q, &ping);
 			}
 
-			cgpu->thr[j] = thr;
-		}
-	}
-
-	// Start threads
-	for (i = 0; i < total_devices; ++i) {
-		struct cgpu_info *cgpu = devices[i];
-		for (j = 0; j < cgpu->threads; ++j) {
-			thr = cgpu->thr[j];
-
 			if (cgpu->api->thread_prepare && !cgpu->api->thread_prepare(thr))
 				continue;