diff --git a/Data/Atomics/Counter/Foreign.hs b/Data/Atomics/Counter/Foreign.hs
new file mode 100644
--- /dev/null
+++ b/Data/Atomics/Counter/Foreign.hs
@@ -0,0 +1,79 @@
+{-# LANGUAGE BangPatterns #-}
+
+-- | This implementation stores an unboxed counter and uses FFI operations to modify
+-- its contents.  It has the advantage that it can use true fetch-and-add operations.
+-- It has the disadvantage of extra overhead due to FFI calls.
+--
+-- For more documentation, see the module "Data.Atomics.Counter", which exports
+-- the same interface as this module.
+
+module Data.Atomics.Counter.Foreign
+       (AtomicCounter, CTicket,
+        newCounter, readCounterForCAS, readCounter, peekCTicket,
+        writeCounter, casCounter, incrCounter, incrCounter_)
+   where
+import Control.Monad (void)
+import Data.Bits.Atomic
+import Foreign.ForeignPtr
+import Foreign.Storable
+
+-- | The type of mutable atomic counters.
+type AtomicCounter = ForeignPtr Int
+
+-- | You should not depend on this type.  It varies between different implementations
+-- of atomic counters.
+type CTicket = Int
+
+{-# INLINE newCounter #-}
+-- | Create a new counter initialized to the given value.
+newCounter :: Int -> IO AtomicCounter
+newCounter n = do x <- mallocForeignPtr
+                  writeCounter x n
+                  -- Do we need a write barrier here?
+                  return x
+
+{-# INLINE incrCounter #-}
+-- | Increment the counter by a given amount.
+--   Returns the original value before the increment.
+--                 
+--   Note that UNLIKE with boxed implementations of counters, where increment is
+--   based on CAS, this increment is /O(1)/.  Fetch-and-add does not require a retry
+--   loop like CAS.
+incrCounter :: Int -> AtomicCounter -> IO Int
+incrCounter bump r = withForeignPtr r$ \r' -> addAndFetch r' bump
+
+{-# INLINE incrCounter_ #-}
+-- | An alternate version for when you don't care about the old value.
+incrCounter_ :: Int -> AtomicCounter -> IO ()
+incrCounter_ bump r = withForeignPtr r$ \r' -> void (addAndFetch r' bump)
+
+{-# INLINE readCounterForCAS #-}
+-- | Just like the "Data.Atomics" CAS interface, this routine returns an opaque
+-- ticket that can be used in CAS operations.
+readCounterForCAS :: AtomicCounter -> IO CTicket
+readCounterForCAS = readCounter
+
+{-# INLINE peekCTicket #-}
+-- | Opaque tickets cannot be constructed, but they can be destructed into values.
+peekCTicket :: CTicket -> Int
+peekCTicket x = x
+
+{-# INLINE readCounter #-}
+-- | Equivalent to `readCounterForCAS` followed by `peekCTicket`.
+readCounter :: AtomicCounter -> IO Int
+readCounter r = withForeignPtr r peek 
+
+{-# INLINE writeCounter #-}
+-- | Make a non-atomic write to the counter.  No memory-barrier.
+writeCounter :: AtomicCounter -> Int -> IO ()
+writeCounter r !new = withForeignPtr r $ \r' -> poke r' new
+
+{-# INLINE casCounter #-}
+-- | Compare and swap for the counter ADT.
+casCounter :: AtomicCounter -> CTicket -> Int -> IO (Bool, CTicket)
+casCounter r !tick !new = withForeignPtr r $ \r' -> do
+   cur <- compareAndSwap r' tick new
+   if cur==tick 
+     then return (True,new)
+     else return (False,cur)
+--   return (b==tick, b)
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c)2012-2013, Ryan R. Newton
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Ryan R. Newton nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/atomic-primops-foreign.cabal b/atomic-primops-foreign.cabal
new file mode 100644
--- /dev/null
+++ b/atomic-primops-foreign.cabal
@@ -0,0 +1,42 @@
+Name:                atomic-primops-foreign
+Version:             0.6
+License:             BSD3
+License-file:        LICENSE
+Author:              Ryan Newton
+Maintainer:          rrnewton@gmail.com
+Category:            Data
+Build-type:          Simple
+Cabal-version:       >=1.8
+HomePage: https://github.com/rrnewton/haskell-lockfree/wiki
+Bug-Reports: https://github.com/rrnewton/haskell-lockfree/issues
+
+-- 0.6 -- Factored out of parent module to separate dependencies.
+
+Synopsis: An atomic counter implemented using the FFI.
+Description:
+
+Library
+  exposed-modules: Data.Atomics.Counter.Foreign
+  ghc-options: -O2 -funbox-strict-fields
+  build-depends: bits-atomic >= 0.1.3
+
+  -- This can go back further than the atomic-primops package in supporting old GHC's:
+  -- For now let's say GHC 7.0 through 7.8:
+  build-depends: base >= 4.3.0.0 && <= 4.7.0.0
+  CC-Options:       -Wall 
+
+Test-Suite test-atomic-primops-foreign
+    type:       exitcode-stdio-1.0
+    main-is: testing/Main.hs
+    hs-source-dirs: testing/ ./
+
+    ghc-options: -threaded -rtsopts -with-rtsopts=-N4
+    build-depends: bits-atomic
+    build-depends: base >= 4.3.0.0 && <= 4.7.0.0, 
+                   -- For Testing:
+                   time, HUnit, test-framework, test-framework-hunit
+
+Source-Repository head
+    Type:         git
+    Location:     git://github.com/rrnewton/haskell-lockfree.git
+    Subdir:       atomic-primops-foreign/
diff --git a/testing/Main.hs b/testing/Main.hs
new file mode 100644
--- /dev/null
+++ b/testing/Main.hs
@@ -0,0 +1,18 @@
+
+module Main where
+
+import GHC.Conc
+import Test.Framework  (Test, defaultMain, testGroup)
+import qualified CounterForeign
+import Control.Monad (when)
+
+----------------------------------------
+
+main :: IO ()
+main = do
+       -- TEMP: Fixing this at four processors because it takes a REALLY long time at larger numbers:
+       -- It does 248 test cases and takes 55s at -N16...
+       -- numcap <- getNumProcessors
+       let numcap = 4
+       when (numCapabilities /= numcap) $ setNumCapabilities numcap
+       defaultMain CounterForeign.tests
