Reorder drillbit_scanwork to prioritise sending work over receiving results
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
diff --git a/driver-drillbit.c b/driver-drillbit.c
index ef120cd..4eebe09 100644
--- a/driver-drillbit.c
+++ b/driver-drillbit.c
@@ -549,6 +549,9 @@ static int check_for_results(struct thr_info *thr)
uint8_t buf[SZ_SERIALISED_WORKRESULT];
WorkResult response;
+ if (unlikely(thr->work_restart))
+ return 0;
+
successful_results = 0;
// Send request for completed work
@@ -560,11 +563,15 @@ static int check_for_results(struct thr_info *thr)
drvlog(LOG_ERR, "Got no response to request for work results");
return false;
}
+ if(unlikely(drillbit->usbinfo.nodev))
+ return 0;
if(result_count)
drvlog(LOG_DEBUG, "Result count %d",result_count);
// Receive work results (0 or more)
for(j = 0; j < result_count; j++) {
+ if(unlikely(drillbit->usbinfo.nodev))
+ return 0;
if(!usb_read_fixed_size(drillbit, buf, SZ_SERIALISED_WORKRESULT, TIMEOUT, C_BF_GETRES)) {
drvlog(LOG_ERR, "Failed to read response data packet idx %d count 0x%x", j, result_count);
@@ -584,6 +591,8 @@ static int check_for_results(struct thr_info *thr)
drvlog(LOG_WARNING, "Got spurious work results for idle ASIC %d", response.chip_id);
}
for(i = 0; i < response.num_nonces; i++) {
+ if (unlikely(thr->work_restart))
+ continue;
found = false;
for(k = 0; k < WORK_HISTORY_LEN; k++) {
if (chip->current_work[k] && drillbit_checkresults(thr, chip->current_work[k], response.nonce[i])) {
@@ -609,52 +618,19 @@ cleanup:
return successful_results;
}
-static int64_t drillbit_scanwork(struct thr_info *thr)
+static void drillbit_send_work_to_chip(struct thr_info *thr, struct drillbit_chip_info *chip)
{
struct cgpu_info *drillbit = thr->cgpu;
- struct drillbit_info *info = drillbit->device_data;
struct work *work;
- struct drillbit_chip_info *chip = NULL;
- struct timeval tv_now, tv_start;
- int amount, i, j;
- int ms_diff;
uint8_t cmd;
- int result_count;
- uint8_t buf[200]; // also larger than SZ_SERIALISED_WORKREQUEST
- char *tmp;
-
- // check for outstanding results
- result_count = check_for_results(thr);
- for(i = 0; i < info->num_chips; i++) {
- if(info->chips[i].state != WORKING_QUEUED) {
- chip = &info->chips[i];
- break;
- }
- }
-
- // check for any chips that have timed out on sending results
- cgtime(&tv_now);
- for(i = 0; i < info->num_chips; i++) {
- if(info->chips[i].state == IDLE)
- continue;
- ms_diff = ms_tdiff(&tv_now, &info->chips[i].tv_start);
- if(ms_diff > TIMEOUT) {
- drvlog(LOG_ERR, "Timing out unresponsive ASIC %d", info->chips[i].chip_id);
- info->chips[i].state = IDLE;
- info->chips[i].timeout_count++;
- chip = &info->chips[i];
- }
- }
-
- if(chip == NULL) { // nothing available to send work to!
- goto cascade;
- }
+ uint8_t buf[SZ_SERIALISED_WORKREQUEST];
+ int amount, i;
/* Get some new work for the chip */
work = get_queue_work(thr, drillbit, thr->id);
if (unlikely(thr->work_restart)) {
work_completed(drillbit, work);
- goto cascade;
+ return;
}
drvlog(LOG_DEBUG, "Sending work to chip_id %d", chip->chip_id);
@@ -666,7 +642,7 @@ static int64_t drillbit_scanwork(struct thr_info *thr)
usb_write(drillbit, buf, SZ_SERIALISED_WORKREQUEST, &amount, C_BF_REQWORK);
if (unlikely(thr->work_restart))
- goto cascade;
+ return;
/* Expect a single 'W' byte as acknowledgement */
usb_read_simple_response(drillbit, 'W', C_BF_REQWORK);
@@ -682,6 +658,47 @@ static int64_t drillbit_scanwork(struct thr_info *thr)
chip->current_work[i] = chip->current_work[i+1];
chip->current_work[WORK_HISTORY_LEN-1] = copy_work(work);
cgtime(&chip->tv_start);
+}
+
+static int64_t drillbit_scanwork(struct thr_info *thr)
+{
+ struct cgpu_info *drillbit = thr->cgpu;
+ struct drillbit_info *info = drillbit->device_data;
+ struct drillbit_chip_info *chip;
+ struct timeval tv_now, tv_start;
+ int amount, i, j;
+ int ms_diff;
+ int result_count = 0;
+ uint8_t buf[200];
+ char *tmp;
+
+ /* send work to an any chip without queued work */
+ for(i = 0; i < info->num_chips; i++) {
+ if(info->chips[i].state != WORKING_QUEUED) {
+ drillbit_send_work_to_chip(thr, &info->chips[i]);
+ }
+ if (unlikely(thr->work_restart) || unlikely(drillbit->usbinfo.nodev))
+ goto cascade;
+ }
+
+ /* check for any chips that have timed out on sending results */
+ cgtime(&tv_now);
+ for(i = 0; i < info->num_chips; i++) {
+ if(info->chips[i].state == IDLE)
+ continue;
+ ms_diff = ms_tdiff(&tv_now, &info->chips[i].tv_start);
+ if(ms_diff > TIMEOUT) {
+ drvlog(LOG_ERR, "Timing out unresponsive ASIC %d", info->chips[i].chip_id);
+ info->chips[i].state = IDLE;
+ info->chips[i].timeout_count++;
+ drillbit_send_work_to_chip(thr, &info->chips[i]);
+ }
+ if (unlikely(thr->work_restart) || unlikely(drillbit->usbinfo.nodev))
+ goto cascade;
+ }
+
+ /* Check for results */
+ result_count = check_for_results(thr);
/* Print a per-chip info line every 30 seconds */
cgtime(&tv_now);