<p><pre><code> import Control.Concurrent.STM
import Control.Monad
import Data.Vector
type VecInts = Vector (TVar Int)
newVecInts :: Int -> STM (VecInts)
newVecInts s = generateM s (\_ -> newTVar 0)
modifyVI :: VecInts -> Int -> Int -> STM ()
modifyVI vi pos val = do
writeTVar (vi ! pos) val
waitUntilEqual :: VecInts -> Int -> Int -> STM ()
waitUntilEqual vi p1 p2 = do
a <- readTVar (vi ! p1)
b <- readTVar (vi ! p2)
when (a /= b) retry</code></pre>
My c++ solution: <a href="https://gist.github.com/anonymous/7e6cc8f58e9cde1b6fda" rel="nofollow">https://gist.github.com/anonymous/7e6cc8f58e9cde1b6fda</a><p>I believe it follows all of the requirements. There is one glaring flaw which is that it uses a condition variable per 'wait_until_equal' call, though it uses only N mutexes. So this doesn't fall under the N^2 primitives (in the case of many waits), though its unclear to me if thats an official rule.<p>Im happy to listen to feedback or if someone sees an error.
This is an example of why I see node.js having more value in its single-threaded async architecture than in its capacity to use the same programming language on client and server.<p>More generally, when you discover a tricky problem that would make a good interview question, oftentimes there's an architectural decision that would eliminate the problem.