"Dave Frost" <[EMAIL PROTECTED]> wrote:
From the outset i decided i wanted the vm to provide its own threading
mechanism i.e. not based on posix threads for example.
Parrot had the option of providing its own threads, thread scheduling and
the like. As leo mentioned, we're using OS threads. The problem with
threads in user space (as you propose) is that the operating system doesn't
know of the threads - it just sees the single OS thread running the program.
And that means that if you have 4 CPUs (or a 4-core CPU, which I doubt will
be uncommon in the near future) then any program running on your VM can only
ever use 2 of those (the OS can only schedule threads that it knows about,
and your VM's program's threads wouldn't be real ones, so couldn't be
scheduled on seperate CPUs). With concurrency being of increasing
importance, I think this is a powerful argument for using OS threads.
My first plan was to have 2 native threads, one for execution of the main
'core' execution code the runtime if you like, the other thread was used
to tell the execution code to swap threads.
The most expensive part of using threading, aside from thread creation, is
doing context switches (between threads). Here, you are requiring two
context switches to provide one virtual context switch to code you are
executing. And the switches are, of course, wasted if you decide not to
switch.
I thought i could synchronise these 2 using native semaphores. When it
comes down to it a single op code takes a number of nastive instructions
i.e. to execute an add insttuction i may have to do (say) 5 things. so I
just check after each op code has been executed to see if the thread needs
swapping out. That seems like a bad idea mainly due to speed/efficiency.
Each thread is a top level object, so the stack, all stack pointers and
register data etc resides in the thread, but i still cant have the
execution engine swapping threads mid operation, so in my add example i
still dont think i would want the execution engine swapping out a thread
after 3 instructions, it would need to complete all 5.
Its been a bit of a brick wall this, it seemed to be going quite well up
to this point and i need to solve this before i can move on with
lwm,(light weight machine).
Any pointers, thoughts or comments are welcome.
I guess what I really want to say is "consider using OS threads". :-) But
more helpfully, here's a (hacky, but maybe workable) approach that
immediately occurs to me. I assume you have a sequence of bytecode that you
execute. When you need to do a context switch, the thread is doing the
signalling to say "context switch now" takes a copy of the instruction part
of the next opcode that would be executed in the current "virtual thread"
and then replaces the instruction with a "context switch" opcode. Then,
when the context switch opcode executes, it replaces the instruction in the
bytecode with the original one and does the context switch. But you need
special cases for ops that want to try and obtain locks, so you can force a
switch if the lock isn't available and stuff. And probably a flag to set
when a switch happens, so you don't mess up the bytecode by re-writing the
context switch opcode twice.
Not saying it's the best scheme, but it may be Good Enough.
Have fun,
Jonathan