diff --git a/CHANGES.txt b/CHANGES.txt
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,8 @@
 Changelog for Shake
 
+0.15.11
+    #488, make sure parallel tracks dependencies
+    #513, permit process-1.4.3.0 and above
 0.15.10
     #465, fix phony names which clash with directories
 0.15.9
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright Neil Mitchell 2011-2016.
+Copyright Neil Mitchell 2011-2017.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/shake.cabal b/shake.cabal
--- a/shake.cabal
+++ b/shake.cabal
@@ -1,13 +1,13 @@
-cabal-version:      >= 1.10
+cabal-version:      >= 1.18
 build-type:         Simple
 name:               shake
-version:            0.15.10
+version:            0.15.11
 license:            BSD3
 license-file:       LICENSE
 category:           Development, Shake
 author:             Neil Mitchell <ndmitchell@gmail.com>
 maintainer:         Neil Mitchell <ndmitchell@gmail.com>
-copyright:          Neil Mitchell 2011-2016
+copyright:          Neil Mitchell 2011-2017
 synopsis:           Build system library, like Make, but more accurate dependencies.
 description:
     Shake is a Haskell library for writing build systems - designed as a
@@ -75,6 +75,7 @@
 
 flag portable
     default: False
+    manual: True
     description: Obtain FileTime using portable functions
 
 library
diff --git a/src/Development/Shake/Core.hs b/src/Development/Shake/Core.hs
--- a/src/Development/Shake/Core.hs
+++ b/src/Development/Shake/Core.hs
@@ -925,15 +925,20 @@
     -- number of items still to complete, or Nothing for has completed (by either failure or completion)
     todo :: Var (Maybe Int) <- liftIO $ newVar $ Just $ length acts
     -- a list of refs where the results go
-    results :: [IORef (Maybe (Either SomeException a))] <- liftIO $ replicateM (length acts) $ newIORef Nothing
+    results :: [IORef (Maybe (Either SomeException (Local, a)))] <- liftIO $ replicateM (length acts) $ newIORef Nothing
 
-    captureRAW $ \continue -> do
+    (locals, results) <- captureRAW $ \continue -> do
         let resume = do
                 res <- liftIO $ sequence . catMaybes <$> mapM readIORef results
-                continue res
+                continue $ fmap unzip res
 
         liftIO $ forM_ (zip acts results) $ \(act, result) -> do
-            let act2 = ifM (liftIO $ isJust <$> readVar todo) act (fail "")
+            let act2 = do
+                    b <- liftIO $ isJust <$> readVar todo
+                    when (not b) $ fail "parallel, one has already failed"
+                    res <- act
+                    old <- Action getRW
+                    return (old, res)
             addPool globalPool $ runAction global local act2 $ \res -> do
                 writeIORef result $ Just res
                 modifyVar_ todo $ \v -> case v of
@@ -941,6 +946,20 @@
                     Just i | i == 1 || isLeft res -> do resume; return Nothing
                     Just i -> return $ Just $ i - 1
 
+    -- don't construct with RecordWildCards so any new fields raise an error
+    modifyRW $ \root -> Local
+        -- immutable/stack that need copying
+        {localStack = localStack root
+        ,localVerbosity = localVerbosity root
+        ,localBlockApply = localBlockApply root
+        -- mutable locals that need integrating
+        ,localDepends = localDepends root ++ concatMap localDepends locals
+        ,localDiscount = localDiscount root + maximum (0:map localDiscount locals)
+        ,localTraces = localTraces root ++ concatMap localTraces locals
+        ,localTrackAllows = localTrackAllows root ++ concatMap localTrackAllows locals
+        ,localTrackUsed = localTrackUsed root ++ concatMap localTrackUsed locals
+        }
+    return results
 
 -- | Run an action but do not depend on anything the action uses.
 --   A more general version of 'orderOnly'.
diff --git a/src/General/Process.hs b/src/General/Process.hs
--- a/src/General/Process.hs
+++ b/src/General/Process.hs
@@ -130,8 +130,9 @@
     -- seems to happen with some GHC 7.2 compiled binaries with FFI etc
     terminateProcess pid
 
-withCreateProcess :: CreateProcess -> ((Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) -> IO a) -> IO a
-withCreateProcess cp act = mask $ \restore -> do
+-- FIXME: There is a new withCreateProcess in process-1.4.3.0 which is probably better than ours...
+withCreateProcessOld :: CreateProcess -> ((Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) -> IO a) -> IO a
+withCreateProcessOld cp act = mask $ \restore -> do
     ans@(inh, outh, errh, pid) <- createProcess cp
     onException (restore $ act ans) $ do
         mapM_ (`whenJust` hClose) [inh, outh, errh]
@@ -157,7 +158,7 @@
         let cp = (cmdSpec poCommand){cwd = poCwd, env = poEnv, create_group = isJust poTimeout, close_fds = True
                  ,std_in = fst $ stdIn inHandle poStdin
                  ,std_out = stdStream outHandle poStdout poStderr, std_err = stdStream outHandle poStderr poStdout}
-        withCreateProcess cp $ \(inh, outh, errh, pid) ->
+        withCreateProcessOld cp $ \(inh, outh, errh, pid) ->
             withTimeout poTimeout (abort pid) $ do
 
                 let streams = [(outh, stdout, poStdout) | Just outh <- [outh], CreatePipe <- [std_out cp]] ++
diff --git a/src/General/Timing.hs b/src/General/Timing.hs
--- a/src/General/Timing.hs
+++ b/src/General/Timing.hs
@@ -2,38 +2,41 @@
 module General.Timing(resetTimings, addTiming, printTimings) where
 
 import Data.IORef
-import Data.Time
 import System.IO.Unsafe
 import Numeric.Extra
 import System.Time.Extra
 
+{-# NOINLINE timer #-}
+timer :: IO Seconds
+timer = unsafePerformIO offsetTime
 
+
 {-# NOINLINE timings #-}
-timings :: IORef [(UTCTime, String)] -- number of times called, newest first
+timings :: IORef [(Seconds, String)] -- number of times called, newest first
 timings = unsafePerformIO $ newIORef []
 
 
 resetTimings :: IO ()
 resetTimings = do
-    now <- getCurrentTime
+    now <- timer
     writeIORef timings [(now, "Start")]
 
 
 -- | Print all withTiming information and clear the information.
 printTimings :: IO ()
 printTimings = do
-    now <- getCurrentTime
+    now <- timer
     old <- atomicModifyIORef timings $ \ts -> ([(now, "Start")], ts)
     putStr $ unlines $ showTimings now $ reverse old
 
 
 addTiming :: String -> IO ()
 addTiming msg = do
-    now <- getCurrentTime
+    now <- timer
     atomicModifyIORef timings $ \ts -> ((now,msg):ts, ())
 
 
-showTimings :: UTCTime -> [(UTCTime, String)] -> [String]
+showTimings :: Seconds -> [(Seconds, String)] -> [String]
 showTimings _ [] = []
 showTimings stop times = showGap $
     [(a ++ "  ", showDP 3 b ++ "s  " ++ showPerc b ++ "  " ++ progress b) | (a,b) <- xs] ++
@@ -44,7 +47,7 @@
         progress x = let i = floor $ x * 25 // mx in replicate i '=' ++ replicate (25-i) ' '
         mx = maximum $ map snd xs
         sm = sum $ map snd xs
-        xs = [ (name, stop `subtractTime` start)
+        xs = [ (name, stop - start)
              | ((start, name), stop) <- zip times $ map fst (drop 1 times) ++ [stop]]
 
 
