@@ -1,3 +1,4 @@
1+{-# LANGUAGE ForeignFunctionInterface #-}
12-- |
23-- Module : Data.Attoparsec.ByteString.Buffer
34-- Copyright : Bryan O'Sullivan 2007-2014
@@ -31,15 +32,17 @@ module Data.Attoparsec.ByteString.Buffer
3132 , unsafeDrop
3233 ) where
3334
35+import Control.Applicative ((<$>))
3436import Control.Exception (assert)
3537import Data.ByteString.Internal (ByteString(..), memcpy, nullForeignPtr)
3638import Data.Attoparsec.Internal.Fhthagn (inlinePerformIO)
3739import Data.List (foldl1')
3840import Data.Monoid (Monoid(..))
3941import Data.Word (Word8)
42+import Foreign.C.Types (CLong(..))
4043import Foreign.ForeignPtr (ForeignPtr, withForeignPtr)
41−import Foreign.Ptr (castPtr, plusPtr)
42−import Foreign.Storable (peek, peekByteOff, poke, sizeOf)
44+import Foreign.Ptr (Ptr, castPtr, plusPtr)
45+import Foreign.Storable (peekByteOff, poke, sizeOf)
4346import GHC.ForeignPtr (mallocPlainForeignPtrBytes)
4447import Prelude hiding (length)
4548
@@ -75,15 +78,13 @@ instance Monoid Buffer where
7578 newlen = len0 + len1
7679 gen <- if gen0 == 0
7780 then return 0
78− else peek (castPtr ptr0)
79− if gen == gen0 && newlen <= cap0
81+ else fromIntegral <$> atomic_inc (castPtr ptr0)
82+ if newlen <= cap0 && gen == gen0 + 1
8083 then do
81− let newgen = gen + 1
82− poke (castPtr ptr0) newgen
8384 memcpy (ptr0 `plusPtr` (off0+len0))
8485 (ptr1 `plusPtr` off1)
8586 (fromIntegral len1)
86− return (Buf fp0 off0 newlen cap0 newgen)
87+ return (Buf fp0 off0 newlen cap0 gen)
8788 else do
8889 let newcap = newlen * 2
8990 fp <- mallocPlainForeignPtrBytes (newcap + genSize)
@@ -120,3 +121,6 @@ unsafeDrop s (Buf fp off len _ _) =
120121 assert (s >= 0 && s <= len) $
121122 PS fp (off+s) (len-s)
122123{-# INLINE unsafeDrop #-}
124+
125+foreign import ccall unsafe "_atto_atomic_inc" atomic_inc
126+ :: Ptr CLong -> IO CLong