Create an array of 4 lots of work for avalon and cycle through them.
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
diff --git a/driver-avalon.c b/driver-avalon.c
index 69e78ef..5d4656d 100644
--- a/driver-avalon.c
+++ b/driver-avalon.c
@@ -645,7 +645,7 @@ static bool avalon_prepare(struct thr_info *thr)
struct avalon_info *info = avalon_infos[avalon->device_id];
struct timeval now;
- avalon->works = calloc(info->miner_count * sizeof(struct work *), 1);
+ avalon->works = calloc(info->miner_count * sizeof(struct work *), 4);
if (!avalon->works)
quit(1, "Failed to calloc avalon works in avalon_prepare");
__avalon_init(avalon);
@@ -669,7 +669,31 @@ static void avalon_free_work(struct thr_info *thr)
works = avalon->works;
info = avalon_infos[avalon->device_id];
- for (i = 0; i < info->miner_count; i++) {
+ for (i = 0; i < info->miner_count * 4; i++) {
+ if (works[i]) {
+ work_completed(avalon, works[i]);
+ works[i] = NULL;
+ }
+ }
+}
+
+static void avalon_free_work_array(struct thr_info *thr)
+{
+ struct cgpu_info *avalon;
+ struct work **works;
+ int i, j, mc, wa;
+
+ avalon = thr->cgpu;
+ avalon->queued = 0;
+ if (unlikely(!avalon->works))
+ return;
+ works = avalon->works;
+ mc = avalon_infos[avalon->device_id]->miner_count;
+ wa = avalon->work_array + 1;
+ if (wa > 3)
+ wa = 0;
+
+ for (i = wa * mc, j = 0; j < mc; i++, j++) {
if (likely(works[i])) {
work_completed(avalon, works[i]);
works[i] = NULL;
@@ -758,13 +782,14 @@ static inline void adjust_fan(struct avalon_info *info)
static bool avalon_fill(struct cgpu_info *avalon)
{
struct work *work = get_queued(avalon);
+ int mc = avalon_infos[avalon->device_id]->miner_count;
if (unlikely(!work))
return false;
- if (avalon->queued == avalon_infos[avalon->device_id]->miner_count)
+ if (avalon->queued >= mc)
return true;
- avalon->works[avalon->queued++] = work;
- if (avalon->queued == avalon_infos[avalon->device_id]->miner_count)
+ avalon->works[avalon->work_array * mc + avalon->queued++] = work;
+ if (avalon->queued >= mc)
return true;
return false;
}
@@ -780,6 +805,7 @@ static int64_t avalon_scanhash(struct thr_info *thr)
struct avalon_result ar;
int i;
int avalon_get_work_count;
+ int start_count, end_count;
struct timeval tv_start, tv_finish, elapsed;
uint32_t nonce;
@@ -806,7 +832,9 @@ static int64_t avalon_scanhash(struct thr_info *thr)
tcflush(fd, TCOFLUSH);
#endif
- i = 0;
+ start_count = avalon->work_array * avalon_get_work_count;
+ end_count = start_count + avalon_get_work_count;
+ i = start_count;
while (true) {
avalon_init_task(&at, 0, 0, info->fan_pwm,
info->timeout, info->asic_count,
@@ -815,7 +843,7 @@ static int64_t avalon_scanhash(struct thr_info *thr)
ret = avalon_send_task(fd, &at, avalon);
if (unlikely(ret == AVA_SEND_ERROR ||
(ret == AVA_SEND_BUFFER_EMPTY &&
- (i + 1 == avalon_get_work_count) &&
+ (i + 1 == end_count) &&
first_try))) {
do_avalon_close(thr);
applog(LOG_ERR, "AVA%i: Comms error(buffer)",
@@ -826,7 +854,7 @@ static int64_t avalon_scanhash(struct thr_info *thr)
avalon_init(avalon);
return 0; /* This should never happen */
}
- if (ret == AVA_SEND_BUFFER_EMPTY && (i + 1 == avalon_get_work_count)) {
+ if (ret == AVA_SEND_BUFFER_EMPTY && (i + 1 == end_count)) {
first_try = 1;
return 0xffffffff;
}
@@ -908,7 +936,9 @@ static int64_t avalon_scanhash(struct thr_info *thr)
return 0;
}
- avalon_free_work(thr);
+ avalon_free_work_array(thr);
+ if (++avalon->work_array > 3)
+ avalon->work_array = 0;
record_temp_fan(info, &ar, &(avalon->temp));
applog(LOG_INFO,
diff --git a/miner.h b/miner.h
index 819d242..754d5f8 100644
--- a/miner.h
+++ b/miner.h
@@ -429,6 +429,7 @@ struct cgpu_info {
};
#ifdef USE_AVALON
struct work **works;
+ int work_array;
int queued;
#endif
#ifdef USE_USBUTILS