Mail Archives: djgpp-workers/1999/05/26/16:29:03
Eli Zaretskii <eliz AT is DOT elta DOT co DOT il> writes:
> My suggestion was meant to be a replacement for the mandatory use of
> the library wrappers. I think saying "#pragma interrupt" is easier
> than throwing in all the code to call the wrapper
That is certainly true. Surely gcc would use an __attribute__ for this
rather than a #pragma, though? Judging from the info pages, the gcc
developers don't like #pragma very much (and quite rightly: it is crazy to
have important modifiers that you can't generate from a macro).
> > I do have some reservations about how the libc interrupt wrappers
> > currently work
>
> May I suggest to submit changes to the wrappers, then?
The biggest problem is the inability to only sometimes chain to the old
handler. I did try to write a conditional chaining wrapper at one point,
that used a return code from the C handler to decide whether to chain or
iret, but I got confused and never completed it. I'll try to get this
finished, but no promises if/when I'll have time.
The reentrancy difficulty is IMHO not something that can be nicely overcome
in a runtime library. It is only a problem for very interrupt intensive
programs, in obscure situations like when Allegro is running multiple timer
handlers at different speeds, and may need to reenable interrupts so that a
fast timer event can interrupt a longer running, more expensive timer task.
Almost nobody needs to do that, so I don't think it is worth the overhead of
putting that code in libc. If anyone but me ever does need it, my wrappers
from Allegro can easily be recycled.
> > Also, the libc handlers only allocate one stack per interrupt, which
> > makes it impossible to do anything but crash if a reentrant interrupt
> > comes along.
>
> Sorry, I'm not sure I understand this completely. If the stack is large
> enough, why are reentrant interrupts a problem, exactly?
At the start of the handler, it just loads the IRQ stack into %esp. If it
then reenables interrupts and is called reentrantly, it reloads the same
stack address, and destroys the stack of the first call. There is no way for
it to find out how far down the stack the previous interrupt had gotten.
> > I don't think there is any really generic solution to this, though,
> > because everyone has different needs.
>
> Perhaps we could have several solutions for several popular needs.
I can think of basically three situations:
- lightweight handlers like the keyboard and timer ones in libc. These can
be written directly in asm, and don't need any wrapper at all.
- normal handlers, written in C but not doing too much work. The libc
wrappers are fine for these.
- people doing lots of work inside the handler, like mixing sound samples,
at which point reentrancy becomes an issue. This is where you need something
more like the Allegro wrappers, but I'm not brave enough to try and rewrite
those as relocatable, generated code blocks in the style of the libc
routines (my current code just has a number of global wrapper functions,
which is slightly wasteful of memory but much easier to implement :-)
--
Shawn Hargreaves - shawn AT talula DOT demon DOT co DOT uk - http://www.talula.demon.co.uk/
"A binary is barely software: it's more like hardware on a floppy disk."
- Raw text -