Tweaked the siointr1() so that it works better at 921600 bps, especially
with multiple ports on a shared interrupt demultiplexed by the puc_intr() handler. siointr1() first read as much input as possible and then checked all possibly-relevant status registers, partly for robustness and partly for historical reasons. This is very bad if it is called for every port sharing an interrupt like puc_intr() does. It can spend too long reading all the input for some ports when the interrupt is for a more urgent event on another, or just too long checking all the status registers when there are lots of ports. The inter-character time is too long for reading all the input even when the interrupt is for a transmitter interrupt on the same port, and at 921600 bps the inter-char time is 10.85 usec and was often exceeded with just 2 ports, leaving the transmitters idle for about 6% of the time. The tweak is to break out of the read loop after reading 1 char if output can be done. This avoids most of the idle transmitter time for 2 active ports at 921600 bps bidirectional on the test system. It also reduces overhead by about 20%. More complete fixes use the programmable tx low watermark on 16950's and reduce overhead by another 65%.
This commit is contained in:
parent
170f850343
commit
c0952034c3
@ -1868,6 +1868,10 @@ if (com->iptr - com->ibuf == 8)
|
||||
CE_RECORD(com, CE_OVERRUN);
|
||||
}
|
||||
cont:
|
||||
if (line_status & LSR_TXRDY
|
||||
&& com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY))
|
||||
goto txrdy;
|
||||
|
||||
/*
|
||||
* "& 0x7F" is to avoid the gcc-1.40 generating a slow
|
||||
* jump from the top of the loop to here
|
||||
@ -1905,6 +1909,7 @@ if (com->iptr - com->ibuf == 8)
|
||||
}
|
||||
}
|
||||
|
||||
txrdy:
|
||||
/* output queued and everything ready? */
|
||||
if (line_status & LSR_TXRDY
|
||||
&& com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)) {
|
||||
|
Loading…
Reference in New Issue
Block a user