volatile is a pre-requisite for implementing atomic types, as used in the post and enkiTS. It is not on its own sufficient however, and so I use both atomic intrinsics and memory barriers where appropriate. This is mentioned in the article, though obviously I need to emphasize the role of volatile more.
For those interested in the implementation of atomic operations see Jeff Preshing's "How Ubisoft Develops Games for Multicore - Before and After C++11", especially after 15m55s in on the video, or slide 37 of the pdf on github.