git.iko.soy/typeable/attoparsec
on master help sign in
Back out the atomic increment change

The cost is simply not worth it, especially to defend against a particularly esoteric instance of something a programmer should never even be doing in the first place.

commit9f07ac2c28f15c1bee22b3256cd858849a26bb3e authorBryan O'Sullivan <bos@serpentine.com> dateThu 29 May 2014, 23:19 (12 years ago) parentc26d059
4 files changed+7−19
Data/Attoparsec/ByteString/Buffer.hs+7−11 attoparsec.cabal−3 benchmarks/attoparsec-benchmarks.cabal−1 cbits/cbits.c−4
Data/Attoparsec/ByteString/Buffer.hs+7−11
@@ -1,4 +1,3 @@
1−{-# LANGUAGE ForeignFunctionInterface #-}
21-- |
32-- Module : Data.Attoparsec.ByteString.Buffer
43-- Copyright : Bryan O'Sullivan 2007-2014
@@ -32,17 +31,15 @@ module Data.Attoparsec.ByteString.Buffer
3231 , unsafeDrop
3332 ) where
3433
35−import Control.Applicative ((<$>))
3634import Control.Exception (assert)
3735import Data.ByteString.Internal (ByteString(..), memcpy, nullForeignPtr)
3836import Data.Attoparsec.Internal.Fhthagn (inlinePerformIO)
3937import Data.List (foldl1')
4038import Data.Monoid (Monoid(..))
4139import Data.Word (Word8)
42−import Foreign.C.Types (CLong(..))
4340import Foreign.ForeignPtr (ForeignPtr, withForeignPtr)
44−import Foreign.Ptr (Ptr, castPtr, plusPtr)
45−import Foreign.Storable (peekByteOff, poke, sizeOf)
41+import Foreign.Ptr (castPtr, plusPtr)
42+import Foreign.Storable (peek, peekByteOff, poke, sizeOf)
4643import GHC.ForeignPtr (mallocPlainForeignPtrBytes)
4744import Prelude hiding (length)
4845
@@ -78,13 +75,15 @@ instance Monoid Buffer where
7875 newlen = len0 + len1
7976 gen <- if gen0 == 0
8077 then return 0
81− else fromIntegral <$> atomic_inc (castPtr ptr0)
82− if newlen <= cap0 && gen == gen0 + 1
78+ else peek (castPtr ptr0)
79+ if gen == gen0 && newlen <= cap0
8380 then do
81+ let newgen = gen + 1
82+ poke (castPtr ptr0) newgen
8483 memcpy (ptr0 `plusPtr` (off0+len0))
8584 (ptr1 `plusPtr` off1)
8685 (fromIntegral len1)
87− return (Buf fp0 off0 newlen cap0 gen)
86+ return (Buf fp0 off0 newlen cap0 newgen)
8887 else do
8988 let newcap = newlen * 2
9089 fp <- mallocPlainForeignPtrBytes (newcap + genSize)
@@ -121,6 +120,3 @@ unsafeDrop s (Buf fp off len _ _) =
121120 assert (s >= 0 && s <= len) $
122121 PS fp (off+s) (len-s)
123122{-# INLINE unsafeDrop #-}
124−
125−foreign import ccall unsafe "_atto_atomic_inc" atomic_inc
126− :: Ptr CLong -> IO CLong
attoparsec.cabal−3
@@ -45,7 +45,6 @@ library
4545 deepseq,
4646 scientific >= 0.3.1 && < 0.4,
4747 text >= 1.1.1.3
48− c-sources: cbits/cbits.c
4948 if impl(ghc < 7.4)
5049 build-depends:
5150 bytestring < 0.10.4.0
@@ -80,7 +79,6 @@ library
8079test-suite tests
8180 type: exitcode-stdio-1.0
8281 hs-source-dirs: tests .
83− c-sources: cbits/cbits.c
8482 main-is: QC.hs
8583 other-modules: QC.Buffer
8684 QC.ByteString
@@ -108,7 +106,6 @@ test-suite tests
108106benchmark benchmarks
109107 type: exitcode-stdio-1.0
110108 hs-source-dirs: benchmarks, .
111− c-sources: cbits/cbits.c
112109 ghc-options: -O2 -Wall -rtsopts
113110 main-is: Benchmarks.hs
114111 other-modules:
benchmarks/attoparsec-benchmarks.cabal−1
@@ -15,7 +15,6 @@ executable attoparsec-benchmarks
1515 Links
1616 Numbers
1717 hs-source-dirs: .. .
18− c-sources: ../cbits/cbits.c
1918 ghc-options: -O2 -Wall -rtsopts
2019 build-depends:
2120 array,
cbits/cbits.cdeleted−4
@@ -1,4 +0,0 @@
1−long _atto_atomic_inc(long *ptr)
2−{
3− return __sync_fetch_and_add(ptr, 1);
4−}