Dan Sugalski wrote:
I'm pretty sure the POSIX docs say that you can't call mutex routines from within interrupt code, which makes sense--the last thing you want is for an interrupt handler to block on a mutex aquisition.
I haven't got a copy, but I'd be surprised if they explicitly forbade it - I think however you *do* need to be very careful if you need to mix mutexes and signals, so that you don't self-deadlock.
I don't have a copy handy anymore either, unfortunately, but Butenhof's pretty clear--none of the Posix thread functions are async safe. (Section 6.6.6, p234-235 in my copy) I seem to remember someone scolding me about this, or something like it, ages ago.
Even in those cases where the posix stuff is OK in signal handlers it's still not enough, as the world isn't entirely unix, and on most of those platforms where this sort of thing is actively useful (Basically systems with async I/O and per-request callbacks) signals aren't used for this sort of thing. Most Unix systems will probably have us falling back to synchronous I/O and I/O threads. It's the Windows (and, to a lesser extent, VMS systems) that get dealt with there, and I'm pretty sure you're not allowed to do any sort of pthreads stuff in their AST routines.
To make this work right without the benefits of locks is going to require proper code ordering, memory barriers, and thread wakeup from interrupt routines. I'm not 100% sure that it's worth it at this point, given how much of a major, platform-dependent pain it'll be. (The whole darned code segment in question will have every other line a PLATFORM_MEMORY_BARRIER macro) I'm half tempted to just punt it into the platform-specific source module, but that has its own issues.
This isn't actually a big deal, as it's reasonably straightforward to write code that can handle multiple user-space readers and writers (which can guard themselves with mutexes) and a single interrupt-time writer. Proper ordering and checking of operations inside the code makes this straightforward, if a pain. (And I know the ordering's doable, otherwise every single OS on the planet with interrupt code would fall down and go boom :) The nasty part comes in with multiple interrupt-time writers. I'm not sure if it's common to be able to have multiple concurrent interrupt handlers running, but I do know it's possible.
You *cannot* achieve what you want by 'proper ordering and checking of operations', as this will *not* work on a SMP machine, where the ordering of loads and stores is *not* guaranteed, *irrespective* of what appears to be the order of instructions produced by the compiler.
Right, I understand that. (My processor of choice is the Alpha -- I'm altogether too familiar with the fun that SMP and out-of-order execution and loads/stores bring) Maintaining a single user-mode reader or writer is simple and, with that caveat, having a single interrupt-level writer becomes, while not trivial, reasonably doable. I realized after I started all this that I could potentially have multiple interrupt-level writers going simultaneously, which makes things rather more difficult, though I think that's only possible so far on recent VMS systems, and is disableable. (And while I could block interrupts from within the interrupt handler, there's still the small but non-zero chance that two interrupts are being serviced essentially simultaneously such that disabling interrupts won't matter since I've two in flight at once.
The more I think about this the more I want to punt on the whole idea. Cross-platform async IO is just one big swamp.
--
Dan
--------------------------------------"it's like this"------------------- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk