{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeApplications #-}
module Proof.Assistant.ResourceLimit where

import GHC.Natural
import System.Posix.Process (nice)
import System.Posix.Resource

import Proof.Assistant.Helpers
import Proof.Assistant.Settings

-- | Make ResourceLimits from soft/hard limits.
makeResourceLimits :: Limit -> ResourceLimits
makeResourceLimits :: Limit -> ResourceLimits
makeResourceLimits (Limit Natural
soft Natural
hard)
  = ResourceLimit -> ResourceLimit -> ResourceLimits
ResourceLimits (Natural -> ResourceLimit
toResourceLimit Natural
soft) (Natural -> ResourceLimit
toResourceLimit Natural
hard)
  where
    toResourceLimit :: Natural -> ResourceLimit
toResourceLimit = Integer -> ResourceLimit
ResourceLimit (Integer -> ResourceLimit)
-> (Natural -> Integer) -> Natural -> ResourceLimit
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Natural -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral

-- | Read Resources from 'ResourceSettings'.
makeLimits :: ResourceSettings -> [(Resource, ResourceLimits)]
makeLimits :: ResourceSettings -> [(Resource, ResourceLimits)]
makeLimits ResourceSettings{Limit
$sel:cpuTime:ResourceSettings :: ResourceSettings -> Limit
$sel:fileSize:ResourceSettings :: ResourceSettings -> Limit
$sel:openFiles:ResourceSettings :: ResourceSettings -> Limit
$sel:dataSize:ResourceSettings :: ResourceSettings -> Limit
$sel:totalMemory:ResourceSettings :: ResourceSettings -> Limit
cpuTime :: Limit
fileSize :: Limit
openFiles :: Limit
dataSize :: Limit
totalMemory :: Limit
..} =
  [ (Resource
ResourceTotalMemory,  Limit -> ResourceLimits
makeResourceLimits Limit
totalMemory)
  , (Resource
ResourceOpenFiles,    Limit -> ResourceLimits
makeResourceLimits Limit
openFiles)
  , (Resource
ResourceFileSize,     Limit -> ResourceLimits
makeResourceLimits Limit
fileSize)
  , (Resource
ResourceDataSize,     Limit -> ResourceLimits
makeResourceLimits Limit
dataSize)
  , (Resource
ResourceCPUTime,      Limit -> ResourceLimits
makeResourceLimits Limit
cpuTime)
  ]

-- | Read limits from 'ResourceSettings' and set them for current thread.
setLimits :: ResourceSettings -> IO ()
setLimits :: ResourceSettings -> IO ()
setLimits = ((Resource, ResourceLimits) -> IO ())
-> [(Resource, ResourceLimits)] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ((Resource -> ResourceLimits -> IO ())
-> (Resource, ResourceLimits) -> IO ()
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Resource -> ResourceLimits -> IO ()
setResourceLimit) ([(Resource, ResourceLimits)] -> IO ())
-> (ResourceSettings -> [(Resource, ResourceLimits)])
-> ResourceSettings
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ResourceSettings -> [(Resource, ResourceLimits)]
makeLimits

-- | Set 'Priority' for current thread.
setPriority :: Priority -> IO ()
setPriority :: Priority -> IO ()
setPriority = Int -> IO ()
nice (Int -> IO ()) -> (Priority -> Int) -> Priority -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Num Natural, Integral Natural, Coercible Priority Natural) =>
Priority -> Int
forall a b. (Num b, Integral b, Coercible a b) => a -> Int
toInt @_ @Natural