Friday, May 14, 2010

Grand Central Dispatch for Win32

So, I’m trying to put together a Grand Central Dispatch workalike for Win32, using the Vista/7 threadpool system behind the scenes.

The essence of GCD is pretty simple, but there are enough wrinkles (target queues and suspension) that a naive implementation won’t work. I can’t just dump things into the pool and forget about them, so instead I have to maintain my own queues of work items and plop them into the pool myself.

Apple’s implementation has the same issue; behind the scenes it uses Apple’s proprietary “pthread_workqueues”, but it layers its own queuing on top.

It’s an interesting experience. One thing I’ve found is that for all the noise that people made about GCD when Snow Leopard was in beta, there’s vanishingly little content about it on the Web. Either nobody is actually using it (which is a pity, because it enables quite a nice coding style for GUI applications), their uses are all extremely simple (such that they only use a relatively small subset of its features), or they’re just not talking about it.

The latter seems a bit strange, because some of its features aren’t entirely obvious. The utility of the ability to set target queues, in particular, is not at all clear.

I wonder if perhaps it’s not useful as such, but rather a feature they added for their NSOperationQueue stuff, which layers on top of GCD to provide some richer capabilities. NSOperationQueue is used to run NSOperation objects, and those objects can have dependencies on other NSOperations. This allows a DAG of NSOperations to be constructed. My speculation is that perhaps it constructs an equivalent DAG of GCD queues, and this is why GCD has the targeting capability. But I don’t really know for sure.

The big sticking point with any implementation will be dispatch sources. Windows has no direct equivalent (its asynchronous/overlapped I/O mechanism works in a fundamentally different way), so it’s going to require some thinking. It would be nice to be able to support dispatch sources for file/socket I/O, and something similar should be feasible. But that will have to wait until I have the fundamentals done.