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

Reply via email to