ENH make processor and other low level functions more functional
This commit is contained in:
parent
e5f5e54eec
commit
75359e281f
|
@ -85,22 +85,19 @@ return function(update_freq, config, main_state, common, width, point)
|
|||
cores[c] = create_core(dial_x, dial_y)
|
||||
end
|
||||
local coretemp_paths = cpu.get_coretemp_paths()
|
||||
local update_coretemps
|
||||
if coretemp_paths ~= nil then
|
||||
update_coretemps = function()
|
||||
for conky_core_id, path in pairs(coretemp_paths) do
|
||||
if #coretemp_paths ~= ncores then
|
||||
i_o.warnf('could not find all coretemp paths')
|
||||
end
|
||||
local update_coretemps = function()
|
||||
for conky_core_idx, path in pairs(coretemp_paths) do
|
||||
local temp = __math_floor(0.001 * i_o.read_file(path, nil, '*n'))
|
||||
common.text_circle_set(cores[conky_core_id].coretemp, temp)
|
||||
common.text_circle_set(cores[conky_core_idx].coretemp, temp)
|
||||
end
|
||||
end
|
||||
else
|
||||
i_o.warnf('could not find coretemp paths; disabling temp readings')
|
||||
update_coretemps = function() end
|
||||
end
|
||||
local update = function()
|
||||
for _, load_data in pairs(mod_state) do
|
||||
compound_dial.set(
|
||||
cores[load_data.conky_core_id].loads,
|
||||
cores[load_data.conky_core_idx].loads,
|
||||
load_data.conky_thread_id,
|
||||
load_data.percent_active * 100
|
||||
)
|
||||
|
|
29
src/pure.lua
29
src/pure.lua
|
@ -2,7 +2,6 @@ local M = {}
|
|||
|
||||
local err = require 'err'
|
||||
|
||||
local __string_gmatch = string.gmatch
|
||||
local __math_floor = math.floor
|
||||
local __table_insert = table.insert
|
||||
|
||||
|
@ -118,6 +117,14 @@ M.rep = function(n, x)
|
|||
return r
|
||||
end
|
||||
|
||||
M.array_to_map = function(arr)
|
||||
local r = {}
|
||||
for i = 1, #arr do
|
||||
r[arr[i][1]] = arr[i][2]
|
||||
end
|
||||
return r
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- random list things
|
||||
|
||||
|
@ -177,10 +184,20 @@ M.table_array = function(tbl)
|
|||
return r
|
||||
end
|
||||
|
||||
M.gmatch_table = function(pat, s)
|
||||
M.iter_to_table1 = function(iter)
|
||||
local r = {}
|
||||
for m in __string_gmatch(s, pat) do
|
||||
__table_insert(r, m)
|
||||
for next in iter do
|
||||
__table_insert(r, next)
|
||||
end
|
||||
return r
|
||||
end
|
||||
|
||||
M.iter_to_tableN = function(iter)
|
||||
local r = {}
|
||||
local next = {iter()}
|
||||
while #next > 0 do
|
||||
__table_insert(r, next)
|
||||
next = {iter()}
|
||||
end
|
||||
return r
|
||||
end
|
||||
|
@ -262,6 +279,10 @@ M.maybe = function(def, f, x)
|
|||
end
|
||||
end
|
||||
|
||||
M.fmap_maybe = function(f, x)
|
||||
return M.maybe(nil, f, x)
|
||||
end
|
||||
|
||||
-- round to whole numbers since I don't need more granularity and extra values
|
||||
-- will lead to cache misses
|
||||
M.round_percent = __math_floor
|
||||
|
|
109
src/sys.lua
109
src/sys.lua
|
@ -16,6 +16,14 @@ local read_micro = function(path)
|
|||
return i_o.read_file(path, nil, '*n') * 0.000001
|
||||
end
|
||||
|
||||
local gmatch_to_table1 = function(pat, s)
|
||||
return pure.iter_to_table1(__string_gmatch(s, pat))
|
||||
end
|
||||
|
||||
local gmatch_to_tableN = function(pat, s)
|
||||
return pure.iter_to_tableN(__string_gmatch(s, pat))
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- memory
|
||||
|
||||
|
@ -155,9 +163,8 @@ local NET_DIR = '/sys/class/net'
|
|||
|
||||
local get_interfaces = function()
|
||||
local cmd = string.format('realpath %s/* | grep -v virtual', NET_DIR)
|
||||
local s = i_o.execute_cmd(cmd)
|
||||
local f = pure.partial(pure.gmatch_table, '/([^/\n]+)\n')
|
||||
return pure.maybe({}, f, s)
|
||||
local f = pure.partial(gmatch_to_table1, '/([^/\n]+)\n')
|
||||
return pure.maybe({}, f, i_o.execute_cmd(cmd))
|
||||
end
|
||||
|
||||
M.get_net_interface_paths = function()
|
||||
|
@ -187,62 +194,74 @@ end
|
|||
local get_coretemp_dir = function()
|
||||
i_o.assert_exe_exists('grep')
|
||||
local s = i_o.execute_cmd('grep -l \'^coretemp$\' /sys/class/hwmon/*/name')
|
||||
if s == nil then return else return dirname(s) end
|
||||
return pure.fmap_maybe(dirname, s)
|
||||
end
|
||||
|
||||
-- map cores to integer values starting at 1; this is necessary since some cpus
|
||||
-- don't report their core id's as a sequence of integers starting at 0
|
||||
local get_core_id_mapper = function()
|
||||
local s = i_o.execute_cmd('lscpu -p=CORE | tail -n+5 | sort | uniq')
|
||||
local m = {}
|
||||
local i = 1
|
||||
for core_id in string.gmatch(s, '(%d+)') do
|
||||
m[tonumber(core_id)] = i
|
||||
i = i + 1
|
||||
end
|
||||
return m
|
||||
local get_core_id_indexer = function()
|
||||
local make_indexer = pure.compose(
|
||||
pure.array_to_map,
|
||||
pure.partial(pure.imap, function(i, c) return {tonumber(c), i} end),
|
||||
pure.partial(gmatch_to_table1, '(%d+)')
|
||||
)
|
||||
return pure.fmap_maybe(
|
||||
make_indexer,
|
||||
i_o.execute_cmd('lscpu -p=CORE | tail -n+5 | sort | uniq')
|
||||
)
|
||||
end
|
||||
|
||||
local get_core_mappings = function()
|
||||
local ncpus = M.get_cpu_number()
|
||||
local ncores = M.get_core_number()
|
||||
local nthreads = ncpus / ncores
|
||||
local core_id_mapper = get_core_id_mapper()
|
||||
local conky_thread_ids = pure.rep(ncores, nthreads)
|
||||
local core_mappings = {}
|
||||
local s = i_o.execute_cmd('lscpu -p=cpu,CORE | tail -n+5')
|
||||
for cpu_id, core_id in string.gmatch(s, '(%d+),(%d+)') do
|
||||
local conky_core_id = core_id_mapper[tonumber(core_id)]
|
||||
local conky_cpu_id = tonumber(cpu_id) + 1
|
||||
core_mappings[conky_cpu_id] = {
|
||||
conky_core_id = conky_core_id,
|
||||
conky_thread_id = conky_thread_ids[conky_core_id],
|
||||
local map_ids = function(indexer)
|
||||
local f = function(acc, next)
|
||||
local cpu_id = tonumber(next[1]) + 1
|
||||
local core_id = next[2]
|
||||
local conky_core_idx = indexer[tonumber(core_id)]
|
||||
acc.mappings[cpu_id] = {
|
||||
conky_core_idx = conky_core_idx,
|
||||
conky_thread_id = acc.thread_ids[conky_core_idx],
|
||||
}
|
||||
conky_thread_ids[conky_core_id] = conky_thread_ids[conky_core_id] - 1
|
||||
acc.thread_ids[conky_core_idx] = acc.thread_ids[conky_core_idx] - 1
|
||||
return acc
|
||||
end
|
||||
return core_mappings
|
||||
local cpu_to_core_map = pure.maybe(
|
||||
{},
|
||||
pure.partial(gmatch_to_tableN, '(%d+),(%d+)'),
|
||||
i_o.execute_cmd('lscpu -p=cpu,CORE | tail -n+5')
|
||||
)
|
||||
local init = {mappings = {}, thread_ids = pure.rep(ncores, nthreads)}
|
||||
return pure.reduce(f, init, cpu_to_core_map).mappings
|
||||
end
|
||||
return pure.fmap_maybe(map_ids, get_core_id_indexer())
|
||||
end
|
||||
|
||||
M.get_coretemp_paths = function()
|
||||
local get_paths = function(indexer)
|
||||
local d = get_coretemp_dir()
|
||||
if d == nil then return end
|
||||
local get_labels = function(dir)
|
||||
i_o.assert_exe_exists('grep')
|
||||
local s = i_o.execute_cmd(string.format('grep Core %s/temp*_label', d))
|
||||
local ps = {}
|
||||
local core_id_mapper = get_core_id_mapper()
|
||||
for temp_name, core_id in string.gmatch(s, '/([^/\n]+)_label:Core (%d+)\n') do
|
||||
ps[core_id_mapper[tonumber(core_id)]] = string.format('%s/%s_input', d, temp_name)
|
||||
return i_o.execute_cmd(string.format('grep Core %s/temp*_label', dir))
|
||||
end
|
||||
return ps
|
||||
local to_tuple = function(m)
|
||||
return {
|
||||
indexer[tonumber(m[2])],
|
||||
string.format('%s/%s_input', d, m[1])
|
||||
}
|
||||
end
|
||||
local f = pure.compose(
|
||||
pure.array_to_map,
|
||||
pure.partial(pure.map, to_tuple),
|
||||
pure.partial(gmatch_to_tableN, '/([^/\n]+)_label:Core (%d+)\n')
|
||||
)
|
||||
return pure.maybe({}, f, pure.fmap_maybe(get_labels, d))
|
||||
end
|
||||
return pure.maybe({}, get_paths, get_core_id_indexer())
|
||||
end
|
||||
|
||||
M.read_freq = function()
|
||||
-- NOTE: Using the builtin conky functions for getting cpu freq seems to make
|
||||
-- the entire loop jittery due to high variance latency. Querying
|
||||
-- scaling_cur_freq in sysfs seems to do the same thing. It appears lscpu
|
||||
-- (which queries /proc/cpuinfo) is much faster and doesn't have this jittery
|
||||
-- problem.
|
||||
local c = i_o.execute_cmd('lscpu -p=MHZ')
|
||||
local match_freq = function(c)
|
||||
local f = 0
|
||||
local n = 0
|
||||
for s in __string_gmatch(c, '(%d+%.%d+)') do
|
||||
|
@ -252,7 +271,17 @@ M.read_freq = function()
|
|||
return __string_format('%.0f Mhz', f / n)
|
||||
end
|
||||
|
||||
M.read_freq = function()
|
||||
-- NOTE: Using the builtin conky functions for getting cpu freq seems to make
|
||||
-- the entire loop jittery due to high variance latency. Querying
|
||||
-- scaling_cur_freq in sysfs seems to do the same thing. It appears lscpu
|
||||
-- (which queries /proc/cpuinfo) is much faster and doesn't have this jittery
|
||||
-- problem.
|
||||
return pure.maybe('N/A', match_freq, i_o.execute_cmd('lscpu -p=MHZ'))
|
||||
end
|
||||
|
||||
M.get_hwp_paths = function()
|
||||
-- ASSUME this will never fail
|
||||
return pure.map_n(
|
||||
function(i)
|
||||
return '/sys/devices/system/cpu/cpu'
|
||||
|
@ -301,7 +330,7 @@ M.init_cpu_loads = function()
|
|||
active_prev = 0,
|
||||
total_prev = 0,
|
||||
percent_active = 0,
|
||||
conky_core_id = core.conky_core_id,
|
||||
conky_core_idx = core.conky_core_idx,
|
||||
conky_thread_id = core.conky_thread_id,
|
||||
}
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue