Preemptive multithreading, stack checking in Linux user-land
Posted: Tue Jul 29, 2008 1:28 pm
Hi everyone,
I'm writing a VM for my high-level language which is to be JIT-compiled to native code before execution. To be able to take advantage of multiple cores, I plan to use POSIX "VM" threads (I'm working with Linux and GCC), and each VM thread will manage multiple language threads for light-weight multithreading (but also so that if/when it becomes a standalone OS, each CPU core can be assigned a VM thread).
I'm fine with writing some assembly to switch from VM code to JITed code, but exiting out again is puzzling me. Ideally, I'd like to have a timer go off after a language thread's quantum expires and do a longjmp to the "restore the stack, return to VM" code. I've found that alarm()/sigaction() can act as a timer, but they seem to expect the signal handler to return. So could I longjmp out of a signal handler reliably, with possibly only needing to re-enable signals for the thread? That sounds kind of dirty...
Since polling the system time or constantly decrementing a "quantum remaining" register is inefficient and not needing to clutter the compiler with such code would be nice, is there another way to implement my own preempting in user-land?
Another problem is a language thread overflowing its (private) stack; is it possible to trap a stack overflow in a child POSIX thread separately from other invalid memory writes? From what I can find, SIGSTKFLT doesn't seem to be well supported at all. Even if the thread dies, that wouldn't be too much of a problem, as long as it's traceable back to overflowing the stack, and where. (Methods could check the remaining stack size in their prologues but that sounds slow, maybe it's the most stable way though.)
Thanks in advance! Certain things are so much easier when you have access to the PIT and IDT...
I'm writing a VM for my high-level language which is to be JIT-compiled to native code before execution. To be able to take advantage of multiple cores, I plan to use POSIX "VM" threads (I'm working with Linux and GCC), and each VM thread will manage multiple language threads for light-weight multithreading (but also so that if/when it becomes a standalone OS, each CPU core can be assigned a VM thread).
I'm fine with writing some assembly to switch from VM code to JITed code, but exiting out again is puzzling me. Ideally, I'd like to have a timer go off after a language thread's quantum expires and do a longjmp to the "restore the stack, return to VM" code. I've found that alarm()/sigaction() can act as a timer, but they seem to expect the signal handler to return. So could I longjmp out of a signal handler reliably, with possibly only needing to re-enable signals for the thread? That sounds kind of dirty...
Since polling the system time or constantly decrementing a "quantum remaining" register is inefficient and not needing to clutter the compiler with such code would be nice, is there another way to implement my own preempting in user-land?
Another problem is a language thread overflowing its (private) stack; is it possible to trap a stack overflow in a child POSIX thread separately from other invalid memory writes? From what I can find, SIGSTKFLT doesn't seem to be well supported at all. Even if the thread dies, that wouldn't be too much of a problem, as long as it's traceable back to overflowing the stack, and where. (Methods could check the remaining stack size in their prologues but that sounds slow, maybe it's the most stable way though.)
Thanks in advance! Certain things are so much easier when you have access to the PIT and IDT...