Browse Source

bitforce: Support for queue id based jobs

Luke Dashjr 11 years ago
parent
commit
dac54aff29
1 changed files with 81 additions and 24 deletions
  1. 81 24
      driver-bitforce.c

+ 81 - 24
driver-bitforce.c

@@ -117,6 +117,7 @@ struct bitforce_data {
 	float temp[2];
 	float temp[2];
 	long *volts;
 	long *volts;
 	int volts_count;
 	int volts_count;
+	unsigned max_queueid;
 	
 	
 	bool probed;
 	bool probed;
 	bool supports_fanspeed;
 	bool supports_fanspeed;
@@ -413,6 +414,7 @@ struct bitforce_init_data {
 	int *parallels;
 	int *parallels;
 	unsigned queue_depth;
 	unsigned queue_depth;
 	unsigned long scan_interval_ms;
 	unsigned long scan_interval_ms;
+	unsigned max_queueid;
 };
 };
 
 
 static
 static
@@ -510,6 +512,9 @@ bool bitforce_detect_oneof(const char * const devpath, struct bitforce_lowl_inte
 		if (!strncasecmp(pdevbuf, "CHANNEL", 7))
 		if (!strncasecmp(pdevbuf, "CHANNEL", 7))
 			maxchipno = max(maxchipno, atoi(&pdevbuf[7]));
 			maxchipno = max(maxchipno, atoi(&pdevbuf[7]));
 		else
 		else
+		if (!strncasecmp(pdevbuf, "CORTEX-", 7))
+			maxchipno = max(maxchipno, strtol(&pdevbuf[7], NULL, 0x10));
+		else
 		if (!strncasecmp(pdevbuf, "DEVICES IN CHAIN:", 17))
 		if (!strncasecmp(pdevbuf, "DEVICES IN CHAIN:", 17))
 			procs = atoi(&pdevbuf[17]);
 			procs = atoi(&pdevbuf[17]);
 		else
 		else
@@ -534,6 +539,9 @@ bool bitforce_detect_oneof(const char * const devpath, struct bitforce_lowl_inte
 		if (!strncasecmp(pdevbuf, "Scan Interval:", 14))
 		if (!strncasecmp(pdevbuf, "Scan Interval:", 14))
 			initdata->scan_interval_ms = atoi(&pdevbuf[14]);
 			initdata->scan_interval_ms = atoi(&pdevbuf[14]);
 		else
 		else
+		if (!strncasecmp(pdevbuf, "Max Queue ID:", 13))
+			initdata->max_queueid = strtol(&pdevbuf[13], NULL, 0x10);
+		else
 		if (!strncasecmp(pdevbuf, "MANUFACTURER:", 13))
 		if (!strncasecmp(pdevbuf, "MANUFACTURER:", 13))
 		{
 		{
 			manuf = &pdevbuf[13];
 			manuf = &pdevbuf[13];
@@ -1546,6 +1554,7 @@ static bool bitforce_thread_init(struct thr_info *thr)
 			.sleep_ms_default = BITFORCE_SLEEP_MS,
 			.sleep_ms_default = BITFORCE_SLEEP_MS,
 			.parallel = abs(initdata->parallels[boardno]),
 			.parallel = abs(initdata->parallels[boardno]),
 			.parallel_protocol = (initdata->parallels[boardno] != -1),
 			.parallel_protocol = (initdata->parallels[boardno] != -1),
+			.max_queueid = initdata->max_queueid,
 		};
 		};
 		thr->cgpu_data = procdata = malloc(sizeof(*procdata));
 		thr->cgpu_data = procdata = malloc(sizeof(*procdata));
 		*procdata = (struct bitforce_proc_data){
 		*procdata = (struct bitforce_proc_data){
@@ -1951,7 +1960,27 @@ retry:
 	if (data->missing_zwx)
 	if (data->missing_zwx)
 		queued_ok = 1;
 		queued_ok = 1;
 	else
 	else
-		queued_ok = atoi(&buf[9]);
+	{
+		char *p;
+		queued_ok = strtol(&buf[9], &p, 0);
+		if (data->max_queueid)
+		{
+			if (unlikely(p[0] != ':'))
+				applog(LOG_ERR, "%"PRIpreprv": Successfully queued %d/%d jobs, but no queue ids returned (queued<=%d)", bitforce->proc_repr, queued_ok, data->ready_to_queue, data->queued + queued_ok);
+			else
+			{
+				// NOTE: work is set to just-before the first item from the build-command loop earlier
+				// NOTE: This ugly statement ends up with the first work item queued
+				work = work ? (work->next ?: work) : thr->work_list;
+				for (int i = data->ready_to_queue; i > 0; --i, (work = work->next))
+				{
+					work->device_id = strtol(&p[1], &p, 0x10);
+					if (unlikely(!p[0]))
+						--p;
+				}
+			}
+		}
+	}
 	data->queued += queued_ok;
 	data->queued += queued_ok;
 	applog(LOG_DEBUG, "%"PRIpreprv": Successfully queued %d/%d jobs on device (queued<=%d)",
 	applog(LOG_DEBUG, "%"PRIpreprv": Successfully queued %d/%d jobs on device (queued<=%d)",
 	       bitforce->proc_repr,
 	       bitforce->proc_repr,
@@ -2016,27 +2045,39 @@ again:
 		if ( (noncebuf = next_line(buf)) )
 		if ( (noncebuf = next_line(buf)) )
 			noncebuf[-1] = '\0';
 			noncebuf[-1] = '\0';
 		
 		
-		if (strlen(buf) <= 90)
+		if (data->max_queueid)
 		{
 		{
-			applog(LOG_ERR, "%"PRIpreprv": Gibberish within queue results: %s", bitforce->proc_repr, buf);
-			continue;
+			const work_device_id_t queueid = strtol(buf, &end, 0x10);
+			if (unlikely(!end[0]))
+				goto gibberish;
+			DL_SEARCH_SCALAR(thr->work_list, thiswork, device_id, queueid);
 		}
 		}
-		
-		hex2bin(midstate, buf, 32);
-		hex2bin(datatail, &buf[65], 12);
-		
-		thiswork = NULL;
-		DL_FOREACH(thr->work_list, work)
+		else
 		{
 		{
-			if (unlikely(memcmp(work->midstate, midstate, 32)))
-				continue;
-			if (unlikely(memcmp(&work->data[64], datatail, 12)))
+			if (strlen(buf) <= 90)
+			{
+gibberish:
+				applog(LOG_ERR, "%"PRIpreprv": Gibberish within queue results: %s", bitforce->proc_repr, buf);
 				continue;
 				continue;
-			thiswork = work;
-			break;
+			}
+			
+			hex2bin(midstate, buf, 32);
+			hex2bin(datatail, &buf[65], 12);
+			
+			thiswork = NULL;
+			DL_FOREACH(thr->work_list, work)
+			{
+				if (unlikely(memcmp(work->midstate, midstate, 32)))
+					continue;
+				if (unlikely(memcmp(&work->data[64], datatail, 12)))
+					continue;
+				thiswork = work;
+				break;
+			}
+			
+			end = &buf[89];
 		}
 		}
 		
 		
-		end = &buf[89];
 		chip_cgpu = bitforce;
 		chip_cgpu = bitforce;
 		if (data->parallel_protocol)
 		if (data->parallel_protocol)
 		{
 		{
@@ -2072,7 +2113,7 @@ again:
 				applog(LOG_ERR, "%"PRIpreprv": Missing nonces in queue results: %s", chip_cgpu->proc_repr, buf);
 				applog(LOG_ERR, "%"PRIpreprv": Missing nonces in queue results: %s", chip_cgpu->proc_repr, buf);
 				goto finishresult;
 				goto finishresult;
 			}
 			}
-			bitforce_process_result_nonces(chip_thr, work, &end[1]);
+			bitforce_process_result_nonces(chip_thr, thiswork, &end[1]);
 		}
 		}
 		++fcount;
 		++fcount;
 		++counts[chipno];
 		++counts[chipno];
@@ -2250,19 +2291,30 @@ void bitforce_queue_flush(struct thr_info *thr)
 	// "ZqX" returns jobs in progress, allowing us to sanity check
 	// "ZqX" returns jobs in progress, allowing us to sanity check
 	// NOTE: Must process buffer into hash table BEFORE calling bitforce_queue_do_results, which clobbers it
 	// NOTE: Must process buffer into hash table BEFORE calling bitforce_queue_do_results, which clobbers it
 	// NOTE: Must do actual sanity check AFTER calling bitforce_queue_do_results, to ensure we don't delete completed jobs
 	// NOTE: Must do actual sanity check AFTER calling bitforce_queue_do_results, to ensure we don't delete completed jobs
+	
+	const size_t keysz = data->max_queueid ? sizeof(work_device_id_t) : sizeof(this->key);
+	
 	if (buf2)
 	if (buf2)
 	{
 	{
 		// First, turn buf2 into a hash
 		// First, turn buf2 into a hash
 		for ( ; buf2[0]; buf2 = next_line(buf2))
 		for ( ; buf2[0]; buf2 = next_line(buf2))
 		{
 		{
 			this = malloc(sizeof(*this));
 			this = malloc(sizeof(*this));
-			hex2bin(&this->key[ 0], &buf2[ 0], 32);
-			hex2bin(&this->key[32], &buf2[65], 12);
-			HASH_FIND(hh, processing, &this->key[0], sizeof(this->key), item);
+			if (data->max_queueid)
+			{
+				const work_device_id_t queueid = strtol(buf2, NULL, 0x10);
+				memcpy(&this->key[0], &queueid, sizeof(queueid));
+			}
+			else
+			{
+				hex2bin(&this->key[ 0], &buf2[ 0], 32);
+				hex2bin(&this->key[32], &buf2[65], 12);
+			}
+			HASH_FIND(hh, processing, &this->key[0], keysz, item);
 			if (likely(!item))
 			if (likely(!item))
 			{
 			{
 				this->instances = 1;
 				this->instances = 1;
-				HASH_ADD(hh, processing, key, sizeof(this->key), this);
+				HASH_ADD(hh, processing, key, keysz, this);
 			}
 			}
 			else
 			else
 			{
 			{
@@ -2283,9 +2335,14 @@ void bitforce_queue_flush(struct thr_info *thr)
 		// Now iterate over the work_list and delete anything not in the hash
 		// Now iterate over the work_list and delete anything not in the hash
 		DL_FOREACH_SAFE(thr->work_list, work, tmp)
 		DL_FOREACH_SAFE(thr->work_list, work, tmp)
 		{
 		{
-			memcpy(&key[ 0],  work->midstate, 32);
-			memcpy(&key[32], &work->data[64], 12);
-			HASH_FIND(hh, processing, &key[0], sizeof(key), item);
+			if (data->max_queueid)
+				memcpy(&key[0], &work->device_id, sizeof(work->device_id));
+			else
+			{
+				memcpy(&key[ 0],  work->midstate, 32);
+				memcpy(&key[32], &work->data[64], 12);
+			}
+			HASH_FIND(hh, processing, &key[0], keysz, item);
 			if (unlikely(!item))
 			if (unlikely(!item))
 			{
 			{
 				char hex[89];
 				char hex[89];