Browse Source

Use only one cgsem in avalon signalling when the write thread should commit work by reading the status bytes off during an avalon_read, minimising the number of usb calls and resetting from only one place.

nfactor-troky
Con Kolivas 12 years ago
parent
commit
581afcf9ab
  1. 34
      driver-avalon.c
  2. 1
      driver-avalon.h

34
driver-avalon.c

@ -233,9 +233,17 @@ static void wait_avalon_ready(struct cgpu_info *avalon)
} }
} }
#define AVALON_CTS (1 << 4)
static inline bool avalon_cts(char c)
{
return (c & AVALON_CTS);
}
static int avalon_read(struct cgpu_info *avalon, unsigned char *buf, static int avalon_read(struct cgpu_info *avalon, unsigned char *buf,
size_t bufsize, int timeout, int ep) size_t bufsize, int timeout, int ep)
{ {
struct avalon_info *info = avalon->device_data;
size_t total = 0, readsize = bufsize + 2; size_t total = 0, readsize = bufsize + 2;
char readbuf[AVALON_READBUF_SIZE]; char readbuf[AVALON_READBUF_SIZE];
int err, amount, ofs = 2, cp; int err, amount, ofs = 2, cp;
@ -244,6 +252,15 @@ static int avalon_read(struct cgpu_info *avalon, unsigned char *buf,
applog(LOG_DEBUG, "%s%i: Get avalon read got err %d", applog(LOG_DEBUG, "%s%i: Get avalon read got err %d",
avalon->drv->name, avalon->device_id, err); avalon->drv->name, avalon->device_id, err);
if (amount < 2)
goto out;
/* Use the fact that we're reading the status with the buffer to tell
* the write thread it should send more work without needing to call
* avalon_buffer_full directly. */
if (avalon_cts(buf[0]))
cgsem_post(&info->write_sem);
/* The first 2 of every 64 bytes are status on FTDIRL */ /* The first 2 of every 64 bytes are status on FTDIRL */
while (amount > 2) { while (amount > 2) {
cp = amount - 2; cp = amount - 2;
@ -254,6 +271,7 @@ static int avalon_read(struct cgpu_info *avalon, unsigned char *buf,
amount -= cp + 2; amount -= cp + 2;
ofs += 64; ofs += 64;
} }
out:
return total; return total;
} }
@ -762,10 +780,7 @@ static void *avalon_get_results(void *userdata)
} }
if (unlikely(info->reset)) { if (unlikely(info->reset)) {
/* Tell the write thread it can start the reset */ avalon_running_reset(avalon, info);
cgsem_post(&info->write_sem);
cgsem_wait(&info->read_sem);
/* Discard anything in the buffer */ /* Discard anything in the buffer */
offset = 0; offset = 0;
} }
@ -823,15 +838,8 @@ static void *avalon_send_tasks(void *userdata)
struct avalon_task at; struct avalon_task at;
int idled = 0; int idled = 0;
wait_avalon_ready(avalon); while (avalon_buffer_full(avalon))
if (unlikely(info->reset)) {
/* Wait till read thread tells us it's received the
* reset message */
cgsem_wait(&info->write_sem); cgsem_wait(&info->write_sem);
avalon_running_reset(avalon, info);
cgsem_post(&info->read_sem);
}
mutex_lock(&info->qlock); mutex_lock(&info->qlock);
start_count = avalon->work_array * avalon_get_work_count; start_count = avalon->work_array * avalon_get_work_count;
@ -898,7 +906,6 @@ static bool avalon_prepare(struct thr_info *thr)
mutex_init(&info->qlock); mutex_init(&info->qlock);
if (unlikely(pthread_cond_init(&info->qcond, NULL))) if (unlikely(pthread_cond_init(&info->qcond, NULL)))
quit(1, "Failed to pthread_cond_init avalon qcond"); quit(1, "Failed to pthread_cond_init avalon qcond");
cgsem_init(&info->read_sem);
cgsem_init(&info->write_sem); cgsem_init(&info->write_sem);
if (pthread_create(&info->read_thr, NULL, avalon_get_results, (void *)avalon)) if (pthread_create(&info->read_thr, NULL, avalon_get_results, (void *)avalon))
@ -925,7 +932,6 @@ static void do_avalon_close(struct thr_info *thr)
info->no_matching_work = 0; info->no_matching_work = 0;
cgsem_destroy(&info->read_sem);
cgsem_destroy(&info->write_sem); cgsem_destroy(&info->write_sem);
} }

1
driver-avalon.h

@ -111,7 +111,6 @@ struct avalon_info {
pthread_mutex_t lock; pthread_mutex_t lock;
pthread_mutex_t qlock; pthread_mutex_t qlock;
pthread_cond_t qcond; pthread_cond_t qcond;
cgsem_t read_sem;
cgsem_t write_sem; cgsem_t write_sem;
int nonces; int nonces;

Loading…
Cancel
Save