Browse Source

Merge branch 'master' into nogpu

Con Kolivas 12 years ago
parent
commit
b0573a0791
5 changed files with 69 additions and 24 deletions
  1. 1 0
      README
  2. 24 1
      cgminer.c
  3. 41 20
      driver-bitfury.c
  4. 0 3
      driver-bitfury.h
  5. 3 0
      miner.h

+ 1 - 0
README

@@ -119,6 +119,7 @@ Basic *nix build instructions:
 
 
 	./autogen.sh	# only needed if building from git repo
 	./autogen.sh	# only needed if building from git repo
 	CFLAGS="-O2 -Wall -march=native" ./configure <options>
 	CFLAGS="-O2 -Wall -march=native" ./configure <options>
+	make
 
 
 	No installation is necessary. You may run cgminer from the build
 	No installation is necessary. You may run cgminer from the build
 	directory directly, but you may do make install if you wish to install
 	directory directly, but you may do make install if you wish to install

+ 24 - 1
cgminer.c

@@ -6233,6 +6233,13 @@ static void fill_queue(struct thr_info *mythr, struct cgpu_info *cgpu, struct de
 	} while (!drv->queue_full(cgpu));
 	} while (!drv->queue_full(cgpu));
 }
 }
 
 
+/* Add a work item to a cgpu's queued hashlist */
+void __add_queued(struct cgpu_info *cgpu, struct work *work)
+{
+	cgpu->queued_count++;
+	HASH_ADD_INT(cgpu->queued_work, id, work);
+}
+
 /* This function is for retrieving one work item from the unqueued pointer and
 /* This function is for retrieving one work item from the unqueued pointer and
  * adding it to the hashtable of queued work. Code using this function must be
  * adding it to the hashtable of queued work. Code using this function must be
  * able to handle NULL as a return which implies there is no work available. */
  * able to handle NULL as a return which implies there is no work available. */
@@ -6243,7 +6250,7 @@ struct work *get_queued(struct cgpu_info *cgpu)
 	wr_lock(&cgpu->qlock);
 	wr_lock(&cgpu->qlock);
 	if (cgpu->unqueued_work) {
 	if (cgpu->unqueued_work) {
 		work = cgpu->unqueued_work;
 		work = cgpu->unqueued_work;
-		HASH_ADD_INT(cgpu->queued_work, id, work);
+		__add_queued(cgpu, work);
 		cgpu->unqueued_work = NULL;
 		cgpu->unqueued_work = NULL;
 	}
 	}
 	wr_unlock(&cgpu->qlock);
 	wr_unlock(&cgpu->qlock);
@@ -6251,6 +6258,22 @@ struct work *get_queued(struct cgpu_info *cgpu)
 	return work;
 	return work;
 }
 }
 
 
+void add_queued(struct cgpu_info *cgpu, struct work *work)
+{
+	wr_lock(&cgpu->qlock);
+	__add_queued(cgpu, work);
+	wr_unlock(&cgpu->qlock);
+}
+
+/* Get fresh work and add it to cgpu's queued hashlist */
+struct work *get_queue_work(struct thr_info *thr, struct cgpu_info *cgpu, int thr_id)
+{
+	struct work *work = get_work(thr, thr_id);
+
+	add_queued(cgpu, work);
+	return work;
+}
+
 /* This function is for finding an already queued work item in the
 /* This function is for finding an already queued work item in the
  * given que hashtable. Code using this function must be able
  * given que hashtable. Code using this function must be able
  * to handle NULL as a return which implies there is no matching work.
  * to handle NULL as a return which implies there is no matching work.

+ 41 - 20
driver-bitfury.c

@@ -210,7 +210,9 @@ static bool bitfury_checkresults(struct thr_info *thr, struct work *work, uint32
 	int i;
 	int i;
 
 
 	for (i = 0; i < BT_OFFSETS; i++) {
 	for (i = 0; i < BT_OFFSETS; i++) {
-		if (test_nonce(work, nonce + bf_offsets[i])) {
+		uint32_t noffset = nonce + bf_offsets[i];
+
+		if (test_nonce(work, noffset)) {
 			submit_tested_work(thr, work);
 			submit_tested_work(thr, work);
 			return true;
 			return true;
 		}
 		}
@@ -222,18 +224,18 @@ static int64_t bitfury_scanwork(struct thr_info *thr)
 {
 {
 	struct cgpu_info *bitfury = thr->cgpu;
 	struct cgpu_info *bitfury = thr->cgpu;
 	struct bitfury_info *info = bitfury->device_data;
 	struct bitfury_info *info = bitfury->device_data;
+	struct work *work, *tmp;
+	int amount, i, aged = 0;
 	struct timeval tv_now;
 	struct timeval tv_now;
-	struct work *work;
 	double nonce_rate;
 	double nonce_rate;
 	int64_t ret = 0;
 	int64_t ret = 0;
-	int amount, i;
 	char buf[45];
 	char buf[45];
 	int ms_diff;
 	int ms_diff;
 
 
-	work = get_work(thr, thr->id);
+	work = get_queue_work(thr, bitfury, thr->id);
 	if (unlikely(thr->work_restart)) {
 	if (unlikely(thr->work_restart)) {
-		free_work(work);
-		return 0;
+		work_completed(bitfury, work);
+		goto out;
 	}
 	}
 
 
 	buf[0] = 'W';
 	buf[0] = 'W';
@@ -251,7 +253,7 @@ static int64_t bitfury_scanwork(struct thr_info *thr)
 	}
 	}
 
 
 	if (unlikely(thr->work_restart))
 	if (unlikely(thr->work_restart))
-		goto cascade;
+		goto out;
 
 
 	/* Now look for the bulk of the previous work results, they will come
 	/* Now look for the bulk of the previous work results, they will come
 	 * in a batch following the first data. */
 	 * in a batch following the first data. */
