Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
I/O Subsystem<br />
algorithm terminal_read<br />
{<br />
if (no data on canonical clist)<br />
{<br />
while (no data on raw clist)<br />
{<br />
if (tty opened <strong>with</strong> no delay option)<br />
return;<br />
if (tty in raw mode based on timer and timer not active)<br />
arrange for timer wakeup (callout table);<br />
sleep (event: data arrives from terminal);<br />
}<br />
Figure 37. Algorithm<br />
for Reading a<br />
Terminal<br />
}<br />
if (tty in raw mode) /* <strong>the</strong>re is data on raw clist */<br />
copy all data from raw c1ist to canonical c1ist;<br />
else<br />
/* tty is in canonical mode *'<br />
{<br />
while (characters on raw clist)<br />
{<br />
copy one character at a time from raw c1ist to canonical clist:<br />
do erase, kill processing;<br />
if (char is carriage return or end-of-file)<br />
break; /* out of while loop */<br />
}<br />
}<br />
}<br />
while (characters on canonical list and read count not satisfied)<br />
copy from cblocks on canonical list to user address space;<br />
If no data is<br />
currently on ei<strong>the</strong>r<br />
input clist, <strong>the</strong><br />
reading process<br />
sleeps until <strong>the</strong><br />
arrival of a line of<br />
data.<br />
When data is entered, <strong>the</strong> terminal interrupt handler invokes <strong>the</strong> line discipline interrupt handler, which places <strong>the</strong><br />
data on <strong>the</strong> raw clist for input to reading processes and on <strong>the</strong> output clist for echoing back to <strong>the</strong> terminal.<br />
Character processing in input and output directions is asymmetric, two input clists and one output clist.<br />
The use of two input clists means that <strong>the</strong> interrupt handler can simply dump characters onto <strong>the</strong> raw clist and<br />
wakeup up reading processes, which properly incur <strong>the</strong> expense of processing input data.<br />
The interrupt handler puts input characters immediately on <strong>the</strong> output clist, so that <strong>the</strong> user sees <strong>the</strong> typed character<br />
<strong>with</strong> minimal delay.<br />
char input[256];<br />
main()<br />
{<br />
register int i;<br />
for (i = 0; i < 18; i++)<br />
{<br />
switch (fork())<br />
{<br />
case -1: /* error */<br />
printf("error cannot fork\n");<br />
exitO;<br />
default: /* parent process * /<br />
break;<br />
case 0: /* child process */<br />
for (;;)<br />
{<br />
read(0, input, 256); /* read line */<br />
printf("%d read %s\n", i, input);<br />
}<br />
}<br />
}<br />
}<br />
149<br />
Figure 38. Contending for Terminal Input<br />
Data<br />
The processes will spend most of <strong>the</strong>ir<br />
time sleeping in terminal_read,<br />
waiting for input data.<br />
Intelligent terminals "cook" <strong>the</strong>ir<br />
input in <strong>the</strong> peripheral, freeing CPU<br />
for o<strong>the</strong>r work.