Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use unsafeDupablePerformIO instead of unsafePerformIO in struct field reads? #157

Open
l29ah opened this issue Aug 26, 2020 · 4 comments
Open

Comments

@l29ah
Copy link

l29ah commented Aug 26, 2020

As it unsafePerformIO is much slower and forces the program to run single-threadedly while providing no benefits.

@hs-viktor
Copy link
Contributor

Can you point at a few salient examples?

@hasufell
Copy link
Member

hasufell commented Jul 10, 2022

As it unsafePerformIO is much slower and forces the program to run single-threadedly while providing no benefits.

It does provide benefits. bracketed functions inside unsafeDupablePerformIO are broken: https://hackage.haskell.org/package/base-4.16.2.0/docs/System-IO-Unsafe.html#v:unsafeDupablePerformIO

So we'd need to know exactly what you mean to judge whether that's a good idea.

@l29ah
Copy link
Author

l29ah commented Jul 10, 2022

@hs-viktor
Copy link
Contributor

Indeed those particular examples are IIRC safe for unsafeDupablePerformIO or even something more aggressive, like similar read-only code in bytestring via accursedUnutterablePerformIO:

{-# INLINE accursedUnutterablePerformIO #-}
accursedUnutterablePerformIO :: IO a -> a
accursedUnutterablePerformIO (IO m) = case m realWorld# of (# _, r #) -> r

The difference with unsafeDupablePerformIO is:

unsafeDupablePerformIO (IO m) = case runRW# m of (# _, a #) -> lazy a

Which takes a few extra precautions against some compiler optimisations, but ultimately (late) inlines to similar code. My sense is that if the bytestring code can read foreign pointer payloads with accursedUnutterablePerformIO, the same should be true here. For example in ByteString.head, we have: accursedUnutterablePerformIO $ unsafeWithForeignPtr x $ \p -> peek p. Which by the way also uses unsafeWithForeignPtr.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants