From 93651960735b66ea7e54115d2fd9617aa125c11a Mon Sep 17 00:00:00 2001 From: ndwarshuis Date: Sat, 16 Jul 2022 23:48:01 -0400 Subject: [PATCH] ENH pass single config table to all modules --- core | 2 +- drawing/common.lua | 37 ++++++++++++++++++---- drawing/filesystem.lua | 20 +++++++----- drawing/graphics.lua | 38 +++++++++++++++------- drawing/memory.lua | 13 +++++--- drawing/network.lua | 4 +-- drawing/pacman.lua | 2 +- drawing/power.lua | 59 ++++++++++++++++------------------- drawing/processor.lua | 71 +++++++++++++++++++----------------------- drawing/readwrite.lua | 8 ++--- drawing/system.lua | 2 +- main.lua | 71 +++++++++++++++++++++++++++++------------- 12 files changed, 196 insertions(+), 131 deletions(-) diff --git a/core b/core index becc24a..ed4fc4e 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit becc24a2c79a582e10db348be435b18f9aba310f +Subproject commit ed4fc4ec0304caff96163017ee9a2ae419358a50 diff --git a/drawing/common.lua b/drawing/common.lua index 4fac77a..12364b6 100644 --- a/drawing/common.lua +++ b/drawing/common.lua @@ -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)) diff --git a/drawing/filesystem.lua b/drawing/filesystem.lua index 6cc0924..72dee0e 100644 --- a/drawing/filesystem.lua +++ b/drawing/filesystem.lua @@ -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 diff --git a/drawing/graphics.lua b/drawing/graphics.lua index 22abc6a..70dd69f 100644 --- a/drawing/graphics.lua +++ b/drawing/graphics.lua @@ -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 diff --git a/drawing/memory.lua b/drawing/memory.lua index 9a3a1d0..07d08c6 100644 --- a/drawing/memory.lua +++ b/drawing/memory.lua @@ -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) diff --git a/drawing/network.lua b/drawing/network.lua index b723872..8f94f32 100644 --- a/drawing/network.lua +++ b/drawing/network.lua @@ -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}, } ) diff --git a/drawing/pacman.lua b/drawing/pacman.lua index 976ca5e..e7a7b12 100644 --- a/drawing/pacman.lua +++ b/drawing/pacman.lua @@ -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 diff --git a/drawing/power.lua b/drawing/power.lua index 25f71e6..9cb0864 100644 --- a/drawing/power.lua +++ b/drawing/power.lua @@ -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 diff --git a/drawing/processor.lua b/drawing/processor.lua index 7cca779..e6667d7 100644 --- a/drawing/processor.lua +++ b/drawing/processor.lua @@ -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 diff --git a/drawing/readwrite.lua b/drawing/readwrite.lua index d950e26..591e9f4 100644 --- a/drawing/readwrite.lua +++ b/drawing/readwrite.lua @@ -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}, } ) diff --git a/drawing/system.lua b/drawing/system.lua index bba3d05..36d0777 100644 --- a/drawing/system.lua +++ b/drawing/system.lua @@ -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 diff --git a/main.lua b/main.lua index d8a2ca0..213a4e8 100644 --- a/main.lua +++ b/main.lua @@ -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()