On 12/30/13 8:40 PM, Christian Ohler wrote:
Example: Even if the scheduling is perfectly fair and assigns the same
number of cycles to a producing task and the corresponding consuming
task, the producer can still outrun the consumer if producing a
message takes fewer cycles than consuming one, leading to memory
exhaustion if the channel is unbounded.

Unless there's some kind of protocol.


Vectors don't have such problems.  We can construct programs where the
size of a vector becomes dependent on scheduling or other
nondeterministic runtime behavior; but channels are inherently tied to
inter-task communication and scheduling, and vectors are not.

But the size of a vector can be dependent on user input and various other things pretty easily as well. I think unbounded channels are no worse than vectors.

For example, processing might happen in stages, and data flows "left
to right", where tasks are either ready to receive any message from
the left, or blocked sending a specific message to the right.  Since
there is never a mismatch in what the receiver expects and what the
sender sends, nor is there a cycle in the blocking sends, there won't
be deadlocks.

I gave an example earlier in which deadlocks can happen.

I haven't thought this through completely, and don’t have a formal
argument, but I am finding these patterns in systems that I’m working
on.  Perhaps this is analogous to how we are generally not worried
that language features like unrestricted function calls and
higher-order functions will make it difficult to avoid infinite
recursion: Programmers have a mental model of how their system is
layered, and they know that calls generally go from higher layers into
lower layers, with few exceptions that they structure in ways that
avoid infinite recursion.

But this argument applies equally well to unbounded channels, in that you can use them safely as long as you think through the way in which you're using them. For example, Servo is architected in such a way so that the channels will never overflow, due to the acknowledgement pattern among other forms of backpressure.

It is clear that you can implement one on top of the other in both directions. The question is how difficult it is to do so, and how much performance you lose.

(4) Servo should implement web semantics without pushing them as
requirements into libstd.

Servo needs an unbounded UI event queue, but that doesn't mean libstd
needs to provide unbounded channels.  Mapping the UI event queue
directly to a libstd channel may be a neat match right now, but it
seems prudent to leave servo product features decoupled from libstd
features and being prepared to introduce intermediate layers, since
servo's product requirements can shift.

Servo is not the only thing that wants unbounded channels. There have been other examples of applications that need unbounded channels on this very list.

I'm not particularly interested in sacrificing performance by not implementing one or the other in libstd. I think it's clear we need both forms of channels, and they should be first-class primitives.

Patrick

_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to