Support for multitasking within taskwindows

Daniel Ellis


Overview
========

When an attempt is made to:
     write to a device whose buffer is full
     read from a device which has no data
  or flush a stream (including upon closure) which has data in the buffer
  
DeviceFS enters a loop waiting until the operation can proceed.  This causes
the machine to lock up which is rather inconvenient.  There is support for
breaking out of the condition by pressing the escape key, but this doesn't
work within taskwindows.

This new facility allows taskwindows to continue to multitask by calling
OS_UpCall 6 while waiting for one of these events to complete, which
corresponds to whenever the internal routine checkescape is called.

To make this more useful, there is also a timeout facility.  If the timeout
is non zero, then after the given time, the device will stop sleeping and
return a timeout error.

These new parameters can either be set from the special field for devicefs or
via IOCtls.  A special field entry has also been added for non-blocking.

The changes can be conditionally included with the build switch TWSleep.

Changes
=======

Flags
-----

A new flag word has been added to the file structure.  It is set to 2
internally if we don't wish OS_UpCall 6 to occur.  On a buffered stream it
is set to zero while waiting for a wake up event.  On non-buffered streams,
there is no event to wake us up so we call OS_UpCall 6 with a non-zero
pollword implying heavier CPU usage from the taskwindow (but still useful). 
The pollword is set to 1 to wake up, and 2 if the device has timed out.

The special field string is now:

"buffer/Nblock,noblock/Snosleep,sleep/Stimeout/N"

and the new IOCtl reason codes are:

IOCTL_GENERIC_SLEEP         (4)

IOCTL_GENERIC_TIMEOUT       (5)
