[comp.os.minix] printer.c timing bug

lyo@uk.ac.newcastle.cheviot (Jim Lyons) (05/06/87)

Another problem has illustrated the errors that can appear when a routine
written for a one machine is run on another with different timing
characteristics. 

With the exception of the first invocation - when the call is from a user -
the pr_char() procedure in printer.c is called directly by the interrupt
handler lpr_int in mpx88.s.  Pr_char() checks the status of the printer  
(specifically that the busy bit is not set) collects the next character 
to be printed, puts it in the data register and strobes the printer:

line 264:	port_out(port_base, ch);	/* output character */
		port_out(port_base + 2, ASSERT_STROBE);
		port_out(port_base + 2, NEGATE_STROBE);

The pointer to the buffer is then adjusted and the count decremented:

		offset++;
		pcount--;

However, the printer can "ack" the data transfer before these last two 
operations are carried out, producing and interrupt and an additional 
invocation of the procedure.  

The end result is when the stack unwinds, the characters appear in 
unpredictable positions on the paper.

One cure is to make the writing action "atomic" by completing the increment
and decrement operations before strobing the printer:

		port_out(port_base, ch);	/* output character */
		offset++;
		pcount--;
		port_out(port_base + 2, ASSERT_STROBE);
		port_out(port_base + 2, NEGATE_STROBE);

Printer.c needs to be re-written!