{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE BangPatterns #-}
module Xmobar.Plugins.Monitors.Top (startTop, topMemConfig, runTopMem) where
import Xmobar.Plugins.Monitors.Common
import Control.Exception (SomeException, handle)
import Data.IORef (IORef, newIORef, readIORef, writeIORef)
import Data.List (sortBy, foldl')
import Data.Ord (comparing)
import Data.Time.Clock (UTCTime, getCurrentTime, diffUTCTime)
import System.Directory (getDirectoryContents)
import System.FilePath ((</>))
import System.IO (IOMode(ReadMode), hGetLine, withFile)
import System.Posix.Unistd (SysVar(ClockTick), getSysVar)
import Foreign.C.Types
maxEntries :: Int
maxEntries :: Pid
maxEntries = Pid
10
intStrs :: [String]
intStrs :: [String]
intStrs = (Pid -> String) -> [Pid] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Pid -> String
forall a. Show a => a -> String
show [Pid
1..Pid
maxEntries]
topMemConfig :: IO MConfig
topMemConfig :: IO MConfig
topMemConfig = String -> [String] -> IO MConfig
mkMConfig String
"<both1>"
[ String
k String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
n | String
n <- [String]
intStrs , String
k <- [String
"name", String
"mem", String
"both"]]
topConfig :: IO MConfig
topConfig :: IO MConfig
topConfig = String -> [String] -> IO MConfig
mkMConfig String
"<both1>"
(String
"no" String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [ String
k String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
n | String
n <- [String]
intStrs
, String
k <- [ String
"name", String
"cpu", String
"both"
, String
"mname", String
"mem", String
"mboth"]])
foreign import ccall "unistd.h getpagesize"
c_getpagesize :: CInt
pageSize :: Float
pageSize :: Float
pageSize = CInt -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
c_getpagesize Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
1024
processes :: IO [FilePath]
processes :: IO [String]
processes = ([String] -> [String]) -> IO [String] -> IO [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
filter String -> Bool
isPid) (String -> IO [String]
getDirectoryContents String
"/proc")
where isPid :: String -> Bool
isPid = (Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Char
'0'..Char
'9']) (Char -> Bool) -> (String -> Char) -> String -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Char
forall a. [a] -> a
head
statWords :: [String] -> [String]
statWords :: [String] -> [String]
statWords line :: [String]
line@(String
x:String
pn:String
ppn:[String]
xs) =
if String -> Char
forall a. [a] -> a
last String
pn Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
')' then [String]
line else [String] -> [String]
statWords (String
xString -> [String] -> [String]
forall a. a -> [a] -> [a]
:(String
pn String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
ppn)String -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
xs)
statWords [String]
_ = Pid -> String -> [String]
forall a. Pid -> a -> [a]
replicate Pid
52 String
"0"
getProcessData :: FilePath -> IO [String]
getProcessData :: String -> IO [String]
getProcessData String
pidf =
(SomeException -> IO [String]) -> IO [String] -> IO [String]
forall e a. Exception e => (e -> IO a) -> IO a -> IO a
handle SomeException -> IO [String]
ign (IO [String] -> IO [String]) -> IO [String] -> IO [String]
forall a b. (a -> b) -> a -> b
$ String -> IOMode -> (Handle -> IO [String]) -> IO [String]
forall r. String -> IOMode -> (Handle -> IO r) -> IO r
withFile (String
"/proc" String -> String -> String
</> String
pidf String -> String -> String
</> String
"stat") IOMode
ReadMode Handle -> IO [String]
readWords
where readWords :: Handle -> IO [String]
readWords = (String -> [String]) -> IO String -> IO [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([String] -> [String]
statWords ([String] -> [String])
-> (String -> [String]) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
words) (IO String -> IO [String])
-> (Handle -> IO String) -> Handle -> IO [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO String
hGetLine
ign :: SomeException -> IO [String]
ign = IO [String] -> SomeException -> IO [String]
forall a b. a -> b -> a
const ([String] -> IO [String]
forall (m :: * -> *) a. Monad m => a -> m a
return []) :: SomeException -> IO [String]
memPages :: [String] -> String
memPages :: [String] -> String
memPages [String]
fs = [String]
fs[String] -> Pid -> String
forall a. [a] -> Pid -> a
!!Pid
23
ppid :: [String] -> String
ppid :: [String] -> String
ppid [String]
fs = [String]
fs[String] -> Pid -> String
forall a. [a] -> Pid -> a
!!Pid
3
skip :: [String] -> Bool
skip :: [String] -> Bool
skip [String]
fs = [String] -> Pid
forall (t :: * -> *) a. Foldable t => t a -> Pid
length [String]
fs Pid -> Pid -> Bool
forall a. Ord a => a -> a -> Bool
< Pid
24 Bool -> Bool -> Bool
|| [String] -> String
memPages [String]
fs String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"0" Bool -> Bool -> Bool
|| [String] -> String
ppid [String]
fs String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"0"
handleProcesses :: ([String] -> a) -> IO [a]
handleProcesses :: forall a. ([String] -> a) -> IO [a]
handleProcesses [String] -> a
f =
([[String]] -> [a]) -> IO [[String]] -> IO [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([a] -> [String] -> [a]) -> [a] -> [[String]] -> [a]
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\[a]
a [String]
p -> if [String] -> Bool
skip [String]
p then [a]
a else [String] -> a
f [String]
p a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
a) [])
(IO [String]
processes IO [String] -> ([String] -> IO [[String]]) -> IO [[String]]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (String -> IO [String]) -> [String] -> IO [[String]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM String -> IO [String]
getProcessData)
showInfo :: String -> String -> Float -> Monitor [String]
showInfo :: String -> String -> Float -> Monitor [String]
showInfo String
nm String
sms Float
mms = do
Pid
mnw <- Selector Pid -> Monitor Pid
forall a. Selector a -> Monitor a
getConfigValue Selector Pid
maxWidth
Pid
mxw <- Selector Pid -> Monitor Pid
forall a. Selector a -> Monitor a
getConfigValue Selector Pid
minWidth
let lsms :: Pid
lsms = String -> Pid
forall (t :: * -> *) a. Foldable t => t a -> Pid
length String
sms
nmw :: Pid
nmw = Pid
mnw Pid -> Pid -> Pid
forall a. Num a => a -> a -> a
- Pid
lsms Pid -> Pid -> Pid
forall a. Num a => a -> a -> a
- Pid
1
nmx :: Pid
nmx = Pid
mxw Pid -> Pid -> Pid
forall a. Num a => a -> a -> a
- Pid
lsms Pid -> Pid -> Pid
forall a. Num a => a -> a -> a
- Pid
1
rnm :: String
rnm = if Pid
nmw Pid -> Pid -> Bool
forall a. Ord a => a -> a -> Bool
> Pid
0 then Pid -> Pid -> String -> Bool -> String -> String -> String
padString Pid
nmw Pid
nmx String
" " Bool
True String
"" String
nm else String
nm
String
mstr <- String -> Float -> Monitor String
forall a. (Num a, Ord a) => String -> a -> Monitor String
showWithColors' String
sms Float
mms
String
both <- String -> Float -> Monitor String
forall a. (Num a, Ord a) => String -> a -> Monitor String
showWithColors' (String
rnm String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
sms) Float
mms
[String] -> Monitor [String]
forall (m :: * -> *) a. Monad m => a -> m a
return [String
nm, String
mstr, String
both]
processName :: [String] -> String
processName :: [String] -> String
processName = Pid -> String -> String
forall a. Pid -> [a] -> [a]
drop Pid
1 (String -> String) -> ([String] -> String) -> [String] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
forall a. [a] -> [a]
init (String -> String) -> ([String] -> String) -> [String] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([String] -> Pid -> String
forall a. [a] -> Pid -> a
!!Pid
1)
sortTop :: [(String, Float)] -> [(String, Float)]
sortTop :: [(String, Float)] -> [(String, Float)]
sortTop = ((String, Float) -> (String, Float) -> Ordering)
-> [(String, Float)] -> [(String, Float)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (((String, Float) -> (String, Float) -> Ordering)
-> (String, Float) -> (String, Float) -> Ordering
forall a b c. (a -> b -> c) -> b -> a -> c
flip (((String, Float) -> Float)
-> (String, Float) -> (String, Float) -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing (String, Float) -> Float
forall a b. (a, b) -> b
snd))
type MemInfo = (String, Float)
meminfo :: [String] -> MemInfo
meminfo :: [String] -> (String, Float)
meminfo [String]
fs = ([String] -> String
processName [String]
fs, Float
pageSize Float -> Float -> Float
forall a. Num a => a -> a -> a
* String -> Float
parseFloat ([String]
fs[String] -> Pid -> String
forall a. [a] -> Pid -> a
!!Pid
23))
meminfos :: IO [MemInfo]
meminfos :: IO [(String, Float)]
meminfos = ([String] -> (String, Float)) -> IO [(String, Float)]
forall a. ([String] -> a) -> IO [a]
handleProcesses [String] -> (String, Float)
meminfo
showMemInfo :: Float -> MemInfo -> Monitor [String]
showMemInfo :: Float -> (String, Float) -> Monitor [String]
showMemInfo Float
scale (String
nm, Float
rss) =
String -> String -> Float -> Monitor [String]
showInfo String
nm (Pid -> Pid -> Float -> String
showWithUnits Pid
3 Pid
1 Float
rss) (Float
100 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
rss Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
sc)
where sc :: Float
sc = if Float
scale Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
> Float
0 then Float
scale else Float
100
showMemInfos :: [MemInfo] -> Monitor [[String]]
showMemInfos :: [(String, Float)] -> Monitor [[String]]
showMemInfos [(String, Float)]
ms = ((String, Float) -> Monitor [String])
-> [(String, Float)] -> Monitor [[String]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Float -> (String, Float) -> Monitor [String]
showMemInfo Float
tm) [(String, Float)]
ms
where tm :: Float
tm = [Float] -> Float
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (((String, Float) -> Float) -> [(String, Float)] -> [Float]
forall a b. (a -> b) -> [a] -> [b]
map (String, Float) -> Float
forall a b. (a, b) -> b
snd [(String, Float)]
ms)
runTopMem :: [String] -> Monitor String
runTopMem :: [String] -> Monitor String
runTopMem [String]
_ = do
[(String, Float)]
mis <- IO [(String, Float)] -> Monitor [(String, Float)]
forall a. IO a -> Monitor a
io IO [(String, Float)]
meminfos
[[String]]
pstr <- [(String, Float)] -> Monitor [[String]]
showMemInfos ([(String, Float)] -> [(String, Float)]
sortTop [(String, Float)]
mis)
[String] -> Monitor String
parseTemplate ([String] -> Monitor String) -> [String] -> Monitor String
forall a b. (a -> b) -> a -> b
$ [[String]] -> [String]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[String]]
pstr
type Pid = Int
type TimeInfo = (String, Float)
type TimeEntry = (Pid, TimeInfo)
type Times = [TimeEntry]
type TimesRef = IORef (Times, UTCTime)
timeMemEntry :: [String] -> (TimeEntry, MemInfo)
timeMemEntry :: [String] -> (TimeEntry, (String, Float))
timeMemEntry [String]
fs = ((Pid
p, (String
n, Float
t)), (String
n, Float
r))
where p :: Pid
p = String -> Pid
parseInt ([String] -> String
forall a. [a] -> a
head [String]
fs)
n :: String
n = [String] -> String
processName [String]
fs
t :: Float
t = String -> Float
parseFloat ([String]
fs[String] -> Pid -> String
forall a. [a] -> Pid -> a
!!Pid
13) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ String -> Float
parseFloat ([String]
fs[String] -> Pid -> String
forall a. [a] -> Pid -> a
!!Pid
14)
(String
_, Float
r) = [String] -> (String, Float)
meminfo [String]
fs
timeMemEntries :: IO [(TimeEntry, MemInfo)]
timeMemEntries :: IO [(TimeEntry, (String, Float))]
timeMemEntries = ([String] -> (TimeEntry, (String, Float)))
-> IO [(TimeEntry, (String, Float))]
forall a. ([String] -> a) -> IO [a]
handleProcesses [String] -> (TimeEntry, (String, Float))
timeMemEntry
timeMemInfos :: IO (Times, [MemInfo], Int)
timeMemInfos :: IO (Times, [(String, Float)], Pid)
timeMemInfos = ([(TimeEntry, (String, Float))] -> (Times, [(String, Float)], Pid))
-> IO [(TimeEntry, (String, Float))]
-> IO (Times, [(String, Float)], Pid)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(TimeEntry, (String, Float))] -> (Times, [(String, Float)], Pid)
forall {a} {b} {b}. Ord a => [((a, b), b)] -> ([(a, b)], [b], Pid)
res IO [(TimeEntry, (String, Float))]
timeMemEntries
where res :: [((a, b), b)] -> ([(a, b)], [b], Pid)
res [((a, b), b)]
x = (((a, b) -> (a, b) -> Ordering) -> [(a, b)] -> [(a, b)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (((a, b) -> a) -> (a, b) -> (a, b) -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing (a, b) -> a
forall a b. (a, b) -> a
fst) ([(a, b)] -> [(a, b)]) -> [(a, b)] -> [(a, b)]
forall a b. (a -> b) -> a -> b
$ (((a, b), b) -> (a, b)) -> [((a, b), b)] -> [(a, b)]
forall a b. (a -> b) -> [a] -> [b]
map ((a, b), b) -> (a, b)
forall a b. (a, b) -> a
fst [((a, b), b)]
x, (((a, b), b) -> b) -> [((a, b), b)] -> [b]
forall a b. (a -> b) -> [a] -> [b]
map ((a, b), b) -> b
forall a b. (a, b) -> b
snd [((a, b), b)]
x, [((a, b), b)] -> Pid
forall (t :: * -> *) a. Foldable t => t a -> Pid
length [((a, b), b)]
x)
combine :: Times -> Times -> Times
combine :: Times -> Times -> Times
combine Times
_ [] = []
combine [] Times
ts = Times
ts
combine l :: Times
l@((Pid
p0, (String
n0, Float
t0)):Times
ls) r :: Times
r@((Pid
p1, (String
n1, Float
t1)):Times
rs)
| Pid
p0 Pid -> Pid -> Bool
forall a. Eq a => a -> a -> Bool
== Pid
p1 Bool -> Bool -> Bool
&& String
n0 String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
n1 = (Pid
p0, (String
n0, Float
t1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
t0)) TimeEntry -> Times -> Times
forall a. a -> [a] -> [a]
: Times -> Times -> Times
combine Times
ls Times
rs
| Pid
p0 Pid -> Pid -> Bool
forall a. Ord a => a -> a -> Bool
<= Pid
p1 = Times -> Times -> Times
combine Times
ls Times
r
| Bool
otherwise = (Pid
p1, (String
n1, Float
t1)) TimeEntry -> Times -> Times
forall a. a -> [a] -> [a]
: Times -> Times -> Times
combine Times
l Times
rs
take' :: Int -> [a] -> [a]
take' :: forall a. Pid -> [a] -> [a]
take' Pid
m [a]
l = let !r :: [a]
r = Pid -> [a] -> [a]
forall {a} {a}. (Eq a, Num a) => a -> [a] -> [a]
tk Pid
m [a]
l in [a] -> Pid
forall (t :: * -> *) a. Foldable t => t a -> Pid
length [a]
l Pid -> [a] -> [a]
`seq` [a]
r
where tk :: a -> [a] -> [a]
tk a
0 [a]
_ = []
tk a
_ [] = []
tk a
n (a
x:[a]
xs) = let !r :: [a]
r = a -> [a] -> [a]
tk (a
n a -> a -> a
forall a. Num a => a -> a -> a
- a
1) [a]
xs in a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
r
topProcesses :: TimesRef -> Float -> IO (Int, [TimeInfo], [MemInfo])
topProcesses :: TimesRef -> Float -> IO (Pid, [(String, Float)], [(String, Float)])
topProcesses TimesRef
tref Float
scale = do
(Times
t0, UTCTime
c0) <- TimesRef -> IO (Times, UTCTime)
forall a. IORef a -> IO a
readIORef TimesRef
tref
(Times
t1, [(String, Float)]
mis, Pid
len) <- IO (Times, [(String, Float)], Pid)
timeMemInfos
UTCTime
c1 <- IO UTCTime
getCurrentTime
let scx :: Float
scx = NominalDiffTime -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac (UTCTime -> UTCTime -> NominalDiffTime
diffUTCTime UTCTime
c1 UTCTime
c0) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
scale
!scx' :: Float
scx' = if Float
scx Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
> Float
0 then Float
scx else Float
scale
nts :: [(String, Float)]
nts = (TimeEntry -> (String, Float)) -> Times -> [(String, Float)]
forall a b. (a -> b) -> [a] -> [b]
map (\(Pid
_, (String
nm, Float
t)) -> (String
nm, Float -> Float -> Float
forall a. Ord a => a -> a -> a
min Float
100 (Float
t Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
scx'))) (Times -> Times -> Times
combine Times
t0 Times
t1)
!t1' :: Times
t1' = Pid -> Times -> Times
forall a. Pid -> [a] -> [a]
take' (Times -> Pid
forall (t :: * -> *) a. Foldable t => t a -> Pid
length Times
t1) Times
t1
!nts' :: [(String, Float)]
nts' = Pid -> [(String, Float)] -> [(String, Float)]
forall a. Pid -> [a] -> [a]
take' Pid
maxEntries ([(String, Float)] -> [(String, Float)]
sortTop [(String, Float)]
nts)
!mis' :: [(String, Float)]
mis' = Pid -> [(String, Float)] -> [(String, Float)]
forall a. Pid -> [a] -> [a]
take' Pid
maxEntries ([(String, Float)] -> [(String, Float)]
sortTop [(String, Float)]
mis)
TimesRef -> (Times, UTCTime) -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef TimesRef
tref (Times
t1', UTCTime
c1)
(Pid, [(String, Float)], [(String, Float)])
-> IO (Pid, [(String, Float)], [(String, Float)])
forall (m :: * -> *) a. Monad m => a -> m a
return (Pid
len, [(String, Float)]
nts', [(String, Float)]
mis')
showTimeInfo :: TimeInfo -> Monitor [String]
showTimeInfo :: (String, Float) -> Monitor [String]
showTimeInfo (String
n, Float
t) =
Selector Pid -> Monitor Pid
forall a. Selector a -> Monitor a
getConfigValue Selector Pid
decDigits Monitor Pid -> (Pid -> Monitor [String]) -> Monitor [String]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Pid
d -> String -> String -> Float -> Monitor [String]
showInfo String
n (Pid -> Float -> String
forall a. RealFloat a => Pid -> a -> String
showDigits Pid
d Float
t) Float
t
showTimeInfos :: [TimeInfo] -> Monitor [[String]]
showTimeInfos :: [(String, Float)] -> Monitor [[String]]
showTimeInfos = ((String, Float) -> Monitor [String])
-> [(String, Float)] -> Monitor [[String]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (String, Float) -> Monitor [String]
showTimeInfo
runTop :: TimesRef -> Float -> [String] -> Monitor String
runTop :: TimesRef -> Float -> [String] -> Monitor String
runTop TimesRef
tref Float
scale [String]
_ = do
(Pid
no, [(String, Float)]
ps, [(String, Float)]
ms) <- IO (Pid, [(String, Float)], [(String, Float)])
-> Monitor (Pid, [(String, Float)], [(String, Float)])
forall a. IO a -> Monitor a
io (IO (Pid, [(String, Float)], [(String, Float)])
-> Monitor (Pid, [(String, Float)], [(String, Float)]))
-> IO (Pid, [(String, Float)], [(String, Float)])
-> Monitor (Pid, [(String, Float)], [(String, Float)])
forall a b. (a -> b) -> a -> b
$ TimesRef -> Float -> IO (Pid, [(String, Float)], [(String, Float)])
topProcesses TimesRef
tref Float
scale
[[String]]
pstr <- [(String, Float)] -> Monitor [[String]]
showTimeInfos [(String, Float)]
ps
[[String]]
mstr <- [(String, Float)] -> Monitor [[String]]
showMemInfos [(String, Float)]
ms
[String] -> Monitor String
parseTemplate ([String] -> Monitor String) -> [String] -> Monitor String
forall a b. (a -> b) -> a -> b
$ Pid -> String
forall a. Show a => a -> String
show Pid
no String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [[String]] -> [String]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (([String] -> [String] -> [String])
-> [[String]] -> [[String]] -> [[String]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
(++) [[String]]
pstr [[String]]
mstr) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ String -> [String]
forall a. a -> [a]
repeat String
"N/A"
startTop :: [String] -> Int -> (String -> IO ()) -> IO ()
startTop :: [String] -> Pid -> (String -> IO ()) -> IO ()
startTop [String]
a Pid
r String -> IO ()
cb = do
Integer
cr <- SysVar -> IO Integer
getSysVar SysVar
ClockTick
UTCTime
c <- IO UTCTime
getCurrentTime
TimesRef
tref <- (Times, UTCTime) -> IO TimesRef
forall a. a -> IO (IORef a)
newIORef ([], UTCTime
c)
let scale :: Float
scale = Integer -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
cr Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
100
(Pid, [(String, Float)], [(String, Float)])
_ <- TimesRef -> Float -> IO (Pid, [(String, Float)], [(String, Float)])
topProcesses TimesRef
tref Float
scale
[String]
-> IO MConfig
-> ([String] -> Monitor String)
-> Pid
-> (String -> IO ())
-> IO ()
runM [String]
a IO MConfig
topConfig (TimesRef -> Float -> [String] -> Monitor String
runTop TimesRef
tref Float
scale) Pid
r String -> IO ()
cb