[comp.sys.ibm.pc] Interrupting DOS

tom@vrdxhq.UUCP (Tom Welsh) (11/13/86)

Some help please ...

As many of you may know, DOS is NOT reentrant.  In other words,
if DOS is busy doing something like writing to disk or printer,
then no interrupt routine should attempt to invoke a DOS service,
e.g. INT 21H.   I found this out by having a program crash.  My
suspicions were verified by being able to consistenly produce
the error.

As further "hint", I quote from ADVANCED-MSDOS, from Microsoft Press:

"Since the current versions of MS-DOS are not reentrant, the MS-DOS
functions should never be called by a hardware interrupt handler
during the actual interrupt processing."  -- page 216

Fine, I accept all this.

Here's what I'm curious about ...

SuperKey, which responds to keyboard interrupts, seems to obey this
rule.  If, while doing nothing, I press ALT-/ to invoke Superkey,
it comes up instantly.  If I do something like copy a gigantic
file (requiring several seconds), and I press ALT-/ as soon as the
copy starts, Superkey WAITS until the copy is done before it comes
up.   HOW DOES IT KNOW at the time of the interrupt that DOS was
currently doing something and should not be interrupted?  A while ago,   
someone on the net mentioned a DOS/BIOS service or a flag that could
be checked to see if DOS was busy.  I can't find such a thing in
the Superkey code.

Any clues?


And, on another note, I found an INT 28H in the Superkey code.  What
does this do?  All my documentation says its reserved for DOS.   

Thanks in advance for information.

- Tom Welsh

backman@interlan.UUCP (Larry Backman) (11/17/86)

In article <2409@vrdxhq.UUCP> tom@vrdxhq.UUCP (Tom Welsh) writes:
>
>As many of you may know, DOS is NOT reentrant.  In other words,
>if DOS is busy doing something like writing to disk or printer,
>then no interrupt routine should attempt to invoke a DOS service,
>e.g. INT 21H.   I found this out by having a program crash.  My
>
>Here's what I'm curious about ...
>
>SuperKey, which responds to keyboard interrupts, seems to obey this
>rule.  If, while doing nothing, I press ALT-/ to invoke Superkey,
>it comes up instantly.  If I do something like copy a gigantic
>file (requiring several seconds), and I press ALT-/ as soon as the
>copy starts, Superkey WAITS until the copy is done before it comes
>up.   HOW DOES IT KNOW at the time of the interrupt that DOS was
>currently doing something and should not be interrupted?  A while ago,   
>someone on the net mentioned a DOS/BIOS service or a flag that could
>be checked to see if DOS was busy.  I can't find such a thing in
>the Superkey code.
>
>And, on another note, I found an INT 28H in the Superkey code.  What
>does this do?  All my documentation says its reserved for DOS.   
>

	In a previous place of employment, I was involved in solving the
	DOS reentrancy puzzle.  The product that I worked on was a real-time
	communications device, a terminal emulator, that could be placed in
	the back-ground via "Hot-Key".  What was special about this product
	was the ability to have background file-transfer while a separate
	user application was occuring in the foreground.  We went through a
	number of contortions with DOS to provide this backgound file transfer
	ability, the above mentioned INT 28 being one of the keys to our
	sucess.
	
	Our product ran off of the hardware timer while in background mode.
	To make matters even more complicated, the product was comprised of 
	three separate resident modules, each of which communicated with
	each other via software interrupts.  The lowest module was driven
	by interrupts occuring from a communication line, while the higher
	modules were driven by the timers tick.   Incoming data was buffered
	in the lower module,  waiting for polls from above before passing it
	up to the higher layers.

	The highest of the three layers was the brains of the whole system. It
	polled the other two modules for data as well as interfacing to both
	DOS and BIOS.  Being the brains, it had to know when DOS was in a
	critical section, caused by a foreground application issuing an INT 21
	call.  Sounds simple... just trap INT 21, put a semaphore around it
	and hold off any DOS accesses until the INT 21 call finished.  This
	was our first approach, and it worked resonably well.  Unfortunately,
	we discovered that the DOS command prompt, as well as many applications
	issued keyboard reads by waiting for input (INT 21 functions 1 and 0A).
	We also had problems around the EXEC and EXIT calls (function 4B and
	4C).  End result... try another solution.

	The next attempt involved the famous undocumented DOS "dirty bit".  
	While DOS is not reentrant to the outside world, it reenters itself
	left and right.  In fact many function calls call DOS dozens of times
	before completing.  For an educational experience try tracing a DOS
	function call, function 4B  for instance. Anyway,  if DOS reenters it-
	self, it must have a means of checking when it is safe to do so.  This
	means is provided  in MS-DOS via INT 21 function 34.  Note that I said
	MS-DOS as opposed to IBM PC-DOS.  It returns the DOS critical section
	semaphore in AL, if AL is 1 DOS is busy, try again later.  To make a
	long story short, this worked 98% of the time, but we still had problems	when DOS itself was waiting for keyboard input, and when the user "hot-
	keyed" at just the wrong instant.  So... scratch one more good idea...

	After a series of marathon sessions tracing through PRINT.COM and
	MODE.COM we started to notice that  DOS grabbed the INT 28 interrupt
	vector in these programs.  More disassembling convinced us that we
	had tripped over DOS's internal scheduling mechanism.  We found that
	many of the DOS functions called INT 28 from within themselves. A
	lot of experimentation convinced us that trapping INT 28 was a means
	of knowing when it was safe to reenter DOS. So.. we built a system
	that used the INT 21 function 34 semaphore to tell us if we could
	interrupt DOS, if we could, great, off went our disk or printer request
	with no risk of rentrancy.  If on the other hand, the semaphore 
	indicated that DOS was in a critical section we backed off, since 
	we were currently in the hardware timer interrupt, not a good place
	to be while DOS is critical. 

	Before we exitted the timer however we set another semaphore of our
	own indicating that we had a pending DOS request which had been post-
	poned.  We then trapped INT 28, and issued the postponed request when
	the next INT 28 occurred, one that DOS itself had generated, indicating 	to other applications that they could schedule a DOS interrupt at this
	time.

	I would be extremely interested in hearing from anyone else on the
	net with similar solutions to this problem.  I also would like to pose
	two questions of my own.

	First; is there anyone who had access to DOS source code that can
	postively confirm that INT 28 is a scheduling function? 

	Second; a corollary part of our product was the ability to deallocate
	the three resident programs from memory.  We did so via a SETBLOCK
	(function 4A) when starting the program and a FREE (function 48)
	when the user wished to deallocate the program.  It worked most of
	the time.  Any hints what we were doing wrong, any other approaches
	to this problem would also be interesting.


	Larry Backman
	Micom Interlan, Inc.
	155 Swanson Rd.
	Boxborough, Ma.  01719
	617-263-1199

	mit-eddie \
	ulowell    -> !interlan!backman
        ima       /