aboutsummaryrefslogtreecommitdiff
path: root/gdb/ser-go32.c
diff options
context:
space:
mode:
authorSteve Chamberlain <sac@cygnus>1994-08-22 17:58:47 +0000
committerSteve Chamberlain <sac@cygnus>1994-08-22 17:58:47 +0000
commitbe5e6fff5a0b3abbcbd6c5129c3286e057ed1bbd (patch)
tree104acb84b4c43f7d26408c6edf2a190477ac284d /gdb/ser-go32.c
parente914ed521998a45e6cd6584ce9b845d8e9255302 (diff)
downloadgdb-be5e6fff5a0b3abbcbd6c5129c3286e057ed1bbd.zip
gdb-be5e6fff5a0b3abbcbd6c5129c3286e057ed1bbd.tar.gz
gdb-be5e6fff5a0b3abbcbd6c5129c3286e057ed1bbd.tar.bz2
Work to reduce the interrupts-off duration when running in DOS.
* ser-go32.c: (dos_async_ready): See if anything is in the buffer. (dos_async_rx): rewrite to unpack as many characters from the asynctsr as possible into a local buffer.
Diffstat (limited to 'gdb/ser-go32.c')
-rw-r--r--gdb/ser-go32.c89
1 files changed, 72 insertions, 17 deletions
diff --git a/gdb/ser-go32.c b/gdb/ser-go32.c
index eced332..b1b5331 100644
--- a/gdb/ser-go32.c
+++ b/gdb/ser-go32.c
@@ -24,6 +24,7 @@
#define disable() asm("cli")
#define enable() asm("sti")
+
struct go32_ttystate
{
int bogus;
@@ -82,6 +83,10 @@ static int dosasync_write PARAMS ((int fd, const char *buf, int len));
#define VERSION 1
#define OFFSET 0x104
+char packet[50];
+int packet_len;
+int packet_idx;
+
unsigned char bb;
unsigned short sb;
unsigned long sl;
@@ -94,7 +99,7 @@ unsigned long sl;
#define GET_LONG(x) ( dosmemget((x),4,&sl), sl)
static
-unsigned short
+unsigned short
GET_WORD (x)
{
unsigned short sb;
@@ -185,6 +190,9 @@ dos_async_ready ()
{
int ret;
+ if (packet_idx < packet_len)
+ return 1;
+
disable ();
#if RDY_CNT
ret = GET_WORD (aindex + AOFF_COUNT);
@@ -203,24 +211,70 @@ dos_async_rx ()
char rv;
short idx;
- while (!dos_async_ready ())
+ while (1)
{
- if (kbhit ())
+ if (packet_idx < packet_len)
+ {
+ char x = packet[packet_idx++];
+ return x;
+ }
+ while (!dos_async_ready ())
{
- printf_unfiltered ("abort!\n");
- return 0;
+ if (kbhit ())
+ {
+ printf_unfiltered ("abort!\n");
+ return 0;
+ }
}
+ disable ();
+ {
+ /* Sometimes we can read more than one char at a time
+ from the buffer, which is good, cause it'll mean
+ less time with interrupts turned off, which means
+ less dropped characters */
+
+ /* We only do the simplest case here - not bothering with
+ wrap around */
+ int len;
+
+ int getp = GET_WORD (aindex + AOFF_GETP);
+ int putp = GET_WORD (aindex + AOFF_PUTP);
+ int endb = GET_WORD (aindex + AOFF_BUFFER_END);
+ int startb = GET_WORD (aindex + AOFF_BUFFER_START);
+
+ /* We'd like to grab to the end of the the input,
+ but it may have wrapped, so max is to the end
+ of the buffer */
+
+ if (putp > endb || putp < getp)
+ putp = endb;
+
+ /* Work out the length of the suck */
+ len = putp - getp;
+
+ /* But only suck as many as we can hold in one go */
+ if (len > sizeof (packet))
+ len = sizeof (packet);
+
+ dosmemget (aindex - OFFSET + getp, len, packet);
+
+ packet_len = len;
+ packet_idx = 0;
+
+ if (getp + len >= endb)
+ {
+ getp = startb;
+ }
+ else
+ {
+ getp = getp + len;
+ }
+
+ SET_WORD (aindex + AOFF_GETP, getp);
+ SET_WORD (aindex + AOFF_COUNT, GET_WORD (aindex + AOFF_COUNT) - len);
+ }
+ enable ();
}
- disable ();
- idx = GET_WORD (aindex + AOFF_GETP);
- idx++;
- SET_WORD (aindex + AOFF_GETP, idx);
- rv = aptr (idx - 1);
- SET_WORD (aindex + AOFF_COUNT, GET_WORD (aindex + AOFF_COUNT) - 1);
- if (GET_WORD (aindex + AOFF_GETP) > GET_WORD (aindex + AOFF_BUFFER_END))
- SET_WORD (aindex + AOFF_GETP, GET_WORD (aindex + AOFF_BUFFER_START));
- enable ();
- return rv;
}
@@ -233,7 +287,7 @@ dosasync_read (fd, buf, len, timeout)
{
long now, then;
int i;
-
+ int its = 0;
time (&now);
then = now + timeout;
@@ -244,8 +298,9 @@ dosasync_read (fd, buf, len, timeout)
while (!dos_async_ready ())
{
time (&now);
- if (now >= then && timeout > 0)
+ if (now >= then && timeout > 0 && its > 1000)
return i;
+ its++;
}
}
*buf++ = dos_async_rx ();