{-# LINE 1 "Data/Memory/MemMap/Posix.hsc" #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE CPP #-}
module Data.Memory.MemMap.Posix
( memoryMap
, memoryUnmap
, memoryAdvise
, memoryLock
, memoryUnlock
, memoryProtect
, memorySync
, MemoryMapFlag(..)
, MemoryProtection(..)
, MemoryAdvice(..)
, MemorySyncFlag(..)
, sysconfPageSize
) where
import System.Posix.Types
import Foreign.Ptr
import Foreign.C.Types
import Foreign.C.Error
import Data.Bits
foreign import ccall unsafe "mmap"
c_mmap :: Ptr a -> CSize -> CInt -> CInt -> CInt -> COff -> IO (Ptr a)
foreign import ccall unsafe "munmap"
c_munmap :: Ptr a -> CSize -> IO CInt
{-# LINE 55 "Data/Memory/MemMap/Posix.hsc" #-}
foreign import ccall unsafe "posix_madvise"
c_madvise :: Ptr a -> CSize -> CInt -> IO CInt
{-# LINE 61 "Data/Memory/MemMap/Posix.hsc" #-}
foreign import ccall unsafe "msync"
c_msync :: Ptr a -> CSize -> CInt -> IO CInt
foreign import ccall unsafe "mprotect"
c_mprotect :: Ptr a -> CSize -> CInt -> IO CInt
{-# LINE 69 "Data/Memory/MemMap/Posix.hsc" #-}
foreign import ccall unsafe "mlock"
c_mlock :: Ptr a -> CSize -> IO CInt
{-# LINE 75 "Data/Memory/MemMap/Posix.hsc" #-}
{-# LINE 77 "Data/Memory/MemMap/Posix.hsc" #-}
foreign import ccall unsafe "munlock"
c_munlock :: Ptr a -> CSize -> IO CInt
{-# LINE 83 "Data/Memory/MemMap/Posix.hsc" #-}
foreign import ccall unsafe "sysconf"
c_sysconf :: CInt -> CLong
data MemoryMapFlag =
MemoryMapShared
| MemoryMapPrivate
deriving (Show,Read,Eq)
data MemoryProtection =
MemoryProtectionNone
| MemoryProtectionRead
| MemoryProtectionWrite
| MemoryProtectionExecute
deriving (Show,Read,Eq)
data MemoryAdvice =
MemoryAdviceNormal
| MemoryAdviceRandom
| MemoryAdviceSequential
| MemoryAdviceWillNeed
| MemoryAdviceDontNeed
deriving (Show,Read,Eq)
data MemorySyncFlag =
MemorySyncAsync
| MemorySyncSync
| MemorySyncInvalidate
deriving (Show,Read,Eq)
cvalueOfMemoryProts :: [MemoryProtection] -> CInt
cvalueOfMemoryProts = foldl (.|.) 0 . map toProt
where toProt :: MemoryProtection -> CInt
toProt MemoryProtectionNone = (0)
{-# LINE 123 "Data/Memory/MemMap/Posix.hsc" #-}
toProt MemoryProtectionRead = (1)
{-# LINE 124 "Data/Memory/MemMap/Posix.hsc" #-}
toProt MemoryProtectionWrite = (2)
{-# LINE 125 "Data/Memory/MemMap/Posix.hsc" #-}
toProt MemoryProtectionExecute = (4)
{-# LINE 126 "Data/Memory/MemMap/Posix.hsc" #-}
cvalueOfMemorySync :: [MemorySyncFlag] -> CInt
cvalueOfMemorySync = foldl (.|.) 0 . map toSync
where toSync MemorySyncAsync = (1)
{-# LINE 130 "Data/Memory/MemMap/Posix.hsc" #-}
toSync MemorySyncSync = (4)
{-# LINE 131 "Data/Memory/MemMap/Posix.hsc" #-}
toSync MemorySyncInvalidate = (2)
{-# LINE 132 "Data/Memory/MemMap/Posix.hsc" #-}
memoryMap :: Maybe (Ptr a)
-> CSize
-> [MemoryProtection]
-> MemoryMapFlag
-> Maybe Fd
-> COff
-> IO (Ptr a)
memoryMap initPtr sz prots flag mfd off =
throwErrnoIf (== m1ptr) "mmap" (c_mmap (maybe nullPtr id initPtr) sz cprot cflags fd off)
where m1ptr = nullPtr `plusPtr` (-1)
fd = maybe (-1) (\(Fd v) -> v) mfd
cprot = cvalueOfMemoryProts prots
cflags = maybe cMapAnon (const 0) mfd
.|. maybe 0 (const cMapFixed) initPtr
.|. toMapFlag flag
{-# LINE 158 "Data/Memory/MemMap/Posix.hsc" #-}
cMapAnon = (32)
{-# LINE 159 "Data/Memory/MemMap/Posix.hsc" #-}
{-# LINE 160 "Data/Memory/MemMap/Posix.hsc" #-}
cMapFixed = (16)
{-# LINE 161 "Data/Memory/MemMap/Posix.hsc" #-}
toMapFlag MemoryMapShared = (1)
{-# LINE 163 "Data/Memory/MemMap/Posix.hsc" #-}
toMapFlag MemoryMapPrivate = (2)
{-# LINE 164 "Data/Memory/MemMap/Posix.hsc" #-}
memoryUnmap :: Ptr a -> CSize -> IO ()
memoryUnmap ptr sz = throwErrnoIfMinus1_ "munmap" (c_munmap ptr sz)
memoryAdvise :: Ptr a -> CSize -> MemoryAdvice -> IO ()
memoryAdvise ptr sz adv = throwErrnoIfMinus1_ "madvise" (c_madvise ptr sz cadv)
where cadv = toAdvice adv
{-# LINE 178 "Data/Memory/MemMap/Posix.hsc" #-}
toAdvice MemoryAdviceNormal = (0)
{-# LINE 179 "Data/Memory/MemMap/Posix.hsc" #-}
toAdvice MemoryAdviceRandom = (1)
{-# LINE 180 "Data/Memory/MemMap/Posix.hsc" #-}
toAdvice MemoryAdviceSequential = (2)
{-# LINE 181 "Data/Memory/MemMap/Posix.hsc" #-}
toAdvice MemoryAdviceWillNeed = (3)
{-# LINE 182 "Data/Memory/MemMap/Posix.hsc" #-}
toAdvice MemoryAdviceDontNeed = (4)
{-# LINE 183 "Data/Memory/MemMap/Posix.hsc" #-}
{-# LINE 190 "Data/Memory/MemMap/Posix.hsc" #-}
memoryLock :: Ptr a -> CSize -> IO ()
memoryLock ptr sz = throwErrnoIfMinus1_ "mlock" (c_mlock ptr sz)
memoryUnlock :: Ptr a -> CSize -> IO ()
memoryUnlock ptr sz = throwErrnoIfMinus1_ "munlock" (c_munlock ptr sz)
memoryProtect :: Ptr a -> CSize -> [MemoryProtection] -> IO ()
memoryProtect ptr sz prots = throwErrnoIfMinus1_ "mprotect" (c_mprotect ptr sz cprot)
where cprot = cvalueOfMemoryProts prots
memorySync :: Ptr a -> CSize -> [MemorySyncFlag] -> IO ()
memorySync ptr sz flags = throwErrnoIfMinus1_ "msync" (c_msync ptr sz cflags)
where cflags = cvalueOfMemorySync flags
sysconfPageSize :: Int
sysconfPageSize = fromIntegral $ c_sysconf (30)
{-# LINE 223 "Data/Memory/MemMap/Posix.hsc" #-}