@@ -268,41 +270,60 @@ static int64_t bitfury_scanwork(struct thr_info *thr)
 	};
 	};
 
 
 	if (unlikely(thr->work_restart))
 	if (unlikely(thr->work_restart))
-		goto cascade;
+		goto out;
 
 
 	/* Send work */
 	/* Send work */
+	cgtime(&work->tv_work_start);
 	usb_write(bitfury, buf, 45, &amount, C_BF1_REQWORK);
 	usb_write(bitfury, buf, 45, &amount, C_BF1_REQWORK);
 	cgtime(&info->tv_start);
 	cgtime(&info->tv_start);
+
 	/* Get response acknowledging work */
 	/* Get response acknowledging work */
 	usb_read(bitfury, buf, BF1MSGSIZE, &amount, C_BF1_GETWORK);
 	usb_read(bitfury, buf, BF1MSGSIZE, &amount, C_BF1_GETWORK);
 
 
-	/* Only happens on startup */
-	if (unlikely(!info->prevwork[BF1ARRAY_SIZE]))
-		goto cascade;
-
 	/* Search for what work the nonce matches in order of likelihood. Last
 	/* Search for what work the nonce matches in order of likelihood. Last
 	 * entry is end of result marker. */
 	 * entry is end of result marker. */
 	for (i = 0; i < info->tot - BF1MSGSIZE; i += BF1MSGSIZE) {
 	for (i = 0; i < info->tot - BF1MSGSIZE; i += BF1MSGSIZE) {
+		bool found = false;
 		uint32_t nonce;
 		uint32_t nonce;
-		int j;
 
 
 		/* Ignore state & switched data in results for now. */
 		/* Ignore state & switched data in results for now. */
 		memcpy(&nonce, info->buf + i + 3, 4);
 		memcpy(&nonce, info->buf + i + 3, 4);
 		nonce = decnonce(nonce);
 		nonce = decnonce(nonce);
-		for (j = 0; j < BF1ARRAY_SIZE; j++) {
-			if (bitfury_checkresults(thr, info->prevwork[j], nonce)) {
+
+		rd_lock(&bitfury->qlock);
+		HASH_ITER(hh, bitfury->queued_work, work, tmp) {
+			if (bitfury_checkresults(thr, work, nonce)) {
 				info->nonces++;
 				info->nonces++;
+				found = true;
 				break;
 				break;
 			}
 			}
 		}
 		}
+		rd_unlock(&bitfury->qlock);
+
+		if (!found)
+			inc_hw_errors(thr);
 	}
 	}
 
 
 	info->tot = 0;
 	info->tot = 0;
-	free_work(info->prevwork[BF1ARRAY_SIZE]);
-cascade:
-	for (i = BF1ARRAY_SIZE; i > 0; i--)
-		info->prevwork[i] = info->prevwork[i - 1];
-	info->prevwork[0] = work;
+out:
+	cgtime(&tv_now);
+
+	/* This iterates over the hashlist finding work started more than 6
+	 * seconds ago which equates to leaving 5 past work items in the array
+	 * to look for results. */
+	wr_lock(&bitfury->qlock);
+	HASH_ITER(hh, bitfury->queued_work, work, tmp) {
+		if (tdiff(&tv_now, &work->tv_work_start) > 6.0) {
+			__work_completed(bitfury, work);
+			aged++;
+		}
+	}
+	wr_unlock(&bitfury->qlock);
+
+	if (aged) {
+		applog(LOG_DEBUG, "%s %d: Aged %d work items", bitfury->drv->name,
+		       bitfury->device_id, aged);
+	}
 
 
 	info->cycles++;
 	info->cycles++;
 	info->total_nonces += info->nonces;
 	info->total_nonces += info->nonces;

+ 0 - 3
driver-bitfury.h

@@ -13,14 +13,11 @@
 #include "miner.h"
 #include "miner.h"
 #include "usbutils.h"
 #include "usbutils.h"
 
 
-#define BF1ARRAY_SIZE 2
-
 struct bitfury_info {
 struct bitfury_info {
 	struct cgpu_info *base_cgpu;
 	struct cgpu_info *base_cgpu;
 	uint8_t version;
 	uint8_t version;
 	char product[8];
 	char product[8];
 	uint32_t serial;
 	uint32_t serial;
-	struct work *prevwork[BF1ARRAY_SIZE + 1];
 	char buf[512];
 	char buf[512];
 	int tot;
 	int tot;
 	int nonces;
 	int nonces;

+ 3 - 0
miner.h

@@ -1435,7 +1435,10 @@ 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,
 extern bool submit_noffset_nonce(struct thr_info *thr, struct work *work, uint32_t nonce,
 			  int noffset);
 			  int noffset);
 extern struct work *get_work(struct thr_info *thr, const int thr_id);
 extern struct work *get_work(struct thr_info *thr, const int thr_id);
+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 struct work *get_queue_work(struct thr_info *thr, struct cgpu_info *cgpu, int thr_id);
 extern struct work *__find_work_bymidstate(struct work *que, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
 extern struct work *__find_work_bymidstate(struct work *que, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
 extern struct work *find_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
 extern struct work *find_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
 extern struct work *clone_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
 extern struct work *clone_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);