1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
-----------------------------------------------------------------------------
-- |
-- Module : Plugins.Monitors.Swap.FreeBSD
-- Copyright : (c) Andrea Rossato
-- License : BSD-style (see LICENSE)
--
-- Maintainer : Jose A. Ortega Ruiz <jao@gnu.org>
-- Stability : unstable
-- Portability : unportable
--
-- A swap usage monitor for Xmobar
--
-----------------------------------------------------------------------------
module Xmobar.Plugins.Monitors.Swap.FreeBSD (parseMEM) where
import System.BSD.Sysctl (sysctlReadUInt)
import Foreign
import Foreign.C.Types
import Foreign.C.String
#include <unistd.h>
#include <fcntl.h>
#include <kvm.h>
#include <limits.h>
#include <paths.h>
#include <stdlib.h>
foreign import ccall unsafe "kvm.h kvm_open" c_kvm_open :: CString -> CString -> CString -> CInt -> CString -> IO (Ptr KVM_T)
foreign import ccall "&kvm_close" c_kvm_close :: FinalizerPtr KVM_T
foreign import ccall unsafe "kvm.h kvm_getswapinfo" c_kvm_getswapinfo :: Ptr KVM_T -> Ptr KVM_SWAP -> CInt -> CInt -> IO CInt
data KVM_T
data KvmT = KvmT !(ForeignPtr KVM_T)
deriving (Eq, Ord, Show)
data KVM_SWAP
data KvmSwap = KvmSwap !(ForeignPtr KVM_SWAP)
deriving (Eq, Ord, Show)
getKvmT:: IO KvmT
getKvmT = do
withCString "/dev/null" $ \dir -> do
kvm_t_ptr <- c_kvm_open nullPtr dir nullPtr #{const O_RDONLY} nullPtr
ptr <- newForeignPtr c_kvm_close kvm_t_ptr
return $ KvmT ptr
getSwapData :: KvmT -> IO SwapData
getSwapData (KvmT kvm_t_fp) = do
withForeignPtr kvm_t_fp $ \kvm_t_ptr -> do
allocaBytes #{size struct kvm_swap} $ \swap_ptr -> do
c_kvm_getswapinfo kvm_t_ptr swap_ptr 1 0
peek $ castPtr swap_ptr :: IO SwapData
data SwapData = AvailableSwapData {
used :: Integer
, total :: Integer
} | NotAvailableSwapData
deriving (Show, Read, Eq)
instance Storable SwapData where
alignment _ = #{alignment struct kvm_swap}
sizeOf _ = #{size struct kvm_swap}
peek ptr = do
cused <- #{peek struct kvm_swap, ksw_used} ptr :: IO CUInt
ctotal <- #{peek struct kvm_swap, ksw_total} ptr :: IO CUInt
return $ AvailableSwapData {used = toInteger cused, total = toInteger ctotal}
poke _ _ = pure ()
isEnabled :: IO Bool
isEnabled = do
enabled <- sysctlReadUInt "vm.swap_enabled"
return $ enabled == 1
parseMEM' :: Bool -> IO [Float]
parseMEM' False = return []
parseMEM' True = do
kvm_t <- getKvmT
swap <- getSwapData kvm_t
pagesize <- toInteger <$> sysctlReadUInt "vm.stats.vm.v_page_size"
let
swapTotal = total swap
swapUsed = used swap
tot = swapTotal * pagesize
fr = tot - swapUsed * pagesize
return $ res (fromInteger tot) (fromInteger fr)
where
res :: Float -> Float -> [Float]
res _ 0 = []
res t f = [(t-f)/t, t, t - f, f]
parseMEM :: IO [Float]
parseMEM = do
enabled <- isEnabled
parseMEM' enabled
|