diff --git a/core/docs/ApiChangelogs/0.2.0-0.2.2.txt b/core/docs/ApiChangelogs/0.2.0-0.2.2.txt index 8e3db32e2..ccce1c0e1 100644 --- a/core/docs/ApiChangelogs/0.2.0-0.2.2.txt +++ b/core/docs/ApiChangelogs/0.2.0-0.2.2.txt @@ -111,9 +111,11 @@ Internal API diff [D] sliceOnSuffix :: Monad m => (a -> Bool) -> Stream m a -> Stream m (Int, Int) [A] indexOnSuffix :: Monad m => (a -> Bool) -> Stream m a -> Stream m (Int, Int) [C] Streamly.Internal.Data.MutByteArray + [A] unsafePinnedAsPtr :: MonadIO m => MutByteArray -> (Ptr a -> m b) -> m b + [A] unsafeAsPtr :: MonadIO m => MutByteArray -> (Ptr a -> m b) -> m b [D] nil :: MutByteArray [A] empty :: MutByteArray - [A] asUnpinnedPtrUnsafe :: MonadIO m => MutByteArray -> (Ptr a -> m b) -> m b + [D] asPtrUnsafe :: MonadIO m => MutByteArray -> (Ptr a -> m b) -> m b [D] Streamly.Internal.Data.MutArray.Stream [D] writeChunks :: (MonadIO m, Unbox a) => Int -> Fold m a (StreamK n (MutArray a)) [D] fromArrayStreamK :: (Unbox a, MonadIO m) => StreamK m (MutArray a) -> m (MutArray a) @@ -142,8 +144,10 @@ Internal API diff [D] writeAppendWith :: forall m a. (MonadIO m, Unbox a) => (Int -> Int) -> m (MutArray a) -> Fold m a (MutArray a) [D] writeAppendNUnsafe :: forall m a. (MonadIO m, Unbox a) => Int -> m (MutArray a) -> Fold m a (MutArray a) [A] unsafePinnedCreateOf :: forall m a. (MonadIO m, Unbox a) => Int -> Fold m a (MutArray a) + [A] unsafePinnedAsPtr :: MonadIO m => MutArray a -> (Ptr a -> m b) -> m b [A] unsafeCreateOfWith :: forall m a. (MonadIO m, Unbox a) => (Int -> m (MutArray a)) -> Int -> Fold m a (MutArray a) [A] unsafeCreateOf :: forall m a. (MonadIO m, Unbox a) => Int -> Fold m a (MutArray a) + [A] unsafeAsPtr :: MonadIO m => MutArray a -> (Ptr a -> m b) -> m b [A] unsafeAppendN :: forall m a. (MonadIO m, Unbox a) => Int -> m (MutArray a) -> Fold m a (MutArray a) [A] toStreamWith :: forall m a. (Monad m, Unbox a) => (forall b. IO b -> m b) -> MutArray a -> Stream m a [A] toStreamRevWith :: forall m a. (Monad m, Unbox a) => (forall b. IO b -> m b) -> MutArray a -> Stream m a @@ -210,7 +214,7 @@ Internal API diff [A] byteEq :: MonadIO m => MutArray a -> MutArray a -> m Bool [A] byteCmp :: MonadIO m => MutArray a -> MutArray a -> m Ordering [A] buildChunks :: (MonadIO m, Unbox a) => Int -> Fold m a (StreamK n (MutArray a)) - [A] asUnpinnedPtrUnsafe :: MonadIO m => MutArray a -> (Ptr a -> m b) -> m b + [D] asPtrUnsafe :: MonadIO m => MutArray a -> (Ptr a -> m b) -> m b [A] appendWith :: forall m a. (MonadIO m, Unbox a) => (Int -> Int) -> m (MutArray a) -> Fold m a (MutArray a) [A] appendN :: forall m a. (MonadIO m, Unbox a) => Int -> m (MutArray a) -> Fold m a (MutArray a) [A] append :: forall m a. (MonadIO m, Unbox a) => m (MutArray a) -> Fold m a (MutArray a) @@ -229,6 +233,7 @@ Internal API diff [A] create :: MonadIO m => Fold m a (Array a) [C] Streamly.Internal.Data.Array [R] ArrayUnsafe + [A] unsafePinnedAsPtr :: MonadIO m => Array a -> (Ptr a -> m b) -> m b [D] toStreamDRev :: forall m a. (Monad m, Unbox a) => Array a -> Stream m a [D] toStreamD :: forall m a. (Monad m, Unbox a) => Array a -> Stream m a [C] splice @@ -276,3 +281,4 @@ Internal API diff [A] byteCmp :: Array a -> Array a -> Ordering [A] buildChunks :: (MonadIO m, Unbox a) => Stream m a -> m (StreamK m (Array a)) [D] bufferChunks :: (MonadIO m, Unbox a) => Stream m a -> m (StreamK m (Array a)) + [D] asPtrUnsafe :: MonadIO m => Array a -> (Ptr a -> m b) -> m b diff --git a/core/src/Streamly/Internal/Data/Array.hs b/core/src/Streamly/Internal/Data/Array.hs index 0d2ba2210..e908ea2ca 100644 --- a/core/src/Streamly/Internal/Data/Array.hs +++ b/core/src/Streamly/Internal/Data/Array.hs @@ -498,8 +498,8 @@ cast arr = asCStringUnsafe :: Array a -> (CString -> IO b) -> IO b asCStringUnsafe arr act = do let arr1 = asBytes arr <> fromList [0] - -- asPtrUnsafe makes sure the array is pinned - asPtrUnsafe arr1 $ \ptr -> act (castPtr ptr) + -- unsafePinnedAsPtr makes sure the array is pinned + unsafePinnedAsPtr arr1 $ \ptr -> act (castPtr ptr) ------------------------------------------------------------------------------- -- Folds diff --git a/core/src/Streamly/Internal/Data/Array/Type.hs b/core/src/Streamly/Internal/Data/Array/Type.hs index 6b4b33c41..c35bc0f16 100644 --- a/core/src/Streamly/Internal/Data/Array/Type.hs +++ b/core/src/Streamly/Internal/Data/Array/Type.hs @@ -28,7 +28,7 @@ module Streamly.Internal.Data.Array.Type , isPinned -- *** Casting - , asPtrUnsafe + , unsafePinnedAsPtr -- ** Construction , empty @@ -129,6 +129,7 @@ module Streamly.Internal.Data.Array.Type , compactGE -- ** Deprecated + , asPtrUnsafe , unsafeIndex , bufferChunks , flattenArrays @@ -231,15 +232,20 @@ data Array a = -- | Use an @Array a@ as @Ptr a@. -- --- See 'MA.asPtrUnsafe' in the Mutable array module for more details. +-- See 'MA.unsafePinnedAsPtr' in the Mutable array module for more details. -- -- /Unsafe/ -- -- /Pre-release/ -- +{-# INLINE unsafePinnedAsPtr #-} +unsafePinnedAsPtr :: MonadIO m => Array a -> (Ptr a -> m b) -> m b +unsafePinnedAsPtr arr = MA.unsafePinnedAsPtr (unsafeThaw arr) + +{-# DEPRECATED asPtrUnsafe "Please use unsafePinnedAsPtr instead." #-} {-# INLINE asPtrUnsafe #-} asPtrUnsafe :: MonadIO m => Array a -> (Ptr a -> m b) -> m b -asPtrUnsafe arr = MA.asPtrUnsafe (unsafeThaw arr) +asPtrUnsafe = unsafePinnedAsPtr ------------------------------------------------------------------------------- -- Freezing and Thawing diff --git a/core/src/Streamly/Internal/Data/MutArray/Type.hs b/core/src/Streamly/Internal/Data/MutArray/Type.hs index 00b415c01..62f689d60 100644 --- a/core/src/Streamly/Internal/Data/MutArray/Type.hs +++ b/core/src/Streamly/Internal/Data/MutArray/Type.hs @@ -42,8 +42,8 @@ module Streamly.Internal.Data.MutArray.Type , cast , castUnsafe -- XXX unsafeCast , asBytes - , asPtrUnsafe -- XXX rename to unsafePinnedAsPtr? - , asUnpinnedPtrUnsafe -- XXX rename to unsafeAsPtr + , unsafePinnedAsPtr + , unsafeAsPtr -- ** Construction , empty @@ -264,6 +264,7 @@ module Streamly.Internal.Data.MutArray.Type , c_memchr -- * Deprecated + , asPtrUnsafe , writeChunks , flattenArrays , flattenArraysRev @@ -2431,7 +2432,7 @@ fromPtrN len addr = do -- XXX We can implement a stream copy in a similar way by streaming Word64 -- first and then remaining Word8. arr <- new len - _ <- asUnpinnedPtrUnsafe arr + _ <- unsafeAsPtr arr (\ptr -> liftIO $ c_memcpy ptr addr (fromIntegral len)) return (arr {arrEnd = len}) @@ -2447,7 +2448,7 @@ fromByteStr# addr = do len <- liftIO $ c_strlen (Ptr addr) let lenInt = fromIntegral len arr <- new lenInt - _ <- asUnpinnedPtrUnsafe arr (\ptr -> liftIO $ c_memcpy ptr (Ptr addr) len) + _ <- unsafeAsPtr arr (\ptr -> liftIO $ c_memcpy ptr (Ptr addr) len) return (arr {arrEnd = lenInt}) ------------------------------------------------------------------------------- @@ -2735,7 +2736,7 @@ splitOn predicate arr = {-# INLINE breakOn #-} breakOn :: MonadIO m => Word8 -> MutArray Word8 -> m (MutArray Word8, Maybe (MutArray Word8)) -breakOn sep arr@MutArray{..} = asUnpinnedPtrUnsafe arr $ \p -> liftIO $ do +breakOn sep arr@MutArray{..} = unsafeAsPtr arr $ \p -> liftIO $ do -- XXX We do not need memchr here, we can use a Haskell equivalent. -- Need efficient stream based primitives that work on Word64. loc <- c_memchr p sep (fromIntegral $ byteLength arr) @@ -2866,16 +2867,21 @@ cast arr = -- -- /Pre-release/ -- -{-# INLINE asPtrUnsafe #-} -asPtrUnsafe :: MonadIO m => MutArray a -> (Ptr a -> m b) -> m b -asPtrUnsafe arr f = - Unboxed.asPtrUnsafe +{-# INLINE unsafePinnedAsPtr #-} +unsafePinnedAsPtr :: MonadIO m => MutArray a -> (Ptr a -> m b) -> m b +unsafePinnedAsPtr arr f = + Unboxed.unsafePinnedAsPtr (arrContents arr) (\ptr -> f (ptr `plusPtr` arrStart arr)) -{-# INLINE asUnpinnedPtrUnsafe #-} -asUnpinnedPtrUnsafe :: MonadIO m => MutArray a -> (Ptr a -> m b) -> m b -asUnpinnedPtrUnsafe arr f = - Unboxed.asUnpinnedPtrUnsafe +{-# DEPRECATED asPtrUnsafe "Please use unsafePinnedAsPtr instead." #-} +{-# INLINE asPtrUnsafe #-} +asPtrUnsafe :: MonadIO m => MutArray a -> (Ptr a -> m b) -> m b +asPtrUnsafe = unsafePinnedAsPtr + +{-# INLINE unsafeAsPtr #-} +unsafeAsPtr :: MonadIO m => MutArray a -> (Ptr a -> m b) -> m b +unsafeAsPtr arr f = + Unboxed.unsafeAsPtr (arrContents arr) (\ptr -> f (ptr `plusPtr` arrStart arr)) ------------------------------------------------------------------------------- diff --git a/core/src/Streamly/Internal/Data/MutByteArray/Type.hs b/core/src/Streamly/Internal/Data/MutByteArray/Type.hs index 62ad220d6..da9fe72af 100644 --- a/core/src/Streamly/Internal/Data/MutByteArray/Type.hs +++ b/core/src/Streamly/Internal/Data/MutByteArray/Type.hs @@ -34,10 +34,11 @@ module Streamly.Internal.Data.MutByteArray.Type , cloneSliceUnsafeAs , cloneSliceUnsafe , pinnedCloneSliceUnsafe - , asPtrUnsafe -- XXX unsafePinnedAsPtr - , asUnpinnedPtrUnsafe -- XXX unsafeAsPtr + , unsafePinnedAsPtr + , unsafeAsPtr -- ** Deprecated + , asPtrUnsafe , nil ) where @@ -117,9 +118,9 @@ touch (MutByteArray contents) = -- -- /Pre-release/ -- -{-# INLINE asPtrUnsafe #-} -asPtrUnsafe :: MonadIO m => MutByteArray -> (Ptr a -> m b) -> m b -asPtrUnsafe arr f = do +{-# INLINE unsafePinnedAsPtr #-} +unsafePinnedAsPtr :: MonadIO m => MutByteArray -> (Ptr a -> m b) -> m b +unsafePinnedAsPtr arr f = do contents <- liftIO $ pin arr let !ptr = Ptr (byteArrayContents# (unsafeCoerce# (getMutableByteArray# contents))) @@ -127,10 +128,15 @@ asPtrUnsafe arr f = do liftIO $ touch contents return r +{-# DEPRECATED asPtrUnsafe "Please use unsafePinnedAsPtr instead." #-} +{-# INLINE asPtrUnsafe #-} +asPtrUnsafe :: MonadIO m => MutByteArray -> (Ptr a -> m b) -> m b +asPtrUnsafe = unsafePinnedAsPtr + -- | For use with unsafe FFI functions. Does not force pin the array memory. -{-# INLINE asUnpinnedPtrUnsafe #-} -asUnpinnedPtrUnsafe :: MonadIO m => MutByteArray -> (Ptr a -> m b) -> m b -asUnpinnedPtrUnsafe arr f = do +{-# INLINE unsafeAsPtr #-} +unsafeAsPtr :: MonadIO m => MutByteArray -> (Ptr a -> m b) -> m b +unsafeAsPtr arr f = do let !ptr = Ptr (byteArrayContents# (unsafeCoerce# (getMutableByteArray# arr))) r <- f ptr diff --git a/core/src/Streamly/Internal/FileSystem/Handle.hs b/core/src/Streamly/Internal/FileSystem/Handle.hs index 607afdc8c..cf1fe52b3 100644 --- a/core/src/Streamly/Internal/FileSystem/Handle.hs +++ b/core/src/Streamly/Internal/FileSystem/Handle.hs @@ -180,7 +180,7 @@ getChunk :: MonadIO m => Int -> Handle -> m (Array Word8) getChunk size h = liftIO $ do arr :: MArray.MutArray Word8 <- MArray.pinnedEmptyOf size -- ptr <- mallocPlainForeignPtrAlignedBytes size (alignment (undefined :: Word8)) - MArray.asPtrUnsafe arr $ \p -> do + MArray.unsafePinnedAsPtr arr $ \p -> do n <- hGetBufSome h p size -- XXX shrink only if the diff is significant return $ @@ -380,12 +380,12 @@ read = A.concat . readChunks {-# INLINABLE putChunk #-} putChunk :: MonadIO m => Handle -> Array a -> m () putChunk _ arr | byteLength arr == 0 = return () -putChunk h arr = A.asPtrUnsafe arr $ \ptr -> +putChunk h arr = A.unsafePinnedAsPtr arr $ \ptr -> liftIO $ hPutBuf h ptr aLen where - -- XXX We should have the length passed by asPtrUnsafe itself. + -- XXX We should have the length passed by unsafePinnedAsPtr itself. aLen = A.byteLength arr ------------------------------------------------------------------------------- diff --git a/src/Streamly/Internal/FileSystem/Event/Darwin.hs b/src/Streamly/Internal/FileSystem/Event/Darwin.hs index 4aaf1319c..b53add830 100644 --- a/src/Streamly/Internal/FileSystem/Event/Darwin.hs +++ b/src/Streamly/Internal/FileSystem/Event/Darwin.hs @@ -451,7 +451,7 @@ openWatch Config{..} paths = do withPathName :: Array Word8 -> (PathName -> IO a) -> IO a withPathName arr act = do - A.asPtrUnsafe arr $ \ptr -> + A.unsafePinnedAsPtr arr $ \ptr -> let pname = PathName (castPtr ptr) (fromIntegral (A.length arr)) in act pname diff --git a/src/Streamly/Internal/FileSystem/Event/Linux.hs b/src/Streamly/Internal/FileSystem/Event/Linux.hs index 4d66d55a2..d2cc61387 100644 --- a/src/Streamly/Internal/FileSystem/Event/Linux.hs +++ b/src/Streamly/Internal/FileSystem/Event/Linux.hs @@ -188,7 +188,7 @@ import qualified Streamly.FileSystem.Handle as FH import qualified Streamly.Unicode.Stream as U import qualified Streamly.Internal.Data.Array as A - ( fromStream, asCStringUnsafe, asPtrUnsafe + ( fromStream, asCStringUnsafe, unsafePinnedAsPtr , getSliceUnsafe, read ) import qualified Streamly.Internal.FileSystem.Dir as Dir (readDirs) @@ -809,7 +809,7 @@ readOneEvent :: Config -> Watch -> Parser Word8 IO Event readOneEvent cfg wt@(Watch _ wdMap) = do let headerLen = sizeOf (undefined :: CInt) + 12 arr <- PR.takeEQ headerLen (A.writeN headerLen) - (ewd, eflags, cookie, pathLen) <- PR.fromEffect $ A.asPtrUnsafe arr readHeader + (ewd, eflags, cookie, pathLen) <- PR.fromEffect $ A.unsafePinnedAsPtr arr readHeader -- XXX need the "initial" in parsers to return a step type so that "take 0" -- can return without an input. otherwise if pathLen is 0 we will keep -- waiting to read one more char before we return this event. diff --git a/src/Streamly/Internal/FileSystem/FD.hs b/src/Streamly/Internal/FileSystem/FD.hs index 05189feb0..a2c404e77 100644 --- a/src/Streamly/Internal/FileSystem/FD.hs +++ b/src/Streamly/Internal/FileSystem/FD.hs @@ -130,7 +130,7 @@ import qualified GHC.IO.Device as RawIO import Streamly.Data.Array (Array, Unbox) import Streamly.Data.Stream (Stream) -import Streamly.Internal.Data.Array (byteLength, unsafeFreeze, asPtrUnsafe) +import Streamly.Internal.Data.Array (byteLength, unsafeFreeze, unsafePinnedAsPtr) import Streamly.Internal.System.IO (defaultChunkSize) #if !defined(mingw32_HOST_OS) @@ -147,7 +147,7 @@ import qualified Streamly.Internal.System.IOVec.Type as RawIO import qualified Streamly.Data.Array as A import qualified Streamly.Data.Fold as FL import qualified Streamly.Internal.Data.MutArray as MArray - (MutArray(..), asPtrUnsafe, pinnedNewBytes) + (MutArray(..), unsafePinnedAsPtr, pinnedNewBytes) import qualified Streamly.Internal.Data.Array.Stream as AS import qualified Streamly.Internal.Data.Stream as S import qualified Streamly.Internal.Data.Stream as D @@ -220,7 +220,7 @@ readArrayUpto :: Int -> Handle -> IO (Array Word8) readArrayUpto size (Handle fd) = do arr <- MArray.pinnedNewBytes size -- ptr <- mallocPlainForeignPtrAlignedBytes size (alignment (undefined :: Word8)) - MArray.asPtrUnsafe arr $ \p -> do + MArray.unsafePinnedAsPtr arr $ \p -> do -- n <- hGetBufSome h p size #if MIN_VERSION_base(4,15,0) n <- RawIO.read fd p 0 size @@ -244,7 +244,7 @@ readArrayUpto size (Handle fd) = do writeArray :: Unbox a => Handle -> Array a -> IO () writeArray _ arr | A.length arr == 0 = return () writeArray (Handle fd) arr = - asPtrUnsafe arr $ \p -> + unsafePinnedAsPtr arr $ \p -> -- RawIO.writeAll fd (castPtr p) aLen #if MIN_VERSION_base(4,15,0) RawIO.write fd (castPtr p) 0 aLen @@ -270,7 +270,7 @@ writeArray (Handle fd) arr = writeIOVec :: Handle -> Array RawIO.IOVec -> IO () writeIOVec _ iov | A.length iov == 0 = return () writeIOVec (Handle fd) iov = - asPtrUnsafe iov $ \p -> + unsafePinnedAsPtr iov $ \p -> RawIO.writevAll fd p (A.length iov) -} #endif diff --git a/src/Streamly/Internal/Network/Socket.hs b/src/Streamly/Internal/Network/Socket.hs index df8713803..21bb3746c 100644 --- a/src/Streamly/Internal/Network/Socket.hs +++ b/src/Streamly/Internal/Network/Socket.hs @@ -98,10 +98,10 @@ import qualified Streamly.Data.Fold as FL import qualified Streamly.Data.Stream as S import qualified Streamly.Data.Unfold as UF import qualified Streamly.Internal.Data.Array as A - ( unsafeFreeze, asPtrUnsafe, byteLength, pinnedChunksOf, + ( unsafeFreeze, unsafePinnedAsPtr, byteLength, pinnedChunksOf, pinnedWriteN, pinnedWriteNUnsafe, lCompactGE ) import qualified Streamly.Internal.Data.MutArray as MArray - (MutArray(..), asPtrUnsafe, pinnedEmptyOf) + (MutArray(..), unsafePinnedAsPtr, pinnedEmptyOf) import qualified Streamly.Internal.Data.Stream as S (fromStreamK, Stream(..), Step(..)) import qualified Streamly.Internal.Data.StreamK as K (mkStream) @@ -263,7 +263,7 @@ readArrayUptoWith readArrayUptoWith f size h = do arr <- MArray.pinnedEmptyOf size -- ptr <- mallocPlainForeignPtrAlignedBytes size (alignment (undefined :: Word8)) - MArray.asPtrUnsafe arr $ \p -> do + MArray.unsafePinnedAsPtr arr $ \p -> do n <- f h p size let v = A.unsafeFreeze $ arr { MArray.arrEnd = n, MArray.arrBound = size } @@ -311,7 +311,7 @@ writeArrayWith :: Unbox a -> Array a -> IO () writeArrayWith _ _ arr | A.length arr == 0 = return () -writeArrayWith f h arr = A.asPtrUnsafe arr $ \ptr -> f h (castPtr ptr) aLen +writeArrayWith f h arr = A.unsafePinnedAsPtr arr $ \ptr -> f h (castPtr ptr) aLen where diff --git a/test/Streamly/Test/Data/Array.hs b/test/Streamly/Test/Data/Array.hs index c20fc0e12..144c96d31 100644 --- a/test/Streamly/Test/Data/Array.hs +++ b/test/Streamly/Test/Data/Array.hs @@ -185,7 +185,7 @@ testUnsafeIndxedFromList inp = testAsPtrUnsafeMA :: IO () testAsPtrUnsafeMA = do arr <- MA.fromList ([0 .. 99] :: [Int]) - MA.asPtrUnsafe arr (getList (0 :: Int)) `shouldReturn` [0 .. 99] + MA.unsafePinnedAsPtr arr (getList (0 :: Int)) `shouldReturn` [0 .. 99] where