Efficient thread safe static initialization
Dave MacLachlan, a Mac programmer at Google, discusses thread safe initialization of statics here and here on the Official Google Mac blog offering an interesting peak under the hood of Objective-C and avoiding the pitfalls of the dreaded DCLP.
Bill Bumgarner offered a clever approach: the Objective-C method which initialzes the static uses an expensive lock to ensure that only one thread performs the initialization, but then calls ReplaceMethodImplementationWithSelector so that later calls to that method call an alternate version of the function without the lock. This provides a general solution to the complications of the DCLP, by using a function pointer which initially calls a function with a lock to guard initialization, then replaces the function pointer. This doesn't actually require a function pointer. One just needs a separate global saying, in essence, don't bother with the expensive lock any more. Modifying the objective C method pointer is quite elegant.
I wonder what subtleties I'm missing behind all this.
In the presence of CPU write-reordering, might another threads see the new method or function pointer but the old uninitialized static variable? A lock acts as a write barrier, but both are set between acquiring and releasing the lock, and the faster version of the function has no lock, so there needs to be an additional memory barrier between the initialization and ReplaceMethodImplementationWithSelector, unless one is implicit in the call to ReplaceMethodImplementationWithSelector.
On reflection, this is just the DCLP in disguise. In essence, DCLP is an attempt to avoid an expensive lock by doing a check first to see if its needed. Using a method or function-pointer for dispatch implements that check without an "if" statement, but doesn't eliminate the problems of DCLP in the presence of relaxed consistency when CPUs can reorder memory reads and writes.