Paul asks >   Why are you using an implementation dependent
          >   feature [DELAY] to force task switching? Is it
          >   that you have extremely long threads between
          >   context switch points? If so you might consider
          >   reducing these thread lengths rather than sticking
          >   delay 0's all over the place. I'd be curious to
          >   hear why you are using them. I think that the need
          >   to use delay 0's in this manner is a flag pointing
          >   to bigger design issues.

Hmmm. Are we getting a little closer to the real reason why gnat
no longer supports DOS? This is precisely the misunderstanding that
prevents most systems from ever being hard-realtime. If every task
were short, in particular finite, there would be little difficulty
in making systems meet their deadlines. The problem is that most
tasks are of unlimited duration, such as: (1) operating system calls
which block until the user gives input, (2) rendezvous (or semaphores,
or monitors, or ...) which block until an elment of a queue appears,
(3) tasks which poll a port for input or for output completion,
(4) tasks which set memory that occasionally require cache refreshes
which in turn occasionally (purposefully) hang the cache across all
the CPUs on the bus, (5) tasks waiting for an interrupt, (6) tasks
doing low priority work on systems where it is Much more expensive
to check the status of the queues for task swapping purposes than
to have low priority tasks simply report that they are optinally
ready for a task swap-out now, and (7) other tasks where the
intelligence as to when to optionally task switch is better placed
with the task than with an external scheduling medium. When a task
finished in a fixed number of milliseconds, it is always possible
to use simple analytical methods to help schedule it. The unlimited
cases are more problematical, and even cases like 4 through 7 where
analytical methods apply to partially solve the problem, it is still
more efficient for the task to share its intelligence with the
task scheduler. The arguments used during both Ada 83 and Ada 95
to require DELAY 0.0 to be a task scheduling point assume that we
do not program code like 1 through 7, limiting Ada to NON-embedded
systems only. Issues like (1) are particularly hazardous as more and
more applications conform to COTS systems and the COE. Answers which
say that realtime theory can only handle (2) through (7) in the presence
of CPUs many thousands of times faster than current CPUs are not
acceptible to engineers who must make the software work Today, and
so short cuts (like a GOTO in TIME) such as DELAY 0.0 are needed
to make the system work without hanging the mouse. Attempting to solve
this with one of the existing DOS extenders has contributed materially
to the delay (possibly unlimited) in the next DOS gnat release. Yet
a DOS release might contribute more to Ada acceptance than any other
kind of release. It would be nice if there were an affordable NT
release (on the order of the price of DOS, for example) that worked
on the plethora of 386, 486, etc., hardware out there. But there is not.
It would be nice if NT (or any other operating system) gave game
(and simulator, communication, command & control,
satellite, mapping, graphics, virtual reality, audio, video,
and basically everything except database) programmers the control
they need of the mouse, graphical memory-mapped pixels, I/O ports,
controller boards, keyboard, and pens. But they do not. It would be nice
if the tasks we were programming (again, we are excepting
the entire database community) were all of predictible, limited duration.
But they are not.

Conclusion: DELAY 0.0 is needed to be a task switch point. DOS is needed
for the future of Ada because we need to give Ada to people who are
stuck on DOS machines today.