Commit 1291f5a4072e6332337c0c1c519dab0f3793ae53

Luke Dashjr 2012-04-21T10:20:21

Icarus: Use epoll (where available) to get nonces ASAP

diff --git a/configure.ac b/configure.ac
index 4f7ed9a..2be6eef 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 4aab784..8ec76eb 100644
--- a/driver-icarus.c
+++ b/driver-icarus.c
@@ -46,10 +46,16 @@
   #include <windows.h>
   #include <io.h>
 #endif
+#ifdef HAVE_SYS_EPOLL_H
+  #include <sys/epoll.h>
+  #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;
 }