on master help sign in
Stop exporting touch from Internal.Data.Unbox

Export asPtrUnsafe instead.

commit628d6c4dbaeaecd3046d3fa09ecb13f0fbb9ce9b authorHarendra Kumar <harendra@composewell.com> dateFri 24 Nov 2023, 00:09 (3 years ago) parentde7a604
4 files changed+59−26
core/src/Streamly/Data/Serialize.hs+5 core/src/Streamly/Internal/Data/Fold/Chunked.hs−2 core/src/Streamly/Internal/Data/MutArray/Type.hs+10−18 core/src/Streamly/Internal/Data/Unbox.hs+44−6
core/src/Streamly/Data/Serialize.hs+5
@@ -43,6 +43,11 @@ module Streamly.Data.Serialize
4343
4444 -- * MutableByteArray
4545 MutableByteArray
46+ -- , isPinned
47+ -- , pin
48+ -- , unpin
49+ -- , newBytes -- XXX rename to newByteArray
50+ -- , pinnedNewBytes -- XXX rename to pinnedNewByteArray
4651
4752 -- * Unbox
4853 , Unbox(..)
core/src/Streamly/Internal/Data/Fold/Chunked.hs−2
@@ -67,7 +67,6 @@ import Data.Bifunctor (first)
6767import Data.Proxy (Proxy(..))
6868import Streamly.Internal.Data.Unbox (Unbox(..))
6969import GHC.Types (SPEC(..))
70−import Streamly.Internal.Data.MutArray.Type (touch)
7170import Streamly.Internal.Data.Array (Array(..))
7271import Streamly.Internal.Data.Parser (Initial(..), Step(..))
7372import Streamly.Internal.Data.Tuple.Strict (Tuple'(..))
@@ -164,7 +163,6 @@ fromParserD (ParserD.Parser step1 initial1 extract1) =
164163
165164 goArray !_ !cur !fs = do
166165 x <- liftIO $ peekByteIndex cur contents
167− liftIO $ touch contents
168166 res <- step1 fs x
169167 let elemSize = SIZE_OF(a)
170168 next = INDEX_NEXT(cur,a)
core/src/Streamly/Internal/Data/MutArray/Type.hs+10−18
@@ -32,7 +32,6 @@ module Streamly.Internal.Data.MutArray.Type
3232 -- $arrayNotes
3333 MutArray (..)
3434 , MutableByteArray
35− , touch
3635 , pin
3736 , unpin
3837 , isPinned
@@ -244,13 +243,11 @@ import Streamly.Internal.Data.Unbox
244243 , Unbox(..)
245244 , PinnedState(..)
246245 , getMutableByteArray#
247− , touch
248246 , putSliceUnsafe
249247 )
250248import GHC.Base
251249 ( IO(..)
252250 , Int(..)
253− , byteArrayContents#
254251 , compareByteArrays#
255252 , copyMutableByteArray#
256253 )
@@ -2325,13 +2322,12 @@ cast arr =
23252322-- guarantees that unsafe calls will be performed in the calling thread. Making
23262323-- it safe to pass heap-allocated objects to unsafe functions.
23272324
2328−-- Unsafe because of direct pointer operations. The user must ensure that they
2329−-- are writing within the legal bounds of the array. Should we just name it
2330−-- asPtr, the unsafety is implicit for any pointer operations. And we are safe
2331−-- from Haskell perspective because we will be pinning the memory.
2325+-- Should we just name it asPtr, the unsafety is implicit for any pointer
2326+-- operations. And we are safe from Haskell perspective because we will be
2327+-- pinning the memory.
23322328
2333−-- | Use an @MutArray a@ as @Ptr a@. This is useful when we want to pass an array
2334−-- as a pointer to some operating system call or to a "safe" FFI call.
2329+-- | Use a @MutArray a@ as @Ptr a@. This is useful when we want to pass an
2330+-- array as a pointer to some operating system call or to a "safe" FFI call.
23352331--
23362332-- If the array is not pinned it is copied to pinned memory before passing it
23372333-- to the monadic action.
@@ -2341,20 +2337,16 @@ cast arr =
23412337-- opportunistically before this operation occurs, to avoid the cost of a copy
23422338-- if possible.
23432339--
2344−-- /Unsafe/
2340+-- /Unsafe/ because of direct pointer operations. The user must ensure that
2341+-- they are writing within the legal bounds of the array.
23452342--
23462343-- /Pre-release/
23472344--
23482345{-# INLINE asPtrUnsafe #-}
23492346asPtrUnsafe :: MonadIO m => MutArray a -> (Ptr a -> m b) -> m b
2350−asPtrUnsafe arr f = do
2351− contents <- liftIO $ Unboxed.pin $ arrContents arr
2352− let !ptr = Ptr (byteArrayContents#
2353− (unsafeCoerce# (getMutableByteArray# contents)))
2354−
2355− r <- f (ptr `plusPtr` arrStart arr)
2356− liftIO $ touch contents
2357− return r
2347+asPtrUnsafe arr f =
2348+ Unboxed.asPtrUnsafe
2349+ (arrContents arr) (\ptr -> f (ptr `plusPtr` arrStart arr))
23582350
23592351-------------------------------------------------------------------------------
23602352-- Equality
core/src/Streamly/Internal/Data/Unbox.hs+44−6
@@ -17,9 +17,9 @@ module Streamly.Internal.Data.Unbox
1717 MutableByteArray(..)
1818 , getMutableByteArray#
1919 , sizeOfMutableByteArray
20− , touch
2120 , nil
2221 , putSliceUnsafe
22+ , asPtrUnsafe
2323
2424 -- ** Allocation
2525 , PinnedState(..)
@@ -106,11 +106,6 @@ data MutableByteArray = MutableByteArray (MutableByteArray# RealWorld)
106106getMutableByteArray# :: MutableByteArray -> MutableByteArray# RealWorld
107107getMutableByteArray# (MutableByteArray mbarr) = mbarr
108108
109−{-# INLINE touch #-}
110−touch :: MutableByteArray -> IO ()
111−touch (MutableByteArray contents) =
112− IO $ \s -> case touch# contents s of s' -> (# s', () #)
113−
114109-- | Return the size of the array in bytes.
115110{-# INLINE sizeOfMutableByteArray #-}
116111sizeOfMutableByteArray :: MutableByteArray -> IO Int
@@ -119,6 +114,49 @@ sizeOfMutableByteArray (MutableByteArray arr) =
119114 case getSizeofMutableByteArray# arr s of
120115 (# s1, i #) -> (# s1, I# i #)
121116
117+{-# INLINE touch #-}
118+touch :: MutableByteArray -> IO ()
119+touch (MutableByteArray contents) =
120+ IO $ \s -> case touch# contents s of s' -> (# s', () #)
121+
122+-- XXX We can provide another API for "unsafe" FFI calls passing an unlifted
123+-- pointer to the FFI call. For unsafe calls we do not need to pin the array.
124+-- We can pass an unlifted pointer to the FFI routine to avoid GC kicking in
125+-- before the pointer is wrapped.
126+--
127+-- From the GHC manual:
128+--
129+-- GHC, since version 8.4, guarantees that garbage collection will never occur
130+-- during an unsafe call, even in the bytecode interpreter, and further
131+-- guarantees that unsafe calls will be performed in the calling thread. Making
132+-- it safe to pass heap-allocated objects to unsafe functions.
133+
134+-- | Use a @MutableByteArray@ as @Ptr a@. This is useful when we want to pass
135+-- an array as a pointer to some operating system call or to a "safe" FFI call.
136+--
137+-- If the array is not pinned it is copied to pinned memory before passing it
138+-- to the monadic action.
139+--
140+-- /Performance Notes:/ Forces a copy if the array is not pinned. It is advised
141+-- that the programmer keeps this in mind and creates a pinned array
142+-- opportunistically before this operation occurs, to avoid the cost of a copy
143+-- if possible.
144+--
145+-- /Unsafe/ because of direct pointer operations. The user must ensure that
146+-- they are writing within the legal bounds of the array.
147+--
148+-- /Pre-release/
149+--
150+{-# INLINE asPtrUnsafe #-}
151+asPtrUnsafe :: MonadIO m => MutableByteArray -> (Ptr a -> m b) -> m b
152+asPtrUnsafe arr f = do
153+ contents <- liftIO $ pin arr
154+ let !ptr = Ptr (byteArrayContents#
155+ (unsafeCoerce# (getMutableByteArray# contents)))
156+ r <- f ptr
157+ liftIO $ touch contents
158+ return r
159+
122160--------------------------------------------------------------------------------
123161-- Creation
124162--------------------------------------------------------------------------------