Skip to content

Instantly share code, notes, and snippets.

@bcantrill
Created January 21, 2014 23:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bcantrill/8550468 to your computer and use it in GitHub Desktop.
Save bcantrill/8550468 to your computer and use it in GitHub Desktop.
Mail exchange with Aram Hăvărneanu on emulating edge-triggered events on event ports -- including a brilliant rant by Aram on why edge-triggered events are, in fact, a terrible idea. ;)
MIME-Version: 1.0
Sender: bryancantrill@gmail.com
Received: by 10.68.33.97 with HTTP; Sat, 21 Dec 2013 00:11:05 -0800 (PST)
In-Reply-To: <CA+0vZFK2i8aq5DUQpt7wdk=QgodKOOEFgU7vz6n1ti0di-r4hw@mail.gmail.com>
References: <CANp9fE8t68+5_oVc=k=7oQPrSCNH5pnLZ2oP9x3YG8g4a9063A@mail.gmail.com>
<CA+0vZFLRGYwysd8kO+KnazBG=vupfORTD+h1yj_dWur2f7LpPQ@mail.gmail.com>
<CA+0vZFLpu5HFhJZLmpm01WOyzHjnaeHrKcuU7YEpMr6hEvyiRA@mail.gmail.com>
<CAAm8y+jXcQ1ix5neUusW6NHXg+mb0V_ZNxrudjTaETdxhUQzKQ@mail.gmail.com>
<F811D3C5-531A-492A-B390-5086F206DD6C@cheney.net>
<CA+0vZFK2i8aq5DUQpt7wdk=QgodKOOEFgU7vz6n1ti0di-r4hw@mail.gmail.com>
Date: Sat, 21 Dec 2013 00:11:05 -0800
Delivered-To: bryancantrill@gmail.com
X-Google-Sender-Auth: 1-P9HY9dQxa-Mr_9AY_InMAQXGE
Message-ID: <CAAm8y+hbBWjw10E6CVjt+ROL-sOGeS1pnahppRVUoGfQHX2snA@mail.gmail.com>
Subject: Re: select and port problems on solaris port
From: Bryan Cantrill <bryan@joyent.com>
To: =?UTF-8?B?QXJhbSBIxIN2xINybmVhbnU=?= <aram@mgk.ro>
Cc: Dave Cheney <dave@cheney.net>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Hey Aram,
Thanks (as always) for your thoughts and guidance. I thought about
this this week, and it seems that one major advantage we have is that
we are actually interposing on all system calls -- we know when the
runtime gets EAGAIN/EWOULDBLOCK/EINPROGRESS from a system call and can
use that to then (and only then) associate the event with the port.
This allows us to effectively replicate edge-triggered events on top
of level-triggered ones. While it still needs some polish (e.g., to
dynamically size the PortPollDesc array), here's a patch that both (1)
passes all tests and (2) doesn't spin on Dave's test:
http://us-east.manta.joyent.com/bcantrill/public/go/edge-triggered-port.diff.txt
Still needs some polish (e.g., I need to update the Perl script that
generates zsyscall_solaris_amd64.go), but I think that this route
seems promising. What do you think?
- Bryan
On Mon, Dec 16, 2013 at 7:32 AM, Aram H=C4=83v=C4=83rneanu <aram@mgk.ro> wr=
ote:
> Oh, how I hate all this stuff in the name of performance.
>
> Edge-triggering is a hack done by people obsessed with reducing
> syscall count. Level triggering is so simple to understand and use.
> You block for something, and once you get it you can do whatever you
> want with it. You can process it synchronously, and then you don't
> have to do anything special, or you can process it asynchronously and
> then the only thing you have to do, the only thing, is to remember to
> add the fd back to the list of interesting fd's once you are done.
> This requirement is trivial, and in fact the explicitness of it is
> quite useful in understanding the code. You can read one byte, a
> hundred. Doesn't matter; you can do whatever you want.
>
> With edge-triggered events it's not like this. At first they seem
> useful because you don't have to remember to add fd's back, but that'a
> a trivial requirement. The downsides are that it's spectacularly easy
> to deadlock, you have to process it asynchronously, and you have to
> process every single byte out of it even if the semantics of the
> application doesn't require it. The kernel does the bookkeeping for
> us, but the kernel doesn't know what we want from it, so the
> programmer has to adapt to a stricter and harder to use programming
> model.
>
> But we're optimised, so making programming harder is okay.
>
> I guess what we have to do is find a way to tell the poller every time
> when we are actually interested in a fd. Now we tell it once we create
> a socket, but we need to tell it after we process any kind of I/O.
> Then we can postpone shoehorning back fd's after we get events until
> we actually care about more events. Unfortunately, this seems very
> hard.
>
> A hack would be to somehow consume the connection-ready event in a
> safe manner. I think if we solve this, the problem goes away (maybe we
> need to do something about errors too). This would be very easy if the
> poller would simple offer hints to the scheduler. Of course, in the
> name of performance, the poller doesn't simply offer hints, it's vital
> to the scheduler function.
>
> I think the easiest way to implement that hack is to special-case
> WaitWrite for Connect (or rather, not use WaitWrite, but WaitConnect
> in Connect). On non-Solaris systems WaitConnect can simply be
> WaitWrite. On Solaris won't (eventually) call runtime=C2=B7netpoll, but i=
t
> will block in port_get.
>
> --
> Aram H=C4=83v=C4=83rneanu
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment