ENH pass single config table to all modules

This commit is contained in:
Nathan Dwarshuis 2022-07-16 23:48:01 -04:00
parent f1438af7ce
commit 9365196073
12 changed files with 196 additions and 131 deletions

2
core

@ -1 +1 @@
Subproject commit becc24a2c79a582e10db348be435b18f9aba310f
Subproject commit ed4fc4ec0304caff96163017ee9a2ae419358a50

View File

@ -669,7 +669,27 @@ local non_false = function(xs)
return pure.filter(function(x) return x ~= false end, xs)
end
M.reduce_blocks_inner = function(f, header, point, width, blocks)
local active_blocks = function(blockspecs)
local bs = pure.filter(function(b) return b[2] end, blockspecs)
return pure.map(function(b) return M.mk_block(table.unpack(b)) end, bs)
end
local flatten_sections = function(top, ...)
local f = function(acc, new)
if #new.blocks == 0 then
return acc
elseif #acc == 0 then
return new.blocks
else
return pure.flatten(
{acc, {M.mk_block(new.sep_fun, true, new.top)}, new.blocks}
)
end
end
return pure.reduce(f, active_blocks(top), {...})
end
M.reduce_blocks_ = function(header, point, width, top_blocks, ...)
local mk_header = function(y)
local obj = M.make_header(point.x, y, width, header)
return M.mk_acc_static(
@ -678,6 +698,7 @@ M.reduce_blocks_inner = function(f, header, point, width, blocks)
function(cr) M.draw_header(cr, obj) end
)
end
local blocks = flatten_sections(top_blocks, ...)
local r = pure.reduce(
_combine_blocks,
{w = 0, next_y = point.y, final_y = point.y, objs = {}},
@ -687,16 +708,12 @@ M.reduce_blocks_inner = function(f, header, point, width, blocks)
return {
next_x = point.x + r.w,
next_y = r.final_y,
update = f(table.unpack(non_false(pure.reverse(us)))),
update = pure.sequence(table.unpack(non_false(us))),
static = pure.sequence(table.unpack(ss)),
dynamic = pure.sequence(table.unpack(non_false(ds)))
}
end
M.reduce_blocks = pure.partial(M.reduce_blocks_inner, pure.compose)
M.reduce_blocks_ = pure.partial(M.reduce_blocks_inner, pure.sequence)
M.mk_acc = function(w, h, u, s, d)
return {w = w, h = h, obj = {u, s, d}}
end
@ -709,6 +726,14 @@ M.mk_block = function(f, active, offset)
return {f = f, active = active, offset = offset}
end
M.mk_section = function(top, sep_fun, ...)
return {
top = top,
sep_fun = sep_fun,
blocks = active_blocks({...})
}
end
M.mk_seperator = function(width, x, y)
local separator = M.make_separator(x, y, width)
return M.mk_acc_static(width, 0, pure.partial(line.draw, separator))

View File

@ -4,7 +4,11 @@ local geometry = require 'geometry'
local pure = require 'pure'
local impure = require 'impure'
return function(pathspecs, main_state, point)
-- ASSUME pathspecs will be at least 1 long
return function(config, main_state, point)
-- local config = {
-- show_smart = true
-- }
local SPACING = 20
local BAR_PAD = 100
local SEPARATOR_SPACING = 20
@ -44,7 +48,7 @@ return function(pathspecs, main_state, point)
-- filesystem bar chart
local mk_bars = function(y)
local paths, names = table.unpack(pure.unzip(pathspecs))
local paths, names = table.unpack(pure.unzip(config.fs_paths))
local CONKY_CMDS = pure.map(
pure.partial(string.format, '${fs_used_perc %s}', true),
paths
@ -69,7 +73,7 @@ return function(pathspecs, main_state, point)
end
return common.mk_acc(
geometry.SECTION_WIDTH,
(#pathspecs - 1) * SPACING,
(#config.fs_paths - 1) * SPACING,
update,
pure.partial(common.compound_bar_draw_static, obj),
pure.partial(common.compound_bar_draw_dynamic, obj)
@ -83,10 +87,10 @@ return function(pathspecs, main_state, point)
'FILE SYSTEMS',
point,
geometry.SECTION_WIDTH,
{
common.mk_block(mk_smart, true, SEPARATOR_SPACING),
common.mk_block(mk_sep, true, SEPARATOR_SPACING),
common.mk_block(mk_bars, true, 0),
}
{{mk_smart, config.show_smart, SEPARATOR_SPACING}},
common.mk_section(SEPARATOR_SPACING, mk_sep, {mk_bars, true, 0})
-- common.mk_block(mk_sep, config.show_smart, SEPARATOR_SPACING),
-- common.mk_block(mk_bars, true, 0),
-- }
)
end

View File

@ -3,7 +3,14 @@ local i_o = require 'i_o'
local common = require 'common'
local geometry = require 'geometry'
return function(update_freq, point)
return function(update_freq, config, point)
-- local config = {
-- show_temp = true,
-- show_clock = true,
-- show_gpu_util = true,
-- show_mem_util = true,
-- show_vid_util = true
-- }
local SEPARATOR_SPACING = 20
local TEXT_SPACING = 20
local PLOT_SEC_BREAK = 20
@ -221,17 +228,24 @@ return function(update_freq, point)
'NVIDIA GRAPHICS',
point,
geometry.SECTION_WIDTH,
{
common.mk_block(mk_status, true, SEPARATOR_SPACING),
common.mk_block(mk_sep, true, TEXT_SPACING),
common.mk_block(mk_temp, true, SEPARATOR_SPACING),
common.mk_block(mk_sep, true, SEPARATOR_SPACING),
common.mk_block(mk_clock, true, SEPARATOR_SPACING),
common.mk_block(mk_sep, true, PLOT_SEC_BREAK),
common.mk_block(mk_gpu_util, true, PLOT_SEC_BREAK),
common.mk_block(mk_mem_util, true, PLOT_SEC_BREAK),
common.mk_block(mk_vid_util, true, 0)
}
{{mk_status, true, SEPARATOR_SPACING}},
common.mk_section(
SEPARATOR_SPACING,
mk_sep,
{mk_temp, config.show_temp, SEPARATOR_SPACING}
),
common.mk_section(
SEPARATOR_SPACING,
mk_sep,
{mk_clock, config.show_clock, SEPARATOR_SPACING}
),
common.mk_section(
SEPARATOR_SPACING,
mk_sep,
{mk_gpu_util, config.show_gpu_util, PLOT_SEC_BREAK},
{mk_mem_util, config.show_mem_util, PLOT_SEC_BREAK},
{mk_vid_util, config.show_vid_util, 0}
)
)
return pure.map_at("update", function(f) return function(_) f(update_state()) end end, rbs)
end

View File

@ -5,7 +5,12 @@ local common = require 'common'
local geometry = require 'geometry'
local pure = require 'pure'
return function(update_freq, point)
return function(update_freq, config, point)
-- local config = {
-- show_stats = true,
-- show_plot = true,
-- show_table = true,
-- }
local DIAL_THICKNESS = 8
local DIAL_RADIUS = 32
local DIAL_SPACING = 40
@ -185,9 +190,9 @@ return function(update_freq, point)
point,
geometry.SECTION_WIDTH,
{
common.mk_block(mk_stats, true, PLOT_SECTION_BREAK),
common.mk_block(mk_plot, true, TABLE_SECTION_BREAK),
common.mk_block(mk_tbl, true, 0),
{mk_stats, config.show_stats, PLOT_SECTION_BREAK},
{mk_plot, config.show_plot, TABLE_SECTION_BREAK},
{mk_tbl, config.show_table, 0},
}
)
return pure.map_at("update", function(f) return function(_) f(read_state()) end end, rbs)

View File

@ -72,8 +72,8 @@ return function(update_freq, point)
point,
geometry.SECTION_WIDTH,
{
common.mk_block(mk_rx, true, 0),
common.mk_block(mk_tx, true, PLOT_SEC_BREAK),
{mk_rx, true, PLOT_SEC_BREAK},
{mk_tx, true, 0},
}
)

View File

@ -46,6 +46,6 @@ return function(main_state, point)
'PACMAN',
point,
geometry.SECTION_WIDTH,
{common.mk_block(mk_stats, true, 0)}
{{mk_stats, true, 0}}
)
end

View File

@ -4,22 +4,10 @@ local common = require 'common'
local geometry = require 'geometry'
local sys = require 'sys'
return function(update_freq, battery, main_state, point)
return function(update_freq, config, point)
local TEXT_SPACING = 20
local PLOT_SEC_BREAK = 20
local PLOT_HEIGHT = 56
local read_pkg0_joules = sys.intel_powercap_reader('intel-rapl:0')
local read_dram_joules = sys.intel_powercap_reader('intel-rapl:0:2')
local _read_battery_power = sys.battery_power_reader(battery)
local read_battery_power = function(is_using_ac)
if is_using_ac then
return 0
else
return _read_battery_power()
end
end
local power_label_function = function(plot_max)
local fmt = common.y_label_format_string(plot_max, 'W')
@ -38,7 +26,8 @@ return function(update_freq, battery, main_state, point)
return pure.partial(common.tagged_scaled_timeseries_draw_dynamic, obj)
end
local mk_rate_plot = function(label, read, y)
local mk_rate_plot = function(label, address, y)
local read_joules = sys.intel_powercap_reader(address)
local obj = common.make_rate_timeseries(
point.x,
y,
@ -50,30 +39,35 @@ return function(update_freq, battery, main_state, point)
label,
0,
update_freq,
read()
read_joules()
)
return common.mk_acc(
geometry.SECTION_WIDTH,
PLOT_HEIGHT + PLOT_SEC_BREAK,
function(_) common.update_rate_timeseries(obj, read()) end,
function(_) common.update_rate_timeseries(obj, read_joules()) end,
mk_static(obj),
mk_dynamic(obj)
)
end
-----------------------------------------------------------------------------
-- package 0 power plot
local mk_pkg0 = pure.partial(mk_rate_plot, 'PKG0', read_pkg0_joules)
-----------------------------------------------------------------------------
-- DRAM power plot
local mk_dram = pure.partial(mk_rate_plot, 'DRAM', read_dram_joules)
local mk_rate_blockspec = function(spec)
local f = pure.partial(mk_rate_plot, table.unpack(spec))
return {f, true, TEXT_SPACING}
end
-----------------------------------------------------------------------------
-- battery power plot
local _read_battery_power = sys.battery_power_reader(config.battery)
local read_battery_power = function(is_using_ac)
if is_using_ac then
return 0
else
return _read_battery_power()
end
end
local format_ac = function(watts)
if watts == 0 then
return "A/C"
@ -83,6 +77,7 @@ return function(update_freq, battery, main_state, point)
end
local mk_bat = function(y)
local read_bat_status = sys.battery_status_reader(config.battery)
local obj = common.make_tagged_scaled_timeseries(
point.x,
y,
@ -101,8 +96,8 @@ return function(update_freq, battery, main_state, point)
function()
common.tagged_scaled_timeseries_set(
obj,
read_battery_power(main_state.is_using_ac
))
read_battery_power(read_bat_status())
)
end,
mk_static(obj),
mk_dynamic(obj)
@ -116,10 +111,10 @@ return function(update_freq, battery, main_state, point)
'POWER',
point,
geometry.SECTION_WIDTH,
{
common.mk_block(mk_pkg0, true, TEXT_SPACING),
common.mk_block(mk_dram, true, TEXT_SPACING),
common.mk_block(mk_bat, true, 0),
}
pure.concat(
pure.map(mk_rate_blockspec, config.rapl_specs),
-- TODO what happens if this is nil?
{{mk_bat, config.battery ~= nil, 0}}
)
)
end

View File

@ -8,11 +8,7 @@ local pure = require 'pure'
local __math_floor = math.floor
return function(update_freq, main_state, point)
-- local SHOW_DIALS = true
-- local SHOW_TIMESERIES = true
-- local SHOW_TABLE = true
return function(update_freq, config, main_state, point)
local DIAL_INNER_RADIUS = 30
local DIAL_OUTER_RADIUS = 42
local DIAL_THICKNESS = 5.5
@ -24,18 +20,17 @@ return function(update_freq, main_state, point)
local TABLE_HEIGHT = 114
-----------------------------------------------------------------------------
-- cores (loads and temps)
-- processor state
-- this totally is not supposed to be a state monad (ssssh...)
local update_state = function(cpu_loads)
return {
cpu_loads = cpu.read_cpu_loads(cpu_loads),
load_sum = 0,
trigger = main_state.trigger10
}
local mod_state = cpu.read_cpu_loads(cpu.init_cpu_loads())
local update_state = function()
mod_state = cpu.read_cpu_loads(mod_state)
end
local state = update_state(cpu.init_cpu_loads())
-----------------------------------------------------------------------------
-- cores (loads and temps)
local ncpus = cpu.get_cpu_number()
local ncores = cpu.get_core_number()
local nthreads = ncpus / ncores
@ -72,23 +67,18 @@ return function(update_freq, main_state, point)
local dial_y = y + DIAL_OUTER_RADIUS
cores[c] = create_core(dial_x, dial_y)
end
local update = function(state_)
local s = state_.load_sum
for _, load_data in pairs(state_.cpu_loads) do
local cur = load_data.percent_active
s = s + cur
local update = function()
for _, load_data in pairs(mod_state) do
compound_dial.set(
cores[load_data.conky_core_id].loads,
load_data.conky_thread_id,
cur * 100
load_data.percent_active * 100
)
end
for conky_core_id, 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)
end
state_.load_sum = s
return state_
end
local static = function(cr)
for i = 1, #cores do
@ -123,15 +113,14 @@ return function(update_freq, main_state, point)
TEXT_SPACING,
{'HWP Preference', 'Ave Freq'}
)
local update = function(state_)
local update = function()
-- For some reason this call is slow (querying anything with pstate in
-- general seems slow), but I also don't need to see an update every
-- cycle, hence the trigger
if state_.trigger == 0 then
if main_state.trigger10 == 0 then
common.text_rows_set(cpu_status, 1, cpu.read_hwp(hwp_paths))
end
common.text_rows_set(cpu_status, 2, cpu.read_freq())
return state_
end
local static = pure.partial(common.text_rows_draw_static, cpu_status)
local dynamic = pure.partial(common.text_rows_draw_dynamic, cpu_status)
@ -166,12 +155,12 @@ return function(update_freq, main_state, point)
"Total Load",
update_freq
)
local update = function(state_)
common.tagged_percent_timeseries_set(
total_load,
state_.load_sum / ncpus * 100
)
return state_
local update = function()
local s = 0
for i = 1, #mod_state do
s = s + mod_state[i].percent_active
end
common.tagged_percent_timeseries_set(total_load, s / ncpus * 100)
end
local static = pure.partial(common.tagged_percent_timeseries_draw_static, total_load)
local dynamic = pure.partial(common.tagged_percent_timeseries_draw_dynamic, total_load)
@ -226,24 +215,28 @@ return function(update_freq, main_state, point)
-----------------------------------------------------------------------------
-- main functions
local rbs = common.reduce_blocks(
local rbs = common.reduce_blocks_(
'PROCESSOR',
point,
geometry.SECTION_WIDTH,
{
common.mk_block(mk_cores, true, TEXT_SPACING),
common.mk_block(mk_hwp_freq, true, SEPARATOR_SPACING),
common.mk_block(mk_sep, true, SEPARATOR_SPACING),
common.mk_block(mk_load_plot, true, TABLE_SECTION_BREAK),
common.mk_block(mk_tbl, true, 0)
}
{mk_cores, config.show_cores, TEXT_SPACING},
{mk_hwp_freq, config.show_stats, SEPARATOR_SPACING},
},
common.mk_section(
SEPARATOR_SPACING,
mk_sep,
{mk_load_plot, config.show_plot, TABLE_SECTION_BREAK},
{mk_tbl, config.show_table, 0}
)
)
return pure.map_at(
"update",
function(f)
return function()
f(update_state(state.cpu_loads))
update_state()
f()
end
end,
rbs

View File

@ -4,11 +4,11 @@ local common = require 'common'
local geometry = require 'geometry'
local sys = require 'sys'
return function(update_freq, devices, point)
return function(update_freq, config, point)
local PLOT_SEC_BREAK = 20
local PLOT_HEIGHT = 56
-- TODO currently this will find any block device
local DEVICE_PATHS = sys.get_disk_paths(devices)
local DEVICE_PATHS = sys.get_disk_paths(config.devices)
local state = {read = 0, write = 0}
state.read, state.write = sys.get_total_disk_io(DEVICE_PATHS)
@ -56,8 +56,8 @@ return function(update_freq, devices, point)
point,
geometry.SECTION_WIDTH,
{
common.mk_block(mk_reads, true, PLOT_SEC_BREAK),
common.mk_block(mk_writes, true, 0),
{mk_reads, true, PLOT_SEC_BREAK},
{mk_writes, true, 0},
}
)

View File

@ -45,6 +45,6 @@ return function(main_state, point)
'SYSTEM',
point,
geometry.SECTION_WIDTH,
{common.mk_block(mk_stats, true, 0)}
{{mk_stats, true, 0}}
)
end

View File

@ -37,30 +37,60 @@ function conky_start(update_interval)
conky_set_update_interval(update_interval)
local update_freq = 1 / update_interval
local devices = {'sda', 'nvme0n1'}
local battery = 'BAT0'
local fs_paths = {
{'/', 'root'},
{'/boot', 'boot'},
{'/home', 'home'},
{'/mnt/data', 'data'},
{'/mnt/dcache', 'dcache'},
{'/tmp', 'tmpfs'}
}
local main_state = {}
local mem = pure.partial(memory, update_freq)
local rw = pure.partial(readwrite, update_freq, devices)
local net = pure.partial(network, update_freq)
local pwr = pure.partial(power, update_freq, battery, main_state)
local fs = pure.partial(filesystem, fs_paths, main_state)
local stm = pure.partial(system, main_state)
local gfx = pure.partial(graphics, update_freq)
local proc = pure.partial(processor, update_freq, main_state)
local pcm = pure.partial(pacman, main_state)
local config = {
filesystem = {
show_smart = true,
fs_paths = {
{'/', 'root'},
{'/boot', 'boot'},
{'/home', 'home'},
{'/mnt/data', 'data'},
{'/mnt/dcache', 'dcache'},
{'/tmp', 'tmpfs'}
}
},
graphics = {
show_temp = true,
show_clock = true,
show_gpu_util = true,
show_mem_util = true,
show_vid_util = true
},
memory = {
show_stats = true,
show_plot = true,
show_table = true,
},
power = {
battery = 'BAT0',
rapl_specs = {
{'PKG0', 'intel-rapl:0'},
{'DRAM', 'intel-rapl:0:2'}
}
},
processor = {
show_cores = true,
show_stats = true,
show_plot = true,
show_table = true,
},
readwrite = {
devices = {'sda', 'nvme0n1'},
},
}
local using_ac = sys.battery_status_reader(battery)
local mem = pure.partial(memory, update_freq, config.memory)
local rw = pure.partial(readwrite, update_freq, config.readwrite)
local net = pure.partial(network, update_freq)
local pwr = pure.partial(power, update_freq, config.power)
local fs = pure.partial(filesystem, config.filesystem, main_state)
local stm = pure.partial(system, main_state)
local gfx = pure.partial(graphics, update_freq, config.graphics)
local proc = pure.partial(processor, update_freq, config.processor, main_state)
local pcm = pure.partial(pacman, main_state)
local compiled = static(
geom.make_point(12, 11),
@ -78,7 +108,6 @@ function conky_start(update_interval)
draw_dynamic = function(cr, _updates)
main_state.trigger10 = _updates % (update_freq * 10)
main_state.pacman_stats = i_o.read_file(STATS_FILE)
main_state.is_using_ac = using_ac()
compiled.static(cr)
compiled.update()