Am 26.01.2013 13:01, schrieb Michael Neumann:
Am 26.01.2013 12:28, schrieb Michael Neumann:
Another question: When a task sends a message to another task, and
this task is waiting exactly for this event, will it directly switch
to that task, or will it buffer the message?
Sometimes this could be quite handy and efficient. I rember this was
done in the L4 microkernel (www.l4ka.org), which only allowed
synchronous IPC. It could make sense to provide a
send_and_receive directive, which sends to the channel and lets the
scheduler know that it is now waiting for a message to receive from
another port. So send_and_receive could
directly switch to the other task, and when this does a send back to
the calling task, it will switch back to it. If you don't have
send_and_receive as atomic operation, there
is no way to switch back to the other task, as it might still be
running.
"as it might still be running" is here of course wrong (as we switched
to another thread). What I wanted to say is, that it is not waiting
for any event, so it is not in a blocking state, so that
we cannot directly switch back (matching the recv() and the send()).
Ideally the task that wants to read would do the non-blocking I/O
itself, and the scheduler would just notify when it can "read". But I
think this is not possible with libuv as you
have no control over when to read (except using uv_read_start() /
_stop). I think this would be much more efficient and even more
powerful (one can read directly into a buffer...
there is no need to allocate a new buffer for each read as done by
libuv). So what I would suggest is the following:
// task
blocking_read(socket, buffer, ...)
// this will register socket with the schedulers event queue (if
not yet done) and block.
// once the scheduler will receive an "data is available" event
from the kernel
// it will unblock the task.
// then the task will do an non-blocking read() on it's own.
Basically it's the same what libuv does internally on it's own, just
that the responsibility for doing the read's for example is
moved into the task itself, so there is no longer a need for an I/O
task and we gain full control of the asynchronous reads.
The advantage is:
* we no longer need messages for I/O.
* more flexibility
* much better memory usage (no need to copy anymore)
* the design is much easier and better to understand,
libraries become so much easier
* and message passing could be done synchronous, i.e. very fast :)
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev