jlm-blog
~jlm

15-Oct-2011

userdel dmr

Filed under: obit — jlm @ 09:19

I’m staggered by the enormous discrepancy in news coverage here, with the media still eulogizing Steve Jobs after a week and a half, Dennis Ritchie passes away, and receives hardly a blip.

How can this be? The man was a giant in the field. He was one of the inventors of C, which became the most successful programming language, remains extremely popular after four decades, and was a direct ancestor to many of the most used languages of the present day. It’s difficult to overstate its impact; nearly all of the software you encounter today — on PCs, on servers, in embedded systems, or anywhere — was written in C or a language that traces back to C. It was Ritchie who decided on one of the keys to C’s success, its “portable assembly” aspect: It had to let you get close to the metal, while still abstracting away the architecture’s particulars. Another aspect to C’s success was its excellent manual written by Ritchie and Brian Kernighan, commonly called simply “K&R”: short, clear, and comprehensive; information rich yet simple writing; it set a standard that few computer texts come close to reaching.

He was a father of Unix, which has led to more of today’s operating systems than you can shake a stick at. The first great wave of webservers was on Solaris and other System V variants. There’s a BSD Unix sitting inside MacOSX and iPhoneOS. Richard Stallman modeled his GNU project on Unix, and Linus Torvalds’ Linux kernel was a clone of Unix’s — and the second great wave of webservers was build on these. Nearly all of the servers you encounter online run operating systems using Ritchie’s designs. And every Android smartphone as well. How is it that one OS family can span such a range? It was Ritchie who pushed for Unix to be rewritten to have a portable core for the bulk of the OS, with the hardware-specific bits isolated away for easy migration to new machines. No operating system had ever done this; it let Unix escape the PDP, and escape it did.

News media be damned. I feel Ritchie’s passing much more keenly than Jobs’. He wasn’t showy, but his influence was legion.

6-Oct-2011

Better SelectableChannel registration in Java NIO

Filed under: programming — jlm @ 12:01

Java NIO’s Selector class is surprisingly difficult to use with multiple threads. Everyone that tries it encounters mysterious blocking, much of which is due to it sharing a lock with SelectableChannel.register. So, if you happen to try to register a channel in a thread other than the selector thread, it blocks that thread until the select is done. Boo.

So, this is a NIO rite of passage of sorts, finding this misfeature and then looking up how to work around it. The usual answer is to keep a ConcurrentQueue of pending registrations, and have your select loop process that queue between select calls. Uggggleeee. It occurred to me that using a synchronization lock, we can do better.

To register a channel and get the SelectionKey:

  synchronized(registerLock) {
      selector.wakeup();
      key = channel.register(selector, operations, attachment);
  }

And in the select loop:

  // before
  synchronized(registerLock) {}
  // between
  numEvents = selector.select(timeout);
  // after

If the loop is before or after when our registration block takes the registerLock, we’re fine, as having the registerLock prevents the loop from reaching select until we’ve registered and released the lock. If the loop is inside select(), then the wakeup() will cause it to exit select, and it won’t re-enter because we hold the registerLock, so we’re fine.

The tricky case is when the loop has the registerLock or is between releasing the registerLock and entering select(). In these cases, the registration block takes the registerLock and races with the loop over select() and wakeup(). Fortunately, the NIO designers anticipated that programmers would have a desire to ensure a Selector wasn’t selecting, even if the wakeup was called in the window between checking it was okay to enter select and actually entering it. Selector.select() returns immediately if wakeup() had been called after that Selector’s prior select(). So, our race doesn’t matter, the select() always exits, and we’re safe.

This is so much simpler than building up a queue of registrations and processing them in the select loop, and we get the SelectionKey right away, I wonder if I’m missing something. Why is the textbook technique to use a ConcurrentQueue, instead of a synchronization lock like this?

Powered by WordPress