summaryrefslogtreecommitdiff
path: root/libraries/base/GHC/ForeignPtr.hs
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2009-03-05 15:41:53 +0000
committerSimon Marlow <marlowsd@gmail.com>2009-03-05 15:41:53 +0000
commit7fc5bad13ca8170a5e28d059909bde5d36fbbcb0 (patch)
treea9065da118fda8d1bdf6884609c828f44c7263ac /libraries/base/GHC/ForeignPtr.hs
parentc751ba577d50817e6273ad7ee421a94fe39c694d (diff)
downloadhaskell-7fc5bad13ca8170a5e28d059909bde5d36fbbcb0.tar.gz
Partial fix for #2917
- add newAlignedPinnedByteArray# for allocating pinned BAs with arbitrary alignment - the old newPinnedByteArray# now aligns to 16 bytes Foreign.alloca will use newAlignedPinnedByteArray#, and so might end up wasting less space than before (we used to align to 8 by default). Foreign.allocaBytes and Foreign.mallocForeignPtrBytes will get 16-byte aligned memory, which is enough to avoid problems with SSE instructions on x86, for example. There was a bug in the old newPinnedByteArray#: it aligned to 8 bytes, but would have failed if the header was not a multiple of 8 (fortunately it always was, even with profiling). Also we occasionally wasted some space unnecessarily due to alignment in allocatePinned(). I haven't done anything about Foreign.malloc/mallocBytes, which will give you the same alignment guarantees as malloc() (8 bytes on Linux/x86 here).
Diffstat (limited to 'libraries/base/GHC/ForeignPtr.hs')
-rw-r--r--libraries/base/GHC/ForeignPtr.hs10
1 files changed, 6 insertions, 4 deletions
diff --git a/libraries/base/GHC/ForeignPtr.hs b/libraries/base/GHC/ForeignPtr.hs
index 50fa58d043..9868942d76 100644
--- a/libraries/base/GHC/ForeignPtr.hs
+++ b/libraries/base/GHC/ForeignPtr.hs
@@ -152,11 +152,12 @@ mallocForeignPtr = doMalloc undefined
doMalloc a = do
r <- newIORef (NoFinalizers, [])
IO $ \s ->
- case newPinnedByteArray# size s of { (# s', mbarr# #) ->
+ case newAlignedPinnedByteArray# size align s of { (# s', mbarr# #) ->
(# s', ForeignPtr (byteArrayContents# (unsafeCoerce# mbarr#))
(MallocPtr mbarr# r) #)
}
- where (I# size) = sizeOf a
+ where (I# size) = sizeOf a
+ (I# align) = alignment a
-- | This function is similar to 'mallocForeignPtr', except that the
-- size of the memory required is given explicitly as a number of bytes.
@@ -186,11 +187,12 @@ mallocPlainForeignPtr :: Storable a => IO (ForeignPtr a)
mallocPlainForeignPtr = doMalloc undefined
where doMalloc :: Storable b => b -> IO (ForeignPtr b)
doMalloc a = IO $ \s ->
- case newPinnedByteArray# size s of { (# s', mbarr# #) ->
+ case newAlignedPinnedByteArray# size align s of { (# s', mbarr# #) ->
(# s', ForeignPtr (byteArrayContents# (unsafeCoerce# mbarr#))
(PlainPtr mbarr#) #)
}
- where (I# size) = sizeOf a
+ where (I# size) = sizeOf a
+ (I# align) = alignment a
-- | This function is similar to 'mallocForeignPtrBytes', except that
-- the internally an optimised ForeignPtr representation with no