diff --git a/Data/Atomics.hs b/Data/Atomics.hs
--- a/Data/Atomics.hs
+++ b/Data/Atomics.hs
@@ -23,39 +23,53 @@
    casArrayElem, casArrayElem2, readArrayElem, 
 
    -- * Atomic operations on byte arrays
-   casByteArrayInt, fetchAddByteArrayInt,
+   casByteArrayInt,
+   fetchAddIntArray,
+   fetchSubIntArray,
+   fetchAndIntArray,
+   fetchNandIntArray,
+   fetchOrIntArray,
+   fetchXorIntArray,
+   -- -- ** Reading and writing with barriers
+   -- atomicReadIntArray,
+   -- atomicWriteIntArray,
       
    -- * Atomic operations on raw MutVars
    -- | A lower-level version of the IORef interface.
    readMutVarForCAS, casMutVar, casMutVar2,
 
    -- * Memory barriers
-   storeLoadBarrier, loadLoadBarrier, writeBarrier
+   storeLoadBarrier, loadLoadBarrier, writeBarrier,
+
+   -- * Deprecated Functions
+   fetchAddByteArrayInt
  ) where
 
-import Control.Monad.ST (stToIO)
 import Control.Exception (evaluate)
 import Data.Primitive.Array (MutableArray(MutableArray))
 import Data.Primitive.ByteArray (MutableByteArray(MutableByteArray))
 import Data.Atomics.Internal
-import Data.Int -- TEMPORARY
-import Debug.Trace
 
 import Data.IORef 
 import GHC.IORef hiding (atomicModifyIORef)
 import GHC.STRef
-import GHC.ST
 #if MIN_VERSION_base(4,7,0)
 import GHC.Prim hiding ((==#))
 import qualified GHC.PrimopWrappers as GPW
 #else
 import GHC.Prim
 #endif
-import GHC.Arr 
 import GHC.Base (Int(I#))
 import GHC.IO (IO(IO))
-import GHC.Word (Word(W#))
+-- import GHC.Word (Word(W#))
 
+
+#if MIN_VERSION_base(4,8,0)
+#else
+import Data.Bits
+import Data.Primitive.ByteArray (readByteArray)
+#endif
+
 #ifdef DEBUG_ATOMICS
 #warning "Activating DEBUG_ATOMICS... NOINLINE's and more"
 {-# NOINLINE seal #-}
@@ -69,6 +83,13 @@
 {-# NOINLINE readMutVarForCAS #-}
 {-# NOINLINE casMutVar #-}
 {-# NOINLINE casMutVar2 #-}
+{-# NOINLINE casByteArrayInt #-}
+{-# NOINLINE fetchAddIntArray #-}
+{-# NOINLINE fetchSubIntArray #-}
+{-# NOINLINE fetchAndIntArray #-}
+{-# NOINLINE fetchNandIntArray #-}
+{-# NOINLINE fetchOrIntArray #-}
+{-# NOINLINE fetchXorIntArray #-}
 #else
 {-# INLINE casIORef #-}
 {-# INLINE casArrayElem2 #-}   
@@ -79,6 +100,12 @@
 {-# INLINE readMutVarForCAS #-}
 {-# INLINE casMutVar #-}
 {-# INLINE casMutVar2 #-}
+{-# INLINE fetchAddIntArray #-}
+{-# INLINE fetchSubIntArray #-}
+{-# INLINE fetchAndIntArray #-}
+{-# INLINE fetchNandIntArray #-}
+{-# INLINE fetchOrIntArray #-}
+{-# INLINE fetchXorIntArray #-}
 #endif
 
 
@@ -122,6 +149,8 @@
 -- Further, this version always returns the /old value/, that was read from the array during
 -- the CAS operation.  That is, it follows the normal protocol for CAS operations
 -- (and matches the underlying instruction on most architectures).
+--
+-- Implies a full memory barrier.
 casByteArrayInt ::  MutableByteArray RealWorld -> Int -> Int -> Int -> IO Int
 casByteArrayInt (MutableByteArray mba#) (I# ix#) (I# old#) (I# new#) =
   IO$ \s1# ->
@@ -136,6 +165,126 @@
   (# s2#, (I# res) #)
   -- I don't know if a let will mak any difference here... hopefully not.
 
+
+--------------------------------------------------------------------------------
+-- Fetch-and-* family of functions:
+
+-- | Atomically add to a word of memory within a `MutableByteArray`, returning
+-- the value *before* the operation. Implies a full memory barrier.
+fetchAddIntArray :: MutableByteArray RealWorld 
+                     -> Int    -- ^ The offset into the array
+                     -> Int    -- ^ The value to be added
+                     -> IO Int -- ^ The value *before* the addition
+fetchAddIntArray (MutableByteArray mba#) (I# offset#) (I# incr#) = IO $ \ s1# -> 
+  let (# s2#, res #) = fetchAddIntArray# mba# offset# incr# s1# in
+-- fetchAddIntArray# changed behavior in 7.10 to return the OLD value, so we
+-- need this to maintain backwards compatibility:
+#if MIN_VERSION_base(4,8,0)
+  (# s2#, (I# res) #)
+#else
+  (# s2#, (I# (res -# incr#)) #)
+#endif
+
+
+-- | Atomically subtract to a word of memory within a `MutableByteArray`,
+-- returning the value *before* the operation. Implies a full memory barrier.
+fetchSubIntArray :: MutableByteArray RealWorld 
+                     -> Int    -- ^ The offset into the array
+                     -> Int    -- ^ The value to be subtracted
+                     -> IO Int -- ^ The value *before* the addition
+fetchSubIntArray = doAtomicRMW 
+#if MIN_VERSION_base(4,8,0)
+                     fetchSubIntArray# 
+#else
+                     (-)
+#endif
+
+-- | Atomically bitwise AND to a word of memory within a `MutableByteArray`,
+-- returning the value *before* the operation. Implies a full memory barrier.
+fetchAndIntArray :: MutableByteArray RealWorld 
+                     -> Int    -- ^ The offset into the array
+                     -> Int    -- ^ The value to be AND-ed
+                     -> IO Int -- ^ The value *before* the addition
+fetchAndIntArray = doAtomicRMW 
+#if MIN_VERSION_base(4,8,0)
+                    fetchAndIntArray# 
+#else
+                    (.&.)
+#endif
+
+-- | Atomically bitwise NAND to a word of memory within a `MutableByteArray`,
+-- returning the value *before* the operation. Implies a full memory barrier.
+fetchNandIntArray :: MutableByteArray RealWorld 
+                     -> Int    -- ^ The offset into the array
+                     -> Int    -- ^ The value to be NAND-ed
+                     -> IO Int -- ^ The value *before* the addition
+fetchNandIntArray = doAtomicRMW 
+#if MIN_VERSION_base(4,8,0)
+                      fetchNandIntArray# 
+#else
+                      nand
+    where nand x y = complement (x .&. y)
+#endif
+
+-- | Atomically bitwise OR to a word of memory within a `MutableByteArray`,
+-- returning the value *before* the operation. Implies a full memory barrier.
+fetchOrIntArray :: MutableByteArray RealWorld 
+                     -> Int    -- ^ The offset into the array
+                     -> Int    -- ^ The value to be OR-ed
+                     -> IO Int -- ^ The value *before* the addition
+fetchOrIntArray = doAtomicRMW 
+#if MIN_VERSION_base(4,8,0)
+                    fetchOrIntArray# 
+#else
+                    (.|.)
+#endif
+
+-- | Atomically bitwise XOR to a word of memory within a `MutableByteArray`,
+-- returning the value *before* the operation. Implies a full memory barrier.
+fetchXorIntArray :: MutableByteArray RealWorld 
+                     -> Int    -- ^ The offset into the array
+                     -> Int    -- ^ The value to be XOR-ed
+                     -> IO Int -- ^ The value *before* the addition
+fetchXorIntArray = doAtomicRMW 
+#if MIN_VERSION_base(4,8,0)
+                     fetchXorIntArray# 
+#else
+                     xor
+#endif
+
+
+-- Internals for our fetch* family of functions, with CAS loop fallbacks for
+-- GHC < 7.10:
+{-# INLINE doAtomicRMW #-}
+#if MIN_VERSION_base(4,8,0)
+doAtomicRMW :: (MutableByteArray# RealWorld -> Int# -> Int# -> State# RealWorld -> (# State# RealWorld, Int# #)) --  primop
+            -> MutableByteArray RealWorld -> Int -> Int -> IO Int      --  exported function
+doAtomicRMW atomicOp# =
+  \(MutableByteArray mba#) (I# offset#) (I# val#) ->
+    IO $ \ s1# -> 
+      let (# s2#, res #) = atomicOp# mba# offset# val# s1# in
+      (# s2#, (I# res) #)
+#else
+doAtomicRMW :: (Int -> Int -> Int)                                     --  fallback op for CAS loop
+            -> MutableByteArray RealWorld -> Int -> Int -> IO Int      --  exported function
+doAtomicRMW op =
+  \mba offset val ->
+    let loop = do
+          old <- readByteArray mba offset
+          let !new = old `op` val
+          actualOld <- casByteArrayInt mba offset old new
+          if old == actualOld
+              then return actualOld
+              else loop
+     in loop
+{-# WARNING fetchSubIntArray "fetchSubIntArray is implemented with a CAS loop on GHC <7.10" #-}
+{-# WARNING fetchAndIntArray "fetchAndIntArray is implemented with a CAS loop on GHC <7.10" #-}
+{-# WARNING fetchNandIntArray "fetchNandIntArray is implemented with a CAS loop on GHC <7.10" #-}
+{-# WARNING fetchOrIntArray "fetchOrIntArray is implemented with a CAS loop on GHC <7.10" #-}
+{-# WARNING fetchXorIntArray "fetchXorIntArray is implemented with a CAS loop on GHC <7.10" #-}
+#endif
+
+
 {-# DEPRECATED fetchAddByteArrayInt "Replaced by fetchAddIntArray which returns the OLD value" #-}
 -- | Atomically add to a word of memory within a `MutableByteArray`.
 -- 
@@ -153,8 +302,58 @@
   (# s2#, (I# res) #)
 #endif
 
+
 --------------------------------------------------------------------------------
+{- WIP. Having trouble writing good tests for these, and not sure how useful
+ - these are. See #43 discussion
+ -
+ - Also remember to add these to the INLINE / NOINLINE section when exported
 
+-- imports for GHC < 7.10 conditionals below.
+#if MIN_VERSION_base(4,8,0)
+#else
+import Control.Monad (void)
+import Data.Primitive.ByteArray (writeByteArray)
+#endif 
+
+
+-- | Given an array and an offset in Int units, read an element. The index is
+-- assumed to be in bounds. Implies a full memory barrier.
+atomicReadIntArray :: MutableByteArray RealWorld -> Int -> IO Int
+#if MIN_VERSION_base(4,8,0)
+atomicReadIntArray (MutableByteArray mba#) (I# ix#) = IO $ \ s# ->
+    case atomicReadIntArray# mba# ix# s# of
+        (# s2#, n# #) -> (# s2#, I# n# #)
+#else
+atomicReadIntArray mba ix = do
+    -- I don't think we can get a full barrier here with the three barriers we
+    -- have exposed, so we use a no-op CAS, which implies a full barrier
+    casByteArrayInt mba ix 0 0
+{-# WARNING atomicReadIntArray "atomicReadIntArray is implemented with a CAS on GHC <7.10 and may be slower than a readByteArray + one of the barriers exposed here" #-}
+#endif
+
+-- | Given an array and an offset in Int units, write an element. The index is
+-- assumed to be in bounds. Implies a full memory barrier.
+atomicWriteIntArray :: MutableByteArray RealWorld -> Int -> Int -> IO ()
+#if MIN_VERSION_base(4,8,0)
+atomicWriteIntArray (MutableByteArray mba#) (I# ix#) (I# n#) = IO $ \ s# ->
+    case atomicWriteIntArray# mba# ix# n# s# of
+        s2# -> (# s2#, () #)
+#else
+atomicWriteIntArray mba ix n = do
+    -- As above we use a no-op CAS to get a full barrier. This is particularly
+    -- gross TODO something better if possible
+    let fullBarrier = void $ casByteArrayInt mba ix 0 0
+    fullBarrier
+    writeByteArray mba ix n
+    fullBarrier
+{-# WARNING atomicWriteIntArray "atomicWriteIntArray is likely to be very slow on GHC <7.10. Consider using writeByteArray along with one of the barriers exposed here instead" #-}
+#endif
+
+-}
+
+--------------------------------------------------------------------------------
+
 -- | Ordinary processor load instruction (non-atomic, not implying any memory barriers).
 -- 
 --   The difference between this function and `readIORef`, is that it returns a /ticket/,
@@ -229,8 +428,8 @@
 casMutVar2 :: MutVar# RealWorld a -> Ticket a -> Ticket a -> IO (Bool, Ticket a)
 casMutVar2 mv tick new = IO$ \st -> 
   case casMutVarTicketed# mv tick new st of 
-    (# st, flag, tick' #) ->
-      (# st, (flag ==# 0#, tick') #)
+    (# st', flag, tick' #) ->
+      (# st', (flag ==# 0#, tick') #)
 --      (# st, if flag ==# 0# then Succeed tick' else Fail tick' #)
 --      if flag ==# 0#    then       else (# st, Fail (W# tick')  #)
 
@@ -293,7 +492,7 @@
    loop tick effort
   where 
    effort = 30 :: Int -- TODO: Tune this.
-   loop old 0     = atomicModifyIORef ref fn -- Fall back to the regular version.
+   loop _   0     = atomicModifyIORef ref fn -- Fall back to the regular version.
    loop old tries = do 
      (new,result) <- evaluate $ fn $ peekTicket old
      (b,tick) <- casIORef ref old new
@@ -312,13 +511,12 @@
    loop tick effort
   where 
    effort = 30 :: Int -- TODO: Tune this.
-   loop old 0     = atomicModifyIORef_ ref fn
+   loop _   0     = atomicModifyIORef ref (\ x -> (fn x, ()))
    loop old tries = do 
      new <- evaluate $ fn $ peekTicket old
      (b,val) <- casIORef ref old new
      if b 
       then return ()
       else loop val (tries-1)
-   atomicModifyIORef_ ref fn = atomicModifyIORef ref (\ x -> (fn x, ()))
 -- </duplicated code>
 
diff --git a/Data/Atomics/Counter.hs b/Data/Atomics/Counter.hs
--- a/Data/Atomics/Counter.hs
+++ b/Data/Atomics/Counter.hs
@@ -32,17 +32,12 @@
  where
 
 
-import GHC.Ptr
-import Data.Atomics          (casByteArrayInt)
--- import Data.Atomics.Internal (casIntArray#, fetchAddIntArray#)
 import Data.Atomics.Internal
 #if MIN_VERSION_base(4,7,0)
 import GHC.Base  hiding ((==#))
-import GHC.Prim hiding ((==#))
 import qualified GHC.PrimopWrappers as GPW
 #else
 import GHC.Base
-import GHC.Prim
 #endif
 
 
@@ -83,23 +78,23 @@
 {-# INLINE newRawCounter #-}
 newRawCounter :: IO AtomicCounter  
 newRawCounter = IO $ \s ->
-  case newByteArray# size s of { (# s, arr #) ->
-  (# s, AtomicCounter arr #) }
+  case newByteArray# size s of { (# s', arr #) ->
+  (# s', AtomicCounter arr #) }
   where !(I# size) = SIZEOF_HSINT
 
 {-# INLINE readCounter #-}
 -- | Equivalent to `readCounterForCAS` followed by `peekCTicket`.        
 readCounter :: AtomicCounter -> IO Int
 readCounter (AtomicCounter arr) = IO $ \s ->
-  case readIntArray# arr 0# s of { (# s, i #) ->
-  (# s, I# i #) }
+  case readIntArray# arr 0# s of { (# s', i #) ->
+  (# s', I# i #) }
 
 {-# INLINE writeCounter #-}
 -- | Make a non-atomic write to the counter.  No memory-barrier.
 writeCounter :: AtomicCounter -> Int -> IO ()
 writeCounter (AtomicCounter arr) (I# i) = IO $ \s ->
-  case writeIntArray# arr 0# i s of { s ->
-  (# s, () #) }
+  case writeIntArray# arr 0# i s of { s' ->
+  (# s', () #) }
 
 {-# INLINE readCounterForCAS #-}
 -- | Just like the "Data.Atomics" CAS interface, this routine returns an opaque
@@ -127,9 +122,9 @@
     False -> (# s2#, (False, I# res# ) #) -- Failure
     True  -> (# s2#, (True , newBox ) #) -- Success
 
-{-# INLINE sameCTicket #-}
-sameCTicket :: CTicket -> CTicket -> Bool
-sameCTicket = (==)
+-- {-# INLINE sameCTicket #-}
+-- sameCTicket :: CTicket -> CTicket -> Bool
+-- sameCTicket = (==)
 
 {-# INLINE incrCounter #-}
 -- | Increment the counter by a given amount.  Returns the value AFTER the increment
@@ -154,5 +149,7 @@
 -- | An alternate version for when you don't care about the old value.
 incrCounter_ :: Int -> AtomicCounter -> IO ()
 incrCounter_ (I# incr#) (AtomicCounter mba#) = IO $ \ s1# -> 
-  let (# s2#, res #) = fetchAddIntArray# mba# 0# incr# s1# in
+  -- NOTE: either old or new behavior of fetchAddIntArray# is fine here, since
+  -- we don't inspect the return value:
+  let (# s2#, _ #) = fetchAddIntArray# mba# 0# incr# s1# in
   (# s2#, () #)
diff --git a/Data/Atomics/Internal.hs b/Data/Atomics/Internal.hs
--- a/Data/Atomics/Internal.hs
+++ b/Data/Atomics/Internal.hs
@@ -16,18 +16,17 @@
   where 
 
 import GHC.Base (Int(I#))
-import GHC.Word (Word(W#))
-import GHC.Prim (RealWorld, Int#, Word#, State#, MutableArray#, MutVar#,
-                 MutableByteArray#, 
+import GHC.Prim (RealWorld, Int#, State#, MutableArray#, MutVar#,
                  unsafeCoerce#, reallyUnsafePtrEquality#) 
 
 #if MIN_VERSION_base(4,7,0)
 import GHC.Prim (casArray#, casIntArray#, fetchAddIntArray#, Any, readMutVar#, casMutVar#)
 #elif MIN_VERSION_base(4,6,0)
 -- Any is only supported in the FFI in the way we need in GHC 7.6+
-import GHC.Prim (readMutVar#, casMutVar#, Any)
+import GHC.Prim (readMutVar#, Any, MutableByteArray#)
 #else
 #error "Need to figure out how to emulate Any () in GHC <= 7.4 !"
+-- import GHC.Prim (Word#)
 -- type Any a = Word#
 #endif    
 
diff --git a/atomic-primops.cabal b/atomic-primops.cabal
--- a/atomic-primops.cabal
+++ b/atomic-primops.cabal
@@ -1,5 +1,5 @@
 Name:                atomic-primops
-Version:             0.7
+Version:             0.8
 License:             BSD3
 License-file:        LICENSE
 Author:              Ryan Newton
@@ -34,7 +34,7 @@
 -- 0.6.0.1 -- minor ghc 7.8 fix
 -- 0.6.0.5 -- fix for GHC 7.8
 -- 0.6.1   -- several bug fixes, mainly re: platform portability
--- 0.7     -- support for GHC 7.10 and several new primops
+-- 0.8     -- support for GHC 7.10 and several new primops
 
 Synopsis: A safe approach to CAS and other atomic ops in Haskell.
 
@@ -82,11 +82,15 @@
  Changes in 0.7: 
  .
  * This release adds support for GHC 7.10 and its expanded library of (now inline) primops.
+ .
+ Changes in 0.8: 
+ .
+ * Implements additional fetch primops available in GHC 7.10
 
 
 Extra-Source-Files:  DEVLOG.md,
                      testing/Test.hs, testing/test-atomic-primops.cabal, testing/ghci-test.hs
-                     testing/Makefile, testing/CommonTesting.hs, testing/Counter.hs, testing/hello.hs
+                     testing/Makefile, testing/CommonTesting.hs, testing/Counter.hs, testing/CounterCommon.hs, testing/hello.hs
                      testing/Issue28.hs
                      testing/TemplateHaskellSplices.hs
                      testing/Raw781_test.hs
@@ -101,6 +105,7 @@
                      Data.Atomics.Internal
                      Data.Atomics.Counter
   ghc-options: -O2 -funbox-strict-fields
+  ghc-options: -Wall
 
   -- casMutVar# had a bug in GHC 7.2, thus we require GHC 7.4 or greater
   -- (base 4.5 or greater). We also need the "Any" kind.
diff --git a/testing/CommonTesting.hs b/testing/CommonTesting.hs
--- a/testing/CommonTesting.hs
+++ b/testing/CommonTesting.hs
@@ -13,7 +13,7 @@
 import System.CPUTime
 import System.Mem.StableName (makeStableName, hashStableName)
 import System.Environment (getEnvironment)
-import System.IO        (stdout, stderr, hPutStrLn, hFlush)
+import System.IO        (stderr, hPutStrLn, hFlush)
 import Debug.Trace      (trace)
 
 -- import Test.Framework.TH (defaultMainGenerator)
@@ -84,8 +84,8 @@
     start <- getCPUTime
     v <- a
     end   <- getCPUTime
-    let diff = (fromIntegral (end - start)) / (10^12)
-    printf "SELFTIMED: %0.3f sec\n" (diff :: Double)
+    let diff = (fromIntegral (end - start)) / (10^(12::Int))
+    _ <- printf "SELFTIMED: %0.3f sec\n" (diff :: Double)
     return v
 
 
@@ -106,7 +106,7 @@
 --
 --  INLINE should not affect recursive functions.  But here it seems to have a
 --  deleterious effect!
-nTimes 0 !c = return ()
+nTimes 0  _  = return ()
 nTimes !n !c = c >> nTimes (n-1) c
 
 
diff --git a/testing/Counter.hs b/testing/Counter.hs
--- a/testing/Counter.hs
+++ b/testing/Counter.hs
@@ -1,148 +1,14 @@
+{-# LANGUAGE CPP #-}
 module Counter (tests) where
-
--- This was formerly CounterCommon and #include-ed to test the different
--- counter implementations which have been removed. 
--- TODO clean up remnants of that approach.
 import qualified Data.Atomics.Counter as C
 
-import Control.Monad
-import GHC.Conc
-import System.CPUTime
-import Test.Framework.Providers.HUnit (testCase)
-import Test.HUnit (Assertion, assertEqual, assertBool)
-import Text.Printf
-import Data.IORef  
-
-import CommonTesting (numElems, forkJoin, timeit, nTimes)
+#include "CounterCommon.hs"
 
+name :: String
 name = "Unboxed"
 
+default_seq_tries, default_conc_tries :: Int
 default_seq_tries  = 10 * numElems
 -- Things are MUCH slower with contention:
 default_conc_tries = numElems
 
---------------------------------------------------------------------------------
--- Test the basics
-
-case_basic1 = do 
-  r <- C.newCounter 0
-  ret <- C.incrCounter 10 r
-  assertEqual "incrCounter returns the NEW value" 10 ret
-
-case_basic2 = do 
-  r <- C.newCounter 0
-  t <- C.readCounterForCAS r
-  (True,newt) <- C.casCounter r t 10
-  assertEqual "casCounter returns new val/ticket on success" 10 (C.peekCTicket newt)
-
-case_basic3 = do 
-  r <- C.newCounter 0
-  t <- C.readCounterForCAS r
-  _ <- C.incrCounter 1 r
-  (False,oldt) <- C.casCounter r t 10
-  assertEqual "casCounter returns read val on failure" 1 (C.peekCTicket oldt)
-
-case_basic4 = do 
-  let tries = numElems `quot` 100
-  r <- C.newCounter 0
-  nTimes tries $ do
-    t <- C.readCounterForCAS r
-    (True,_) <- C.casCounter r t (C.peekCTicket t + 1)
-    return ()
-  cnt <- C.readCounter r
-  assertEqual "Every CAS should succeed on one thread" tries cnt 
-
---------------------------------------------------------------------------------
--- Repeated increments
-
-incrloop tries = do r <- C.newCounter 0; nTimes tries $ void$ C.incrCounter 1 r
-                    C.readCounter r
-case_incrloop = do 
-   cnt <- incrloop default_seq_tries
-   assertEqual "incrloop sum" default_seq_tries cnt
-
--- | Here we do a loop to test the unboxing of results from incrCounter:
---   As of now [2013.07.19], it is successfully unboxing the results 
---   for Data.Atomics.Counter.Unboxed.
-incrloop4B tries = do
-  putStrLn " [incrloop4B] A test where we use the result of each incr."
-  r <- C.newCounter 1
-  loop r tries 1
- where
-   loop :: C.AtomicCounter -> Int -> Int -> IO ()
-   loop r 0 _ = do v <- C.readCounter r
-                   putStrLn$"Final value: "++show v
-                   return ()
-   loop r tries last = do
-     n <- C.incrCounter last r
-     if n == 2
-       then loop r (tries-1) 2
-       else loop r (tries-1) 1
-
--- | Here we let the counter overflow, which seems to be causing problems.
-overflowTest tries = do
-  putStrLn " [incrloop4B] A test where we use the result of each incr."
-  r <- C.newCounter 1
-  loop r tries 1
- where
-   loop :: C.AtomicCounter -> Int -> Int -> IO ()
-   loop r 0 _ = do v <- C.readCounter r
-                   putStrLn$"Final value: "++show v
-                   return ()
-   loop r tries last = do
-     putStrLn$ " [incrloop4B] Looping with tries left "++show tries 
-     n <- C.incrCounter last r
-     -- This is HANGING afer passing 2,147,483,648.  (using Unboxed)
-     -- Is there some defect wrt overflow?
-     putStrLn$ " [incrloop4B] Done incr, received "++show n
-     loop r (tries-1) n
-
---------------------------------------------------------------------------------
--- Parallel repeated increments
-
-
-{-# INLINE parIncrloop #-} 
-parIncrloop new incr iters = do
-  numcap <- getNumCapabilities
-  let (each,left) = iters `quotRem` numcap
-  putStrLn$ "Concurrently incrementing counter from all "++show numcap++" threads, incrs per thread: "++show each
-  r <- new 0
-  forkJoin numcap $ \ ix -> do
-    let mine = if ix==0 then each+left else each
-    nTimes mine $ void $ incr 1 r
-  C.readCounter r
-
-case_parincrloop = do 
-  cnt <- parIncrloop C.newCounter C.incrCounter default_conc_tries
-  assertEqual "incrloop sum" default_conc_tries cnt
-
--- | Use CAS instead of the real incr so we can compare the overhead.
-case_parincrloop_wCAS = do 
-  cnt <- parIncrloop C.newCounter fakeIncr default_conc_tries
-  assertEqual "incrloop sum" default_conc_tries cnt
- where
-  fakeIncr delt r = do tick <- C.readCounterForCAS r
-                       loop r delt tick
-  loop r delt tick = do x <- C.casCounter r tick (C.peekCTicket tick + delt)
-                        case x of 
-                          (True, newtick) -> return (C.peekCTicket newtick)
-                          (False,newtick) -> loop r delt newtick
-                   
-
---------------------------------------------------------------------------------
-
-tests = 
- [
-   testCase (name++"basic1_incrCounter") $ case_basic1
- , testCase (name++"basic2_casCounter") $ case_basic2
- , testCase (name++"basic3_casCounter") $ case_basic3
- , testCase (name++"basic4_casCounter") $ case_basic4
-   ----------------------------------------
- , testCase (name++"_single_thread_repeat_incr") $ timeit case_incrloop
- , testCase (name++"_incr_with_result_feedback") $ timeit (incrloop4B default_seq_tries)
-   ----------------------------------------
-
-   -- Parallel versions:
- , testCase (name++"_concurrent_repeat_incr") $ void$ timeit case_parincrloop
- , testCase (name++"_concurrent_repeat_incrCAS") $ void$ timeit case_parincrloop_wCAS
- ]
diff --git a/testing/CounterCommon.hs b/testing/CounterCommon.hs
new file mode 100644
--- /dev/null
+++ b/testing/CounterCommon.hs
@@ -0,0 +1,152 @@
+-- Common tests to the different counter implementations. N.B. #included from
+-- other projects via soft links!
+
+import Control.Monad
+import GHC.Conc
+import Test.Framework.Providers.HUnit (testCase)
+import Test.Framework(Test)
+import Test.HUnit (assertEqual)
+
+import CommonTesting (numElems, forkJoin, timeit, nTimes)
+
+--------------------------------------------------------------------------------
+-- Test the basics
+
+case_basic1 :: IO ()
+case_basic1 = do 
+  r <- C.newCounter 0
+  ret <- C.incrCounter 10 r
+  assertEqual "incrCounter returns the NEW value" 10 ret
+
+case_basic2 :: IO ()
+case_basic2 = do 
+  r <- C.newCounter 0
+  t <- C.readCounterForCAS r
+  (True,newt) <- C.casCounter r t 10
+  assertEqual "casCounter returns new val/ticket on success" 10 (C.peekCTicket newt)
+
+case_basic3 :: IO ()
+case_basic3 = do 
+  r <- C.newCounter 0
+  t <- C.readCounterForCAS r
+  _ <- C.incrCounter 1 r
+  (False,oldt) <- C.casCounter r t 10
+  assertEqual "casCounter returns read val on failure" 1 (C.peekCTicket oldt)
+
+case_basic4 :: IO ()
+case_basic4 = do 
+  let tries = numElems `quot` 100
+  r <- C.newCounter 0
+  nTimes tries $ do
+    t <- C.readCounterForCAS r
+    (True,_) <- C.casCounter r t (C.peekCTicket t + 1)
+    return ()
+  cnt <- C.readCounter r
+  assertEqual "Every CAS should succeed on one thread" tries cnt 
+
+--------------------------------------------------------------------------------
+-- Repeated increments
+
+incrloop :: Int -> IO Int
+incrloop tries = do r <- C.newCounter 0; nTimes tries $ void$ C.incrCounter 1 r
+                    C.readCounter r
+
+case_incrloop :: IO ()
+case_incrloop = do 
+   cnt <- incrloop default_seq_tries
+   assertEqual "incrloop sum" default_seq_tries cnt
+
+-- | Here we do a loop to test the unboxing of results from incrCounter:
+--   As of now [2013.07.19], it is successfully unboxing the results 
+--   for Data.Atomics.Counter.Unboxed.
+incrloop4B :: Int -> IO ()
+incrloop4B tries = do
+  putStrLn " [incrloop4B] A test where we use the result of each incr."
+  r <- C.newCounter 1
+  loop r tries 1
+ where
+   loop :: C.AtomicCounter -> Int -> Int -> IO ()
+   loop r 0 _ = do v <- C.readCounter r
+                   putStrLn$"Final value: "++show v
+                   return ()
+   loop r i l = do
+     n <- C.incrCounter l r
+     if n == 2
+       then loop r (i-1) 2
+       else loop r (i-1) 1
+
+-- | Here we let the counter overflow, which seems to be causing problems.
+-- NOTE 2/3/2015: THIS APPEARS TO BE WORKING NOW -Brandon 
+overflowTest :: Int -> IO ()
+overflowTest tries = do
+  putStrLn " [incrloop4B] A test where we use the result of each incr."
+  r <- C.newCounter 1
+  loop r tries 1
+ where
+   loop :: C.AtomicCounter -> Int -> Int -> IO ()
+   loop r 0 _ = do v <- C.readCounter r
+                   putStrLn$"Final value: "++show v
+                   return ()
+   loop r i l = do
+     --putStrLn$ " [incrloop4B] Looping with tries left "++show i 
+     n <- C.incrCounter l r
+     -- This is HANGING afer passing 2,147,483,648.  (using Unboxed)
+     -- Is there some defect wrt overflow?
+     --putStrLn$ " [incrloop4B] Done incr, received "++show n
+     loop r (i-1) n
+
+--------------------------------------------------------------------------------
+-- Parallel repeated increments
+
+
+{-# INLINE parIncrloop #-} 
+parIncrloop :: (Int -> IO C.AtomicCounter)
+            -> (Int -> C.AtomicCounter -> IO Int) -> Int -> IO Int
+parIncrloop new incr iters = do
+  numcap <- getNumCapabilities
+  let (each,left) = iters `quotRem` numcap
+  putStrLn$ "Concurrently incrementing counter from all "++show numcap++" threads, incrs per thread: "++show each
+  r <- new 0
+  void $ forkJoin numcap $ \ ix -> do
+    let mine = if ix==0 then each+left else each
+    nTimes mine $ void $ incr 1 r
+  C.readCounter r
+
+case_parincrloop :: IO ()
+case_parincrloop = do 
+  cnt <- parIncrloop C.newCounter C.incrCounter default_conc_tries
+  assertEqual "incrloop sum" default_conc_tries cnt
+
+-- | Use CAS instead of the real incr so we can compare the overhead.
+case_parincrloop_wCAS :: IO ()
+case_parincrloop_wCAS = do 
+  cnt <- parIncrloop C.newCounter fakeIncr default_conc_tries
+  assertEqual "incrloop sum" default_conc_tries cnt
+ where
+  fakeIncr delt r = do tick <- C.readCounterForCAS r
+                       loop r delt tick
+  loop r delt tick = do x <- C.casCounter r tick (C.peekCTicket tick + delt)
+                        case x of 
+                          (True, newtick) -> return (C.peekCTicket newtick)
+                          (False,newtick) -> loop r delt newtick
+                   
+
+--------------------------------------------------------------------------------
+
+tests :: [Test]
+tests = 
+ [
+   testCase (name++"_basic1_incrCounter") $ case_basic1
+ , testCase (name++"_basic2_casCounter") $ case_basic2
+ , testCase (name++"_basic3_casCounter") $ case_basic3
+ , testCase (name++"_basic4_casCounter") $ case_basic4
+   ----------------------------------------
+ , testCase (name++"_single_thread_repeat_incr") $ timeit case_incrloop
+ , testCase (name++"_incr_with_result_feedback") $ timeit (incrloop4B default_seq_tries)
+ , testCase (name++"_overflow_test") $ timeit (overflowTest 100000)
+   ----------------------------------------
+
+   -- Parallel versions:
+ , testCase (name++"_concurrent_repeat_incr") $ void$ timeit case_parincrloop
+ , testCase (name++"_concurrent_repeat_incrCAS") $ void$ timeit case_parincrloop_wCAS
+ ]
diff --git a/testing/Issue28.hs b/testing/Issue28.hs
--- a/testing/Issue28.hs
+++ b/testing/Issue28.hs
@@ -1,11 +1,12 @@
 
 module Issue28 (main) where
 
-import Control.Monad
+-- import Control.Monad
 import Data.IORef
 import Data.Atomics
 -- import Data.Atomics.Internal (ptrEq)
 
+main :: IO ()
 main = do
   putStrLn "Issue28: Conducting the simplest possible read-then-CAS test."
   r <- newIORef "hi"
@@ -18,4 +19,3 @@
   -- unless (b1 == True) $ error "Test failed"  
 
   putStrLn$  "Issue28: test passed "++show t1
-  return ()
diff --git a/testing/Test.hs b/testing/Test.hs
--- a/testing/Test.hs
+++ b/testing/Test.hs
@@ -22,18 +22,18 @@
 import GHC.Stats (getGCStats, GCStats(..))
 import System.Random (randomIO, randomRIO)
 import Test.HUnit (Assertion, assertEqual, assertBool)
-import Test.Framework  (defaultMain)
+import Test.Framework  (defaultMain,testGroup,mutuallyExclusive)
 import Test.Framework.Providers.HUnit (testCase)
 import System.Mem (performGC)
 
 ----------------------------------------
 import Data.Atomics as A
-import Data.Atomics (casArrayElem, readArrayElem)
 
 import qualified Issue28
 
 import CommonTesting 
 import qualified Counter
+import qualified Fetch
 
 ------------------------------------------------------------------------
 
@@ -53,8 +53,12 @@
        -- numcap <- getNumProcessors
        let numcap = 4
        when (numCapabilities /= numcap) $ setNumCapabilities numcap
-       
+
        defaultMain $ 
+        -- Make these run sequentially (hopefully), so we don't interfere with
+        -- concurrent tests. TODO I guess: figure out how to run tests that
+        -- don't fork in parallel, but forking tests sequentially
+        return $ mutuallyExclusive $ testGroup "All tests" $
          [ testCase "casTicket1"              case_casTicket1
          , testCase "issue28_standalone"      case_issue28_standalone
          , testCase "issue28_copied "         case_issue28_copied
@@ -89,6 +93,7 @@
          , iters   <- [10000]]
 
          ++ Counter.tests
+         ++ Fetch.tests
 
 setify :: [Int] -> [Int]
 setify = S.toList . S.fromList
@@ -115,11 +120,11 @@
  writeArray arr 4 33
  putStrLn "Wrote array elements..."
  
- tick <- readArrayElem arr 4
+ tick <- A.readArrayElem arr 4
  putStrLn$ "(Peeking at array gave: "++show (peekTicket tick)++")"
 
- (res1,tick2) <- casArrayElem arr 4 tick 44
- (res2,_)     <- casArrayElem arr 4 tick 44
+ (res1,_tick2) <- A.casArrayElem arr 4 tick 44
+ (res2,_)     <- A.casArrayElem arr 4 tick 44
 -- res  <- stToIO$ casArrayST arr 4 mynum 44
 -- res2 <- stToIO$ casArrayST arr 4 mynum 44 
 
@@ -141,12 +146,12 @@
 test_random_array_comm :: Int -> Int -> Int -> IO ()
 test_random_array_comm threads size iters = do 
   arr <- newArray size Nothing
-  tick0 <- readArrayElem arr 0
+  tick0 <- A.readArrayElem arr 0
   for_ 1 size $ \ i -> do
-    t2 <- readArrayElem arr i
+    t2 <- A.readArrayElem arr i
     assertEqual "All initial Nothings in the array should be ticket-equal:" tick0 t2
 
-  ls <- forkJoin threads $ \tid -> do 
+  ls <- forkJoin threads $ \_tid -> do 
     localAcc <- newIORef 0
     for_ 0 iters $ \iter -> do
       -- Randomly pick a position:
@@ -154,13 +159,12 @@
       -- Randomly either produce or consume:
       b <- randomIO :: IO Bool
       if b then do 
-        (b,newtick) <- casArrayElem arr ix tick0 (Just iter)
-        return ()
+        void $ A.casArrayElem arr ix tick0 (Just iter)
        else do -- Consume:
-        tick <- readArrayElem arr ix
+        tick <- A.readArrayElem arr ix
         case peekTicket tick of
-          Just _  -> do (b,x) <- casArrayElem arr ix tick (peekTicket tick0) -- Set back to Nothing.
-                        when b $ modifyIORef' localAcc (+1)
+          Just _  -> do (success,_) <- A.casArrayElem arr ix tick (peekTicket tick0) -- Set back to Nothing.
+                        when success $ modifyIORef' localAcc (+1)
 --                        print (peekTicket x)
           Nothing -> return ()
         return ()
@@ -169,13 +173,13 @@
   let successes = sum ls
       -- Pidgeonhole principle.
       -- min_success =
-  printf "Communication through random array positions (threads/size/iters %s).\n" (show (threads,size,iters))
-  printf "Successes: %d (expected 1/4 of total iterations on all threads)\n" successes
-  printf "Per-thread successes: %s\n" (show ls)
+  _ <- printf "Communication through random array positions (threads/size/iters %s).\n" (show (threads,size,iters))
+  _ <- printf "Successes: %d (expected 1/4 of total iterations on all threads)\n" successes
+  _ <- printf "Per-thread successes: %s\n" (show ls)
   assertBool "Number of successes: " (successes <= (threads * iters) `quot` 2 && successes >= 0)
   for_ 0 size $ \ i -> do
-    x <- readArray arr i
---    putStr (show x ++ " ")
+    _x <- readArray arr i
+--    putStr (show _x ++ " ")
     return ()
   putStrLn ""
   return ()
@@ -185,12 +189,6 @@
 -- Simple, non-parameterized tests
  ----------------------------------------------------------------------------------------------------
 
-{-# NOINLINE zer #-}
-zer :: Int
-zer = 0
-default_iters :: Int
-default_iters = 100000
-
 case_casTicket1 :: IO ()
 case_casTicket1 = do
   dbgPrint 1 "\nUsing new 'ticket' based compare and swap:"
@@ -221,7 +219,7 @@
 case_issue28_copied = do 
   r  <- newIORef "hi"
   t0 <- readForCAS r
-  (True,t1) <- casIORef r t0 "bye"
+  (True,_t1) <- casIORef r t0 "bye"
   return ()
 
 ---- toddaaro's tests -----
@@ -249,9 +247,9 @@
   dbgPrint 1$ "  Creating a single 'ticket' based variable to mutate twice."
   x <- newIORef (0::Int)
   tick1 <- A.readForCAS(x)
-  res1 <- A.casIORef x tick1 5
+  void $ A.casIORef x tick1 5
   tick2 <- A.readForCAS(x)
-  res2 <- A.casIORef x tick2 120
+  void $ A.casIORef x tick2 120
   valf <- readIORef x
   assertBool "Does the value after the first mutate equal 5?" (peekTicket tick2 == 5)
   assertBool "Does the value after the second mutate equal 120?" (valf == 120)
@@ -264,8 +262,8 @@
   dbgPrint 1$ "   Creating 120 threads and having each increment a counter value."
   counter <- newIORef (0::Int)
 --  let work :: Int -> IORef Int -> IO (Int,StableName Int,Int,StableName Int,Int)
-  let work :: Int -> IORef Int -> IO (Int,Int,Int,Int,Int)
-      work ix counter = do
+  let work :: Int -> IO (Int,Int,Int,Int,Int)
+      work ix = do
         tick <- A.readForCAS(counter)
         let nxt = peekTicket tick + 1
         (b,was) <- A.casIORef counter tick nxt
@@ -279,8 +277,8 @@
           putStr "!"
 --          putStrLn $ "("++ show ix ++ ": Fail when putting "++show nxt
 --                     ++", was already "++show (peekTicket was) ++")"
-          work ix counter
-  arr <- forkJoin 120 (\i -> work i counter) 
+          work ix
+  arr <- forkJoin 120 work 
   ans <- readIORef counter
 
   let dups = [ n | (_,_,_,_,n) <- arr] \\ [1..120]
@@ -306,13 +304,13 @@
 
 -- | First test: Run a simple CAS a small number of times.
 test_succeed_once :: (Show a, Num a, Eq a) => a -> Assertion
-test_succeed_once n = 
+test_succeed_once initialVal = 
   do
      performGC -- We *ASSUME* GC does not happen below.
      performGC -- We *ASSUME* GC does not happen below.
      checkGCStats
      gc1 <- getGCCount 
-     r <- newIORef n
+     r <- newIORef initialVal
      bitls <- newIORef []
      tick1 <- A.readForCAS r
      let loop 0 = return ()
@@ -321,7 +319,7 @@
           atomicModifyIORef bitls (\x -> (res:x, ()))
 --          putStrLn$ "  CAS result: " ++ show res
           loop (n-1)
-     loop 10
+     loop (10::Int)
 
      x <- readIORef r
      assertEqual "Finished with loop, read cell: " 100 x
@@ -332,7 +330,7 @@
 
      ls <- readIORef bitls
      let rev = (reverse ls)
-         tickets = map snd rev
+      -- tickets = map snd rev
          (hd:tl) = map fst rev
 
      gc2 <- getGCCount
@@ -402,6 +400,149 @@
              (total_success >= expected_success)
 
 
+
+------------------------------------------------------------------------
+-- Reads and Writes with full barriers:
+{- 
+ - WIP
+
+import Data.Atomics (atomicReadIntArray, atomicWriteIntArray)
+import Data.Primitive
+import Control.Concurrent
+import Data.List(sort)
+
+-- TODO DEBUGGING: for required NoBuffering
+import System.IO
+
+
+test_atomic_read_write_sanity :: IO ()
+test_atomic_read_write_sanity = do
+    mba <- newByteArray (sizeOf (undefined :: Int))
+    atomicWriteIntArray mba 0 0
+    x <- atomicReadIntArray mba 0
+    atomicWriteIntArray mba 0 1
+    y <- atomicReadIntArray mba 0
+    assertEqual "test_atomic_read_write_sanity x" x 0
+    assertEqual "test_atomic_read_write_sanity y" y 1
+
+-- These don't really adequately test that we have a *full* barrier, but only
+-- store/store and load/load I think. TODO something better
+test_atomic_read_write_barriers1, test_atomic_read_write_barriers2 :: Int -> IO ()
+
+-- NOTE: We don't observe failure here on x86 with non-atomic reads/writes, but
+-- maybe it will for other architectures. Otherwise this can be removed.
+test_atomic_read_write_barriers1 iters = do
+    let theWrite mba = atomicWriteIntArray mba 0
+        theRead mba = atomicReadIntArray mba 0
+    {- NOTE: We would like this to fail (but it seems to work on x86)
+    let theWrite mba = writeByteArray mba 0
+        theRead mba = readByteArray mba 0
+     -}
+    -- For kicks, a bunch of padding to ensure these are on different cache-lines:
+    mba0 <- newByteArray (sizeOf (undefined :: Int) * 32)
+    mba1 <- newByteArray (sizeOf (undefined :: Int) * 32)
+    writeByteArray mba0 0 (0 :: Int)
+    writeByteArray mba1 0 (1 :: Int)
+    -- One thread increments mba0, then mba1 and repeats. The other repeatedly
+    -- loops reading mba0 and mba1, checking that the value from the first is
+    -- always <= the second:
+    readerWait <- newEmptyMVar
+    void $ forkIO $
+        let go :: Int -> IO ()
+            go n = unless (n > iters) $ do
+                    theWrite mba0 n
+                    theWrite mba1 (n+1)
+                    go (n+1)
+         in go 1
+    void $ forkIO $
+        let go = do x <- theRead mba0
+                    y <- theRead mba1
+                    assertBool "test_atomic_read_write_barriers" $
+                        (x <= y)
+                    when (x < iters) go
+         in go
+-- Peterson's lock: http://en.wikipedia.org/wiki/Peterson%27s_algorithm
+-- 
+-- TODO DEBUGGING see https://github.com/rrnewton/haskell-lockfree/issues/43#issuecomment-71294801
+--                for a discussion of issues to be resolved here.
+test_atomic_read_write_barriers2 iters = do
+
+    hSetBuffering stdout NoBuffering  -- TODO DEBUGGING (THIS APPEARS NECESSARY FOR PUTSTR TRICK BELOW TO WORK, TOO)
+
+    let theWrite mba = atomicWriteIntArray mba 0
+        theRead mba = atomicReadIntArray mba 0
+    {- NOTE: WE WANT TO MAKE SURE THESE FAIL, BUT THEY DON'T !!
+    let theWrite mba (v::Int) = writeByteArray mba 0 v
+        theRead mba = readByteArray mba 0 :: IO Int
+     -}
+    let true = 1 :: Int
+        false = 0 :: Int
+    -- For kicks, a bunch of padding to ensure these are on different cache-lines:
+    flag0 <- newByteArray (sizeOf (undefined :: Int) * 32)
+    flag1 <- newByteArray (sizeOf (undefined :: Int) * 32)
+    turn <- newByteArray (sizeOf (undefined :: Int) * 32)
+    writeByteArray flag0 0 false
+    writeByteArray flag1 0 false
+
+    -- We use our lock to get an atomic counter:
+    counter <- newByteArray (sizeOf (undefined :: Int) * 32)
+    writeByteArray counter 0 (0::Int)
+
+    let petersonIncr flagA flagB turnVal = do
+            theWrite flagA true
+            theWrite turn turnVal
+            let busyWait = do
+                  flagBVal <- theRead flagB
+                  turnVal' <- theRead turn
+                  if turnVal == 1 then putStr "x"  else putStr "+" -- TODO DEBUGGING (THIS APPEARS NECESSARY, AND MUST HAPPEN HERE)
+                  -- putStrLn ""                                      -- TODO DEBUGGING this works too (BUT NOT FOR 1MIL?)
+                  -- void $ newEmptyMVar                              -- TODO DEBUGGING does some heap alloc help? NOPE
+                  -- yield                                             -- TODO DEBUGGING neither this nor -fno-omit-yields seem to help
+                  when (flagBVal == true && turnVal' == 1) busyWait
+            busyWait
+            -- start critical section --
+            old <- theRead counter
+            theWrite counter (old+1)
+            -- exit critical section --
+            theWrite flagA false
+            return old
+
+    out1 <- newEmptyMVar
+    out2 <- newEmptyMVar
+    void $ forkIO $ 
+        (replicateM iters $ petersonIncr flag0 flag1 1)
+          >>= putMVar out1
+    void $ forkIO $ 
+        (replicateM iters $ petersonIncr flag1 flag0 0)
+          >>= putMVar out2
+
+    -- make sure we got some interleaving, and that output was correct:
+    res1 <- takeMVar out1
+    res2 <- takeMVar out2
+
+    let numGaps gaps _ [] = gaps
+        numGaps gaps prev (x:xs)
+            | prev+1 == x = numGaps gaps x xs
+            | otherwise   = numGaps (gaps+1) x xs
+    -- TODO DEBUGGING FYI:
+    print $ numGaps (0::Int) (-1::Int) res1
+    print $ numGaps (0::Int) (-1::Int) res2
+    -- ------------------
+    
+    -- if this fails, fix the test or call with more iters
+    assertBool "test_atomic_read_write_barriers2 had enough interleaving to be legit" $
+           numGaps (0::Int) (-1::Int) res1 > 10000 
+        && numGaps (0::Int) (-1::Int) res2 > 10000
+
+    -- braindead merge check:
+    let ok = sort res1 == res1  
+              &&  sort res2 == res2  
+              &&  sort (res1++res2) == [0..iters*2-1]
+
+    assertBool "test_atomic_read_write_barriers2" ok
+
+ -}
+    
 ----------------------------------------------------------------------------------------------------
 {-
 
diff --git a/testing/test-atomic-primops.cabal b/testing/test-atomic-primops.cabal
--- a/testing/test-atomic-primops.cabal
+++ b/testing/test-atomic-primops.cabal
@@ -19,7 +19,7 @@
 Test-Suite test-atomic-primops
     type:       exitcode-stdio-1.0
     main-is:    Test.hs
-    ghc-options: -rtsopts -main-is Test.main
+    ghc-options: -rtsopts -main-is Test.main -Wall
 
     if flag(opt)
        ghc-options: -O2 -funbox-strict-fields
