@@ -1,5 +1,3 @@
1−{-# LANGUAGE UnboxedTuples #-}
2−
31-- |
42-- Module : Streamly.Internal.Data.Array.Foreign.Mut.Type
53-- Copyright : (c) 2020 Composewell Technologies
@@ -92,13 +90,10 @@ module Streamly.Internal.Data.Array.Foreign.Mut.Type
9290 , writeChunks
9391
9492 -- * Utilities
95− , defaultChunkSize
96− , mkChunkSize
97− , mkChunkSizeKB
9893 , bytesToElemCount
99− , unsafeInlineIO
10094 , memcpy
10195 , memcmp
96+ , c_memchr
10297 )
10398where
10499
@@ -118,10 +113,10 @@ import Foreign.ForeignPtr (touchForeignPtr)
118113import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
119114import Foreign.Ptr (plusPtr, minusPtr, castPtr, nullPtr)
120115import Foreign.Storable (Storable(..))
121−import GHC.Base (nullAddr#, realWorld#, build)
116+import GHC.Base (nullAddr#, build)
122117import GHC.Exts (IsList, IsString(..))
123118import GHC.ForeignPtr (ForeignPtr(..))
124−import GHC.IO (IO(IO), unsafePerformIO)
119+import GHC.IO (unsafePerformIO)
125120import GHC.Ptr (Ptr(..))
126121
127122import Streamly.Internal.BaseCompat
@@ -131,6 +126,9 @@ import Streamly.Internal.Data.SVar (adaptState)
131126import Streamly.Internal.Data.Unfold.Type (Unfold(..))
132127import Text.Read (readPrec, readListPrec, readListPrecDefault)
133128
129+import Streamly.Internal.System.IO
130+ (defaultChunkSize, mkChunkSize, unsafeInlineIO)
131+
134132#ifdef DEVBUILD
135133import qualified Data.Foldable as F
136134#endif
@@ -156,6 +154,37 @@ plusForeignPtr (ForeignPtr addr c) (I# d) = ForeignPtr (plusAddr# addr d) c
156154-- Array Data Type
157155-------------------------------------------------------------------------------
158156
157+foreign import ccall unsafe "string.h memcpy" c_memcpy
158+ :: Ptr Word8 -> Ptr Word8 -> CSize -> IO (Ptr Word8)
159+
160+foreign import ccall unsafe "string.h memchr" c_memchr
161+ :: Ptr Word8 -> Word8 -> CSize -> IO (Ptr Word8)
162+
163+foreign import ccall unsafe "string.h memcmp" c_memcmp
164+ :: Ptr Word8 -> Ptr Word8 -> CSize -> IO CInt
165+
166+{-# INLINE bytesToElemCount #-}
167+bytesToElemCount :: Storable a => a -> Int -> Int
168+bytesToElemCount x n =
169+ let elemSize = sizeOf x
170+ in n + elemSize - 1 `div` elemSize
171+
172+-- XXX we are converting Int to CSize
173+memcpy :: Ptr Word8 -> Ptr Word8 -> Int -> IO ()
174+memcpy dst src len = void (c_memcpy dst src (fromIntegral len))
175+
176+-- XXX we are converting Int to CSize
177+-- return True if the memory locations have identical contents
178+{-# INLINE memcmp #-}
179+memcmp :: Ptr Word8 -> Ptr Word8 -> Int -> IO Bool
180+memcmp p1 p2 len = do
181+ r <- c_memcmp p1 p2 (fromIntegral len)
182+ return $ r == 0
183+
184+-------------------------------------------------------------------------------
185+-- Array Data Type
186+-------------------------------------------------------------------------------
187+
159188-- $arrayNotes
160189--
161190-- We can use a 'Storable' constraint in the Array type and the constraint can
@@ -183,59 +212,6 @@ mutableArray ::
183212 ForeignPtr a -> Ptr a -> Ptr a -> Array a
184213mutableArray = Array
185214
186−-------------------------------------------------------------------------------
187−-- Utility functions
188−-------------------------------------------------------------------------------
189−
190−foreign import ccall unsafe "string.h memcpy" c_memcpy
191− :: Ptr Word8 -> Ptr Word8 -> CSize -> IO (Ptr Word8)
192−
193−foreign import ccall unsafe "string.h memchr" c_memchr
194− :: Ptr Word8 -> Word8 -> CSize -> IO (Ptr Word8)
195−
196−-- XXX we are converting Int to CSize
197−memcpy :: Ptr Word8 -> Ptr Word8 -> Int -> IO ()
198−memcpy dst src len = void (c_memcpy dst src (fromIntegral len))
199−
200−foreign import ccall unsafe "string.h memcmp" c_memcmp
201− :: Ptr Word8 -> Ptr Word8 -> CSize -> IO CInt
202−
203−-- XXX we are converting Int to CSize
204−-- return True if the memory locations have identical contents
205−{-# INLINE memcmp #-}
206−memcmp :: Ptr Word8 -> Ptr Word8 -> Int -> IO Bool
207−memcmp p1 p2 len = do
208− r <- c_memcmp p1 p2 (fromIntegral len)
209− return $ r == 0
210−
211−{-# INLINE unsafeInlineIO #-}
212−unsafeInlineIO :: IO a -> a
213−unsafeInlineIO (IO m) = case m realWorld# of (# _, r #) -> r
214−
215−{-# INLINE bytesToElemCount #-}
216−bytesToElemCount :: Storable a => a -> Int -> Int
217−bytesToElemCount x n =
218− let elemSize = sizeOf x
219− in n + elemSize - 1 `div` elemSize
220−
221−
222−-- | GHC memory management allocation header overhead
223−allocOverhead :: Int
224−allocOverhead = 2 * sizeOf (undefined :: Int)
225−
226−mkChunkSize :: Int -> Int
227−mkChunkSize n = let size = n - allocOverhead in max size 0
228−
229−mkChunkSizeKB :: Int -> Int
230−mkChunkSizeKB n = mkChunkSize (n * k)
231− where k = 1024
232−
233−-- | Default maximum buffer size in bytes, for reading from and writing to IO
234−-- devices, the value is 32KB minus GHC allocation overhead, which is a few
235−-- bytes, so that the actual allocation is 32KB.
236−defaultChunkSize :: Int
237−defaultChunkSize = mkChunkSizeKB 32
238−
239215-------------------------------------------------------------------------------
240216-- Construction
241217-------------------------------------------------------------------------------