From 1291f5a4072e6332337c0c1c519dab0f3793ae53 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 21 Apr 2012 10:20:21 -0400 Subject: [PATCH 1/3] Icarus: Use epoll (where available) to get nonces ASAP --- configure.ac | 2 ++ driver-icarus.c | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 4f7ed9ac..2be6eefd 100644 --- a/configure.ac +++ b/configure.ac @@ -301,6 +301,8 @@ if test "x$bitforce" != xno; then fi AM_CONDITIONAL([HAVE_LIBUDEV], [test x$libudev != xno]) +AC_CHECK_HEADERS([sys/epoll.h]) + PKG_PROG_PKG_CONFIG() PKG_CHECK_MODULES([LIBCURL], [libcurl >= 7.15.6], [AC_DEFINE([CURL_HAS_SOCKOPT], [1], [Defined if version of curl supports sockopts.])], diff --git a/driver-icarus.c b/driver-icarus.c index 4aab784a..8ec76eb5 100644 --- a/driver-icarus.c +++ b/driver-icarus.c @@ -46,10 +46,16 @@ #include #include #endif +#ifdef HAVE_SYS_EPOLL_H + #include + #define HAVE_EPOLL +#endif #include "elist.h" #include "miner.h" +// 8 second timeout +#define ICARUS_READ_FAULT_DECISECONDS (10) #define ICARUS_READ_FAULT_COUNT (8) struct device_api icarus_api; @@ -87,7 +93,7 @@ static int icarus_open(const char *devpath) ISTRIP | INLCR | IGNCR | ICRNL | IXON); my_termios.c_oflag &= ~OPOST; my_termios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); - my_termios.c_cc[VTIME] = 10; /* block 1 second */ + my_termios.c_cc[VTIME] = ICARUS_READ_FAULT_DECISECONDS; my_termios.c_cc[VMIN] = 0; tcsetattr(serialfd, TCSANOW, &my_termios); @@ -112,8 +118,27 @@ static int icarus_gets(unsigned char *buf, size_t bufLen, int fd) { ssize_t ret = 0; int rc = 0; + int epollfd = -1; + +#ifdef HAVE_EPOLL + struct epoll_event ev, evr; + epollfd = epoll_create(1); + if (epollfd != -1) { + ev.events = EPOLLIN; + ev.data.fd = fd; + if (-1 == epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev)) { + close(epollfd); + epollfd = -1; + } + } +#endif while (bufLen) { +#ifdef HAVE_EPOLL + if (epollfd != -1 && epoll_wait(epollfd, &evr, 1, ICARUS_READ_FAULT_DECISECONDS * 100) != 1) + ret = 0; + else +#endif ret = read(fd, buf, 1); if (ret == 1) { bufLen--; @@ -123,12 +148,17 @@ static int icarus_gets(unsigned char *buf, size_t bufLen, int fd) rc++; if (rc == ICARUS_READ_FAULT_COUNT) { + if (epollfd != -1) + close(epollfd); applog(LOG_DEBUG, - "Icarus Read: No data in %d seconds", rc); + "Icarus Read: No data in %d seconds", rc * ICARUS_READ_FAULT_DECISECONDS / 10); return 1; } } + if (epollfd != -1) + close(epollfd); + return 0; } From 34f86417cc2e2b9c53712cf3caa5a316031f03c8 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 21 Apr 2012 10:53:34 -0400 Subject: [PATCH 2/3] Icarus: Abandon a scanhash early when work restart requested --- driver-icarus.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/driver-icarus.c b/driver-icarus.c index 8ec76eb5..78e91290 100644 --- a/driver-icarus.c +++ b/driver-icarus.c @@ -55,8 +55,8 @@ #include "miner.h" // 8 second timeout -#define ICARUS_READ_FAULT_DECISECONDS (10) -#define ICARUS_READ_FAULT_COUNT (8) +#define ICARUS_READ_FAULT_DECISECONDS (1) +#define ICARUS_READ_FAULT_COUNT (80) struct device_api icarus_api; @@ -114,7 +114,7 @@ static int icarus_open(const char *devpath) #endif } -static int icarus_gets(unsigned char *buf, size_t bufLen, int fd) +static int icarus_gets(unsigned char *buf, size_t bufLen, int fd, volatile unsigned long *wr) { ssize_t ret = 0; int rc = 0; @@ -147,6 +147,8 @@ static int icarus_gets(unsigned char *buf, size_t bufLen, int fd) } rc++; + if (*wr) + return 1; if (rc == ICARUS_READ_FAULT_COUNT) { if (epollfd != -1) close(epollfd); @@ -202,7 +204,8 @@ static bool icarus_detect_one(const char *devpath) icarus_write(fd, ob_bin, sizeof(ob_bin)); memset(nonce_bin, 0, sizeof(nonce_bin)); - icarus_gets(nonce_bin, sizeof(nonce_bin), fd); + volatile unsigned long wr = 0; + icarus_gets(nonce_bin, sizeof(nonce_bin), fd, &wr); icarus_close(fd); @@ -273,6 +276,9 @@ static bool icarus_prepare(struct thr_info *thr) static uint64_t icarus_scanhash(struct thr_info *thr, struct work *work, __maybe_unused uint64_t max_nonce) { + volatile unsigned long *wr = &work_restart[thr->id].restart; + *wr = 0; + struct cgpu_info *icarus; int fd; int ret; @@ -308,7 +314,7 @@ static uint64_t icarus_scanhash(struct thr_info *thr, struct work *work, /* Icarus will return 8 bytes nonces or nothing */ memset(nonce_bin, 0, sizeof(nonce_bin)); - ret = icarus_gets(nonce_bin, sizeof(nonce_bin), fd); + ret = icarus_gets(nonce_bin, sizeof(nonce_bin), fd, wr); nonce_hex = bin2hex(nonce_bin, sizeof(nonce_bin)); if (nonce_hex) { From d8ef28069a0b82a8d931122d0403f245c7a3e021 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 21 Apr 2012 20:00:05 -0400 Subject: [PATCH 3/3] work_restart should only be changed by cgminer.c now --- driver-icarus.c | 1 - sha256_4way.c | 2 -- sha256_altivec_4way.c | 2 -- sha256_cryptopp.c | 2 -- sha256_generic.c | 2 -- sha256_sse2_amd64.c | 2 -- sha256_sse2_i386.c | 2 -- sha256_sse4_amd64.c | 2 -- sha256_via.c | 2 -- 9 files changed, 17 deletions(-) diff --git a/driver-icarus.c b/driver-icarus.c index 78e91290..12b70e62 100644 --- a/driver-icarus.c +++ b/driver-icarus.c @@ -277,7 +277,6 @@ static uint64_t icarus_scanhash(struct thr_info *thr, struct work *work, __maybe_unused uint64_t max_nonce) { volatile unsigned long *wr = &work_restart[thr->id].restart; - *wr = 0; struct cgpu_info *icarus; int fd; diff --git a/sha256_4way.c b/sha256_4way.c index 27293d2a..35116a68 100644 --- a/sha256_4way.c +++ b/sha256_4way.c @@ -111,8 +111,6 @@ bool ScanHash_4WaySSE2(int thr_id, const unsigned char *pmidstate, pdata += 64; - work_restart[thr_id].restart = 0; - for (;;) { unsigned int thash[9][NPAR] __attribute__((aligned(128))); diff --git a/sha256_altivec_4way.c b/sha256_altivec_4way.c index 43a96b2b..cb3351c7 100644 --- a/sha256_altivec_4way.c +++ b/sha256_altivec_4way.c @@ -84,8 +84,6 @@ bool ScanHash_altivec_4way(int thr_id, const unsigned char *pmidstate, pdata += 64; - work_restart[thr_id].restart = 0; - for (;;) { unsigned int thash[9][NPAR] __attribute__((aligned(128))); diff --git a/sha256_cryptopp.c b/sha256_cryptopp.c index 11c1c5ca..aab8bba8 100644 --- a/sha256_cryptopp.c +++ b/sha256_cryptopp.c @@ -589,8 +589,6 @@ bool scanhash_asm32(int thr_id, const unsigned char *midstate, data += 64; - work_restart[thr_id].restart = 0; - while (1) { n++; *nonce = n; diff --git a/sha256_generic.c b/sha256_generic.c index 05f4c376..95591fe4 100644 --- a/sha256_generic.c +++ b/sha256_generic.c @@ -251,8 +251,6 @@ bool scanhash_c(int thr_id, const unsigned char *midstate, unsigned char *data, data += 64; - work_restart[thr_id].restart = 0; - while (1) { n++; *nonce = n; diff --git a/sha256_sse2_amd64.c b/sha256_sse2_amd64.c index ad1f45dc..a109e8a6 100644 --- a/sha256_sse2_amd64.c +++ b/sha256_sse2_amd64.c @@ -65,8 +65,6 @@ bool scanhash_sse2_64(int thr_id, const unsigned char *pmidstate, pdata += 64; - work_restart[thr_id].restart = 0; - /* For debugging */ union { __m128i m; diff --git a/sha256_sse2_i386.c b/sha256_sse2_i386.c index 3008e0d6..669781ad 100644 --- a/sha256_sse2_i386.c +++ b/sha256_sse2_i386.c @@ -65,8 +65,6 @@ bool scanhash_sse2_32(int thr_id, const unsigned char *pmidstate, pdata += 64; - work_restart[thr_id].restart = 0; - /* Message expansion */ memcpy(m_midstate, pmidstate, sizeof(m_midstate)); memcpy(m_w, pdata, sizeof(m_w)); /* The 2nd half of the data */ diff --git a/sha256_sse4_amd64.c b/sha256_sse4_amd64.c index 172da2bb..a9cd685d 100644 --- a/sha256_sse4_amd64.c +++ b/sha256_sse4_amd64.c @@ -62,8 +62,6 @@ bool scanhash_sse4_64(int thr_id, const unsigned char *pmidstate, pdata += 64; - work_restart[thr_id].restart = 0; - /* For debugging */ union { __m128i m; diff --git a/sha256_via.c b/sha256_via.c index 2d7d7731..35f42620 100644 --- a/sha256_via.c +++ b/sha256_via.c @@ -35,8 +35,6 @@ bool scanhash_via(int thr_id, const unsigned char *pmidstate, unsigned long stat_ctr = 0; int i; - work_restart[thr_id].restart = 0; - /* bitcoin gives us big endian input, but via wants LE, * so we reverse the swapping bitcoin has already done (extra work) * in order to permit the hardware to swap everything