[sane-devel] Patch to wait loop in sanei_pio.c
Toby Dickenson
toby@tarind.com
Sun, 15 May 2005 21:52:04 +0100
--Boundary-00=_0Z7hC4LPKExNxs1
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Attached is a patch which improves the sanei_pio wait loop with my Epson
GT-5000.
Firstly, sanei_pio currently waits indefinitely in a busy loop if the scanner
is switched off. There is a loop-counter limit implemented, but never
enabled. This patch replaces that with a timeout based on time(). It now
nicely returns with an error message if the printer is switched off.
Currently the timeout is fixed at 10 seconds..... I guess that should be
slow enough for any scanner.
Secondly, this patch reduces cpu usage by using small sleeps. Previously the
busy loop would use 100% cpu during scanning.
The check for timeout and sleep are only made after 1000 cycles of the wait
loop. Most of the time the loop doesnt get that far, so overall performance
is unaffected. Ive been testing this using
time scanimage -t 100 -y 50 --mode Color --resolution 200 > /tmp/a.pnm
real time is unchanged at 43 seconds, user time reduced 32%, from 39 to 26
seconds.
Thanks,
--Boundary-00=_0Z7hC4LPKExNxs1
Content-Type: text/x-diff;
charset="us-ascii";
name="pio_loop.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="pio_loop.diff"
--- sane-backends-1.0.15.original/sanei/sanei_pio.c 2003-09-09 16:04:45.000000000 +0100
+++ sane-backends-1.0.15/sanei/sanei_pio.c 2005-05-15 21:30:04.000000000 +0100
@@ -102,4 +102,5 @@
#include <sys/wait.h>
#include <unistd.h>
+#include <time.h>
#include "sane/saneopts.h"
@@ -146,5 +147,5 @@
u_long base; /* i/o base address */
int fd; /* >= 0 when using /dev/port */
- int max_polls; /* forever if <= 0 */
+ int max_time_seconds; /* forever if <= 0 */
u_int in_use; /* port in use? */
}
@@ -205,5 +206,7 @@
pio_wait (const Port port, u_char val, u_char mask)
{
- int n, stat = 0;
+ int stat = 0;
+ long poll_count = 0;
+ time_t start = time(NULL);
DBG (DL60, "wait on port 0x%03lx for %02x mask %02x\n",
@@ -215,10 +218,11 @@
: "-");
- for (n = 1; (port->max_polls <= 0) || (n <= port->max_polls); n++)
+ for (;;)
{
+ ++poll_count;
stat = inb (port->base + PIO_STAT);
if ((stat & mask) == (val & mask))
{
- DBG (DL60, "got %02x after %d tries\n", stat, n);
+ DBG (DL60, "got %02x after %ld tries\n", stat, poll_count);
DBG (DL61, " BUSY %s\n", stat & PIO_STAT_BUSY ? "on" : "off");
DBG (DL61, " NACKNLG %s\n",
@@ -227,6 +231,12 @@
return stat;
}
+ if(poll_count>1000)
+ {
+ if ((port->max_time_seconds>0) && (time(NULL)-start >= port->max_time_seconds) )
+ break;
+ usleep(1);
+ }
}
- DBG (DL60, "got %02x aborting after %d\n", stat, port->max_polls);
+ DBG (DL60, "got %02x aborting after %ld\n", stat, poll_count);
DBG (DL61, " BUSY %s\n", stat & PIO_STAT_BUSY ? "on" : "off");
DBG (DL61, " NACKNLG %s\n", stat & PIO_STAT_NACKNLG ? "on" : "off");
@@ -451,5 +461,5 @@
port[n].base = base;
port[n].fd = -1;
- port[n].max_polls = 0;
+ port[n].max_time_seconds = 10;
port[n].in_use = 1;
--Boundary-00=_0Z7hC4LPKExNxs1--