----------------------------------------------------------------------------- -- | -- Module : System.Information.CPU2 -- Copyright : (c) José A. Romero L. -- License : BSD3-style (see LICENSE) -- -- Maintainer : José A. Romero L. -- Stability : unstable -- Portability : unportable -- -- Provides information about used CPU times, obtained from parsing the -- @\/proc\/stat@ file using some of the facilities included in the -- "System.Information.StreamInfo" module. -- And also provides information about the temperature of cores. -- (Now supports only physical cpu). -- ----------------------------------------------------------------------------- module System.Information.CPU2 ( getCPULoad, getCPUInfo, getCPUTemp ) where import Data.Maybe ( mapMaybe ) import Safe ( atMay, readDef, tailSafe ) import System.Information.StreamInfo ( getLoad, getParsedInfo ) import Control.Monad (liftM) -- | Returns a two-element list containing relative system and user times -- calculated using two almost simultaneous samples of the @\/proc\/stat@ file -- for the given core (or all of them aggregated, if \"cpu\" is passed). getCPULoad :: String -> IO [Double] getCPULoad cpu = do load <- getLoad 0.05 $ getCPUInfo cpu case load of l0:l1:l2:_ -> return [ l0 + l1, l2 ] _ -> return [] -- | Returns a list containing temperatures of user given cpu cores. -- Use ["cpu1", "cpu2".."cpuN"] to get temperature of exact cores. -- Use ["cpu0"] to get common temperature. getCPUTemp :: [String] -> IO [Int] getCPUTemp cpus = do let cpus' = map (\s -> [last s]) cpus liftM concat $ mapM (\cpu -> getParsedInfo ("/sys/bus/platform/devices/coretemp.0/temp" ++ show ((read cpu::Int) + 1) ++ "_input") (\s -> [("temp", [(read s::Int) `div` 1000])]) "temp") cpus' --TODO and suppoprt for more than 1 physical cpu. -- | Returns a list of 5 to 7 elements containing all the values available for -- the given core (or all of them aggregated, if "cpu" is passed). getCPUInfo :: String -> IO [Int] getCPUInfo = getParsedInfo "/proc/stat" parse parse :: String -> [(String, [Int])] parse = mapMaybe (tuplize . words) . filter (\x -> take 3 x == "cpu") . lines tuplize :: [String] -> Maybe (String, [Int]) tuplize s = do cpu <- s `atMay` 0 return (cpu, map (readDef (-1)) (tailSafe s))