effectful-core 2.2.2.0 → 2.2.2.1
raw patch · 6 files changed
+132/−128 lines, 6 filesdep −effectful-coredep ~basePVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
Dependencies removed: effectful-core
Dependency ranges changed: base
API changes (from Hackage documentation)
+ Effectful.Internal.Utils: data IORef' a
+ Effectful.Internal.Utils: data MVar' a
+ Effectful.Internal.Utils: eqThreadId :: ThreadId -> ThreadId -> Bool
+ Effectful.Internal.Utils: fromAny :: Any -> a
+ Effectful.Internal.Utils: modifyMVar' :: MVar' a -> (a -> IO (a, r)) -> IO r
+ Effectful.Internal.Utils: modifyMVar_' :: MVar' a -> (a -> IO a) -> IO ()
+ Effectful.Internal.Utils: newIORef' :: a -> IO (IORef' a)
+ Effectful.Internal.Utils: newMVar' :: a -> IO (MVar' a)
+ Effectful.Internal.Utils: readIORef' :: IORef' a -> IO a
+ Effectful.Internal.Utils: readMVar' :: MVar' a -> IO a
+ Effectful.Internal.Utils: toAny :: a -> Any
+ Effectful.Internal.Utils: toMVar' :: MVar a -> IO (MVar' a)
+ Effectful.Internal.Utils: type family Any :: k
+ Effectful.Internal.Utils: weakThreadId :: ThreadId -> Int
+ Effectful.Internal.Utils: writeIORef' :: IORef' a -> a -> IO ()
Files
- CHANGELOG.md +3/−0
- cbits/utils.c +5/−0
- effectful-core.cabal +4/−15
- src/Effectful/Internal/Utils.hs +120/−0
- utils/Effectful/Internal/Utils.hs +0/−108
- utils/utils.c +0/−5
CHANGELOG.md view
@@ -1,3 +1,6 @@+# effectful-core-2.2.2.1 (2023-01-12)+* Stop using the internal library because of bugs in `stack`.+ # effectful-core-2.2.2.0 (2023-01-11) * Add `withSeqEffToIO` and `withConcEffToIO` to `Effectful`. * Use strict `IORef` and `MVar` variants where appropriate.
+ cbits/utils.c view
@@ -0,0 +1,5 @@+// Correct implementation of ThreadId# equality for GHC < 9.+long effectful_eq_thread(void *tso1, void *tso2)+{+ return tso1 == tso2;+}
effectful-core.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.4 build-type: Simple name: effectful-core-version: 2.2.2.0+version: 2.2.2.1 license: BSD-3-Clause license-file: LICENSE category: Control@@ -54,23 +54,11 @@ TypeFamilies TypeOperators -library effectful-internal-utils- import: language-- build-depends: base-- hs-source-dirs: utils- c-sources: utils/utils.c-- exposed-modules: Effectful.Internal.Utils- library import: language ghc-options: -O2 - build-depends: effectful-internal-utils- build-depends: base >= 4.13 && < 5 , containers >= 0.6 , exceptions >= 0.10.4@@ -81,6 +69,8 @@ hs-source-dirs: src + c-sources: cbits/utils.c+ exposed-modules: Effectful Effectful.Dispatch.Dynamic Effectful.Dispatch.Static@@ -93,6 +83,7 @@ Effectful.Internal.Env Effectful.Internal.Monad Effectful.Internal.Unlift+ Effectful.Internal.Utils Effectful.NonDet Effectful.Prim Effectful.Reader.Dynamic@@ -103,5 +94,3 @@ Effectful.Writer.Dynamic Effectful.Writer.Static.Local Effectful.Writer.Static.Shared-- reexported-modules: Effectful.Internal.Utils
+ src/Effectful/Internal/Utils.hs view
@@ -0,0 +1,120 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE UnliftedFFITypes #-}+{-# OPTIONS_HADDOCK not-home #-}+module Effectful.Internal.Utils+ ( weakThreadId+ , eqThreadId++ -- * Strict 'IORef'+ , IORef'+ , newIORef'+ , readIORef'+ , writeIORef'++ -- * Strict 'MVar'+ , MVar'+ , toMVar'+ , newMVar'+ , readMVar'+ , modifyMVar'+ , modifyMVar_'++ -- * Utils for 'Any'+ , Any+ , toAny+ , fromAny+ ) where++import Control.Concurrent.MVar+import Data.IORef+import Foreign.C.Types+import GHC.Conc.Sync (ThreadId(..))+import GHC.Exts (Addr#, Any, ThreadId#, unsafeCoerce#)+import Unsafe.Coerce (unsafeCoerce)++-- | Get an id of a thread that doesn't prevent its garbage collection.+weakThreadId :: ThreadId -> Int+weakThreadId (ThreadId t#) = fromIntegral $ rts_getThreadId (threadIdToAddr# t#)++foreign import ccall unsafe "rts_getThreadId"+#if __GLASGOW_HASKELL__ >= 904+ -- https://gitlab.haskell.org/ghc/ghc/-/merge_requests/6163+ rts_getThreadId :: Addr# -> CULLong+#elif __GLASGOW_HASKELL__ >= 900+ -- https://gitlab.haskell.org/ghc/ghc/-/merge_requests/1254+ rts_getThreadId :: Addr# -> CLong+#else+ rts_getThreadId :: Addr# -> CInt+#endif++-- | 'Eq' instance for 'ThreadId' is broken in GHC < 9, see+-- https://gitlab.haskell.org/ghc/ghc/-/issues/16761 for more info.+eqThreadId :: ThreadId -> ThreadId -> Bool+eqThreadId (ThreadId t1#) (ThreadId t2#) =+ eq_thread (threadIdToAddr# t1#) (threadIdToAddr# t2#) == 1++foreign import ccall unsafe "effectful_eq_thread"+ eq_thread :: Addr# -> Addr# -> CLong++-- Note: FFI imports take Addr# instead of ThreadId# because of+-- https://gitlab.haskell.org/ghc/ghc/-/issues/8281, which would prevent loading+-- effectful-core into GHCi.+--+-- Previous workaround was to use an internal library with just this module, but+-- this is not viable because of bugs in stack (sigh).+--+-- The coercion is fine because GHC represents ThreadId# as a pointer.+threadIdToAddr# :: ThreadId# -> Addr#+threadIdToAddr# = unsafeCoerce#++----------------------------------------++-- | A strict variant of 'IORef'.+newtype IORef' a = IORef' (IORef a)++newIORef' :: a -> IO (IORef' a)+newIORef' a = a `seq` (IORef' <$> newIORef a)++readIORef' :: IORef' a -> IO a+readIORef' (IORef' var) = readIORef var++writeIORef' :: IORef' a -> a -> IO ()+writeIORef' (IORef' var) a = a `seq` writeIORef var a++----------------------------------------++-- | A strict variant of 'MVar'.+newtype MVar' a = MVar' (MVar a)++toMVar' :: MVar a -> IO (MVar' a)+toMVar' var = do+ let var' = MVar' var+ modifyMVar_' var' pure+ pure var'++newMVar' :: a -> IO (MVar' a)+newMVar' a = a `seq` (MVar' <$> newMVar a)++readMVar' :: MVar' a -> IO a+readMVar' (MVar' var) = readMVar var++modifyMVar' :: MVar' a -> (a -> IO (a, r)) -> IO r+modifyMVar' (MVar' var) action = modifyMVar var $ \a0 -> do+ (a, r) <- action a0+ a `seq` pure (a, r)+{-# INLINE modifyMVar' #-}++modifyMVar_' :: MVar' a -> (a -> IO a) -> IO ()+modifyMVar_' (MVar' var) action = modifyMVar_ var $ \a0 -> do+ a <- action a0+ a `seq` pure a+{-# INLINE modifyMVar_' #-}++----------------------------------------++toAny :: a -> Any+toAny = unsafeCoerce++fromAny :: Any -> a+fromAny = unsafeCoerce
− utils/Effectful/Internal/Utils.hs
@@ -1,108 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE MagicHash #-}-{-# LANGUAGE UnliftedFFITypes #-}-{-# OPTIONS_HADDOCK not-home #-}-module Effectful.Internal.Utils- ( weakThreadId- , eqThreadId-- -- * Strict 'IORef'- , IORef'- , newIORef'- , readIORef'- , writeIORef'-- -- * Strict 'MVar'- , MVar'- , toMVar'- , newMVar'- , readMVar'- , modifyMVar'- , modifyMVar_'-- -- * Utils for 'Any'- , Any- , toAny- , fromAny- ) where--import Control.Concurrent.MVar-import Data.IORef-import Foreign.C.Types-import GHC.Conc.Sync (ThreadId(..))-import GHC.Exts (Any, ThreadId#)-import Unsafe.Coerce (unsafeCoerce)---- | Get an id of a thread that doesn't prevent its garbage collection.-weakThreadId :: ThreadId -> Int-weakThreadId (ThreadId t#) = fromIntegral $ rts_getThreadId t#--foreign import ccall unsafe "rts_getThreadId"-#if __GLASGOW_HASKELL__ >= 904- -- https://gitlab.haskell.org/ghc/ghc/-/merge_requests/6163- rts_getThreadId :: ThreadId# -> CULLong-#elif __GLASGOW_HASKELL__ >= 900- -- https://gitlab.haskell.org/ghc/ghc/-/merge_requests/1254- rts_getThreadId :: ThreadId# -> CLong-#else- rts_getThreadId :: ThreadId# -> CInt-#endif---- | 'Eq' instance for 'ThreadId' is broken in GHC < 9, see--- https://gitlab.haskell.org/ghc/ghc/-/issues/16761 for more info.-eqThreadId :: ThreadId -> ThreadId -> Bool-eqThreadId (ThreadId t1#) (ThreadId t2#) = eq_thread t1# t2# == 1--foreign import ccall unsafe "effectful_eq_thread"- eq_thread :: ThreadId# -> ThreadId# -> CLong---------------------------------------------- | A strict variant of 'IORef'.-newtype IORef' a = IORef' (IORef a)--newIORef' :: a -> IO (IORef' a)-newIORef' a = a `seq` (IORef' <$> newIORef a)--readIORef' :: IORef' a -> IO a-readIORef' (IORef' var) = readIORef var--writeIORef' :: IORef' a -> a -> IO ()-writeIORef' (IORef' var) a = a `seq` writeIORef var a---------------------------------------------- | A strict variant of 'MVar'.-newtype MVar' a = MVar' (MVar a)--toMVar' :: MVar a -> IO (MVar' a)-toMVar' var = do- let var' = MVar' var- modifyMVar_' var' pure- pure var'--newMVar' :: a -> IO (MVar' a)-newMVar' a = a `seq` (MVar' <$> newMVar a)--readMVar' :: MVar' a -> IO a-readMVar' (MVar' var) = readMVar var--modifyMVar' :: MVar' a -> (a -> IO (a, r)) -> IO r-modifyMVar' (MVar' var) action = modifyMVar var $ \a0 -> do- (a, r) <- action a0- a `seq` pure (a, r)-{-# INLINE modifyMVar' #-}--modifyMVar_' :: MVar' a -> (a -> IO a) -> IO ()-modifyMVar_' (MVar' var) action = modifyMVar_ var $ \a0 -> do- a <- action a0- a `seq` pure a-{-# INLINE modifyMVar_' #-}--------------------------------------------toAny :: a -> Any-toAny = unsafeCoerce--fromAny :: Any -> a-fromAny = unsafeCoerce
− utils/utils.c
@@ -1,5 +0,0 @@-// Correct implementation of ThreadId# equality for GHC < 9.-long effectful_eq_thread(void *tso1, void *tso2)-{- return tso1 == tso2;-}