Browse Source

Use select for a reliable timeout in avalon read and don't read 1 byte at a time, optimising read loop.

Con Kolivas 13 years ago
parent
commit
d013551862
1 changed files with 19 additions and 12 deletions
  1. 19 12
      driver-avalon.c

+ 19 - 12
driver-avalon.c

@@ -16,6 +16,7 @@
 #include <stdio.h>
 #include <stdio.h>
 #include <sys/time.h>
 #include <sys/time.h>
 #include <sys/types.h>
 #include <sys/types.h>
+#include <sys/select.h>
 #include <dirent.h>
 #include <dirent.h>
 #include <unistd.h>
 #include <unistd.h>
 #ifndef WIN32
 #ifndef WIN32
@@ -207,22 +208,28 @@ static int avalon_gets(int fd, uint8_t *buf, int read_count,
 	int read_amount = AVALON_READ_SIZE;
 	int read_amount = AVALON_READ_SIZE;
 	bool first = true;
 	bool first = true;
 
 
-	/* Read reply 1 byte at a time to get earliest tv_finish */
 	while (true) {
 	while (true) {
-		ret = read(fd, buf, 1);
-		if (ret < 0)
-			return AVA_GETS_ERROR;
-
-		if (first && tv_finish != NULL)
-			gettimeofday(tv_finish, NULL);
-
-		if (ret >= read_amount)
-			return AVA_GETS_OK;
+		struct timeval timeout = {0, 1000};
+		fd_set rd;
 
 
-		if (ret > 0) {
+		FD_ZERO(&rd);
+		FD_SET(fd, &rd);
+		ret = select(fd + 1, &rd, NULL, NULL, &timeout);
+		if (unlikely(ret < 0))
+			return AVA_GETS_ERROR;
+		if (ret) {
+			ret = read(fd, buf, read_amount);
+			if (unlikely(ret < 0))
+				return AVA_GETS_ERROR;
+			if (ret >= read_amount)
+				return AVA_GETS_OK;
+			if (first) {
+				if (tv_finish)
+					gettimeofday(tv_finish, NULL);
+				first = false;
+			}
 			buf += ret;
 			buf += ret;
 			read_amount -= ret;
 			read_amount -= ret;
-			first = false;
 			continue;
 			continue;
 		}
 		}