In that case, what needs to be done to finish it, or at least make it "self-compilable"? And then what do we need to do to skip c? Or is that even reasonable?
Regarding I/O: it's difficult to do I/O in the presence of green threads. Obviously when one green thread is blocked by I/O the other threads must continue running, meaning we need some sort of async I/O. Most of the async I/O libraries I've seen so far seem to concentrate more on sockets than I/O in general.
What are your ideas for handling async io? I know there are system specific ways, but I don't think that's a good idea.
We could have separate os threads for the io, one for each major io system: HDDs, network, keyboard, etc. We could write special io methods for the green threads that request the io from the scheduler. The scheduler adds the request to the appropriate io thread queue. When the operation completes, it either unblocks the gt, uses the provided call-back, or passes a SNAP style message.
I don't know if that would work very well. It doesn't seem very scalable, and at the very least is complicated. It would be best of course, if we could find a cross platform async io lib. But it still might be a good idea to make the scheduler responsible for io, whatever we use. I'm sure you know more about the whole process than I do.
Do you know how any other systems do it? Does erlang have async io? How does the JVM get it's async io? The wikipedia page claims that it is possible to synthesize async io from polling and interrupts (supposedly the JVM does that), but I don't know how standard and trans-system those are. http://en.wikipedia.org/wiki/Non-blocking_I/O
I assume it uses async I/O: For a long time Erlang had only green threads and didn't actually use OS threads. From what little I could grok of the Erlang source, it seems it has a set of OS-specific "drivers" for I/O, but these drivers seem to be extremely basic. It seems to have some sort of queue, but I can't figure out how it handles the queue (i.e. how it prevents the queue from blocking normal operation).
Each port is apparently modeled as a process that happens to have the ability to resume/suspend other processes. When the port gets its timeslice (?) it goes through its queue, does one I/O request (?), then resumes the process that asked for that I/O (I think).
In fact the scheme you described seems, approximately, what Erlang does. I think. I haven't found any particularly good discussions on the Erlang source.
Then there's some note somewhere in erl_async too that if threads (OS threads?) are unsupported, then the "async" I/O becomes synchronous (?).
> How does the JVM get it's async io?
I think that again, this is OS-dependent. After all, JVM is a virtual machine, so it's up to the JVM implementation to handle this. Figuring out how a random JVM implementation does this probably means digging through C source.
To do async IO there are 2 ways: use OS threads or use green threads and OS-specific asynchronous I/O calls. Either way, the VM should, obviously, abstract away the OS-dependant features. Using OS threads seems easier to me.
Well, there is a Boost library for cross-platform threading. We could just use that and "simulated" async using threads to offload the synchronous io. Now, maybe that's a bad idea, and we need to use some abstracted os specific async libraries, but it would work.
Boost also seems to have plenty of libraries that would be useful for SNAP. How is that going anyway, almkglor? I should probably ask questions pertaining to that subjects in it's own thread.
Pretty quiet around here. Hopefully that means everyone's busy ;)
> Well, there is a Boost library for cross-platform threading. We could just use that and "simulated" async using threads to offload the synchronous io.
Boost also has asio, but it appears to be concentrated more on socket I/O than I/O in general.
What I would like is to have a general-purpose asynchronous I/O library, which would handle all details of asynchronicity.
Basically, I intend to allow SNAP to be compiled in two modes:
1. Single worker thread, multiple process. For cases where the OS doesn't have decent threads (dorky embedded systems? LOL, quite a few of the embedded systems I've seen recently actually have decent threads)
2. Multiple worker OS-level threads, single runqueue.
async I/O is needed for 1, and would be nice for 2: in case 2, if a worker thread blocks on synchronous I/O, the others will still fetch processes to run from the runqueue, although the blocked worker thread is one less thread that can work.
However in case 1, there's just one thread, so it can't block.