From cc806784e6da86774773e6b66095f938cbe452c6 Mon Sep 17 00:00:00 2001 From: ndwarshuis Date: Sat, 17 Jul 2021 21:22:17 -0400 Subject: [PATCH] ENH move cpu functions to cpu module --- core | 2 +- drawing/Processor.lua | 183 +++++++++++------------------------------- main.lua | 9 ++- 3 files changed, 53 insertions(+), 141 deletions(-) diff --git a/core b/core index d7b9066..a0ce1c0 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit d7b90666a7dd1ca0da49dfc85b7998ec4924d856 +Subproject commit a0ce1c015dce79db4bd30af68893fbcedc1d5cff diff --git a/drawing/Processor.lua b/drawing/Processor.lua index 45541e5..e017e14 100644 --- a/drawing/Processor.lua +++ b/drawing/Processor.lua @@ -4,28 +4,12 @@ local Table = require 'Table' local Util = require 'Util' local Common = require 'Common' local Geometry = require 'Geometry' +local CPU = require 'CPU' -local __string_match = string.match -local __string_gmatch = string.gmatch -local __string_format = string.format -local __tonumber = tonumber local __math_floor = math.floor -local CORETEMP_PATH = '/sys/devices/platform/coretemp.0/hwmon/hwmon%i/%s' - -local NUM_PHYSICAL_CORES = 4 -local NUM_THREADS_PER_CORE = 2 -local NCPU = NUM_THREADS_PER_CORE * NUM_PHYSICAL_CORES - local NUM_ROWS = 5 -local HWP_PATHS = {} - -for i = 1, NCPU do - HWP_PATHS[i] = '/sys/devices/system/cpu/cpu' .. (i - 1) .. - '/cpufreq/energy_performance_preference' -end - local TABLE_CONKY = {} for r = 1, NUM_ROWS do @@ -46,30 +30,24 @@ local _PLOT_HEIGHT_ = 56 local _TABLE_SECTION_BREAK_ = 20 local _TABLE_HEIGHT_ = 114 -local _create_core_ = function(cores, id, x, y) - local hwmon_index = -1 - while Util.read_file(string.format(CORETEMP_PATH, hwmon_index, 'name'), nil, '*l') ~= 'coretemp' do - hwmon_index = hwmon_index + 1 - end - - cores[id +1] = { - dials = Common.compound_dial( +local _create_core_ = function(x, y, nthreads) + return { + loads = Common.compound_dial( x, y, _DIAL_OUTER_RADIUS_, _DIAL_INNER_RADIUS_, _DIAL_THICKNESS_, 0.8, - NUM_THREADS_PER_CORE + nthreads ), - text_ring = Common.initTextRing( + coretemp = Common.initTextRing( x, y, _DIAL_INNER_RADIUS_ - 2, '%s°C', 90 - ), - coretemp_path = string.format(CORETEMP_PATH, hwmon_index, 'temp'..(id + 2)..'_input'), + ) } end @@ -80,15 +58,6 @@ local header = Common.Header( 'PROCESSOR' ) ---we assume that this cpu has 4 physical cores with 2 logical each -local cores = {} - -for c = 0, NUM_PHYSICAL_CORES - 1 do - local dial_x = Geometry.LEFT_X + _DIAL_OUTER_RADIUS_ + - (Geometry.SECTION_WIDTH - 2 * _DIAL_OUTER_RADIUS_) * c / 3 - local dial_y = header.bottom_y + _DIAL_OUTER_RADIUS_ - _create_core_(cores, c, dial_x, dial_y) -end local _HWP_Y_ = header.bottom_y + _DIAL_OUTER_RADIUS_ * 2 + _PLOT_SECTION_BREAK_ @@ -124,71 +93,11 @@ local tbl = Common.initTable( {'Name', 'PID', 'CPU (%)'} ) -local cpu_loads = {} -for i = 1, NCPU do - cpu_loads[i] = {active_prev = 0, active_total = 0} -end +-- local cpu_loads = {} +-- for i = 1, NCPU do +-- cpu_loads[i] = {active_prev = 0, active_total = 0} +-- end -local _read_cpu = function() - local i = NCPU - local iter = io.lines('/proc/stat') - iter() -- ignore first line - for ln in iter do - if i == 0 then break end - local user, system, idle = __string_match(ln, '(%d+) %d+ (%d+) (%d+)', 5) - local c = cpu_loads[i] - c.active_prev = c.active - c.total_prev = c.total - c.active = user + system - c.total = user + system + idle - i = i - 1 - end -end - -_read_cpu() -- prime once - -local _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 - -- /proc/cpuinfo is much faster and doesn't have this jittery problem. - local c = Util.read_file('/proc/cpuinfo') - local f = 0 - for s in __string_gmatch(c, 'cpu MHz%s+: (%d+%.%d+)') do - f = f + __tonumber(s) - end - return __string_format('%.0f Mhz', f / NCPU) -end - -local _read_hwp = function() - -- read HWP of first cpu, then test all others to see if they match - local hwp_pref = Util.read_file(HWP_PATHS[1], nil, "*l") - local mixed = false - local i = 2 - - while not mixed and i <= #HWP_PATHS do - if hwp_pref ~= Util.read_file(HWP_PATHS[i], nil, '*l') then - mixed = true - end - i = i + 1 - end - - if mixed then - return 'Mixed' - elseif hwp_pref == 'power' then - return 'Power' - elseif hwp_pref == 'balance_power' then - return 'Bal. Power' - elseif hwp_pref == 'balance_performance' then - return 'Bal. Performance' - elseif hwp_pref == 'performance' then - return 'Performance' - elseif hwp_pref == 'default' then - return 'Default' - else - return 'Unknown' - end -end -- _MODULE_Y_ = nil -- _DIAL_INNER_RADIUS_ = nil @@ -208,8 +117,25 @@ end -- _HWP_Y_ = nil -- _PLOT_Y_ = nil - return function(update_freq) + local cpu_loads = CPU.init_cpu_loads() + local ncpus = CPU.get_cpu_number() + local ncores = CPU.get_core_number() + local nthreads = ncpus / ncores + local hwp_paths = CPU.get_hwp_paths() + local coretemp_paths = CPU.get_coretemp_paths() + + -- prime the load matrix + CPU.read_cpu_loads(cpu_loads) + + local cores = {} + + for c = 1, ncores do + local dial_x = Geometry.LEFT_X + _DIAL_OUTER_RADIUS_ + + (Geometry.SECTION_WIDTH - 2 * _DIAL_OUTER_RADIUS_) * (c - 1) / 3 + local dial_y = header.bottom_y + _DIAL_OUTER_RADIUS_ + cores[c] = _create_core_(dial_x, dial_y, nthreads) + end local total_load = Common.initPercentPlot( Geometry.LEFT_X, @@ -225,40 +151,27 @@ return function(update_freq) local conky = Util.conky local load_sum = 0 - -- TODO bundle all the crap down below into this function and make it return - -- something useful rather than totally use a side effect (it will be mildly - -- slower) - -- this entire loop is about 10% total execution time - _read_cpu() - for c = 1, NUM_PHYSICAL_CORES do - local core = cores[c] + cpu_loads = CPU.read_cpu_loads(cpu_loads) + for _, load_data in pairs(cpu_loads) do + local cur = load_data.percent_active + load_sum = load_sum + cur + CompoundDial.set(cores[load_data.core_id].loads, load_data.thread_id, cur) + end - for t = 1, NUM_THREADS_PER_CORE do - -- TODO these might not match the actual core numbers (if I care) - local cl = cpu_loads[(c - 1) * NUM_THREADS_PER_CORE + t] - -- this is necessary to prevent 1/0 errors - if cl.total > cl.total_prev then - local p = (cl.active - cl.active_prev) / (cl.total - cl.total_prev) - CompoundDial.set(core.dials, t, p) - load_sum = load_sum + p - end - end - Common.text_ring_set( - core.text_ring, - cr, - __math_floor(0.001 * Util.read_file(core.coretemp_path, nil, '*n')) - ) + for core_id, path in pairs(coretemp_paths) do + local temp = __math_floor(0.001 * Util.read_file(path, nil, '*n')) + Common.text_ring_set(cores[core_id].coretemp, cr, temp) end -- 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 trigger == 0 then - Common.text_rows_set(cpu_status, cr, 1, _read_hwp()) + Common.text_rows_set(cpu_status, cr, 1, CPU.read_hwp(hwp_paths)) end - Common.text_rows_set(cpu_status, cr, 2, _read_freq()) + Common.text_rows_set(cpu_status, cr, 2, CPU.read_freq()) - Common.percent_plot_set(total_load, cr, load_sum / NCPU * 100) + Common.percent_plot_set(total_load, cr, load_sum / ncpus * 100) for r = 1, NUM_ROWS do local pid = conky(TABLE_CONKY[r].pid, '(%d+)') -- may have leading spaces @@ -275,10 +188,9 @@ return function(update_freq) local draw_static = function(cr) Common.drawHeader(cr, header) - for c = 1, NUM_PHYSICAL_CORES do - local this_core = cores[c] - Common.text_ring_draw_static(this_core.text_ring, cr) - CompoundDial.draw_static(this_core.dials, cr) + for _, this_core in pairs(cores) do + Common.text_ring_draw_static(this_core.coretemp, cr) + CompoundDial.draw_static(this_core.loads, cr) end Common.text_rows_draw_static(cpu_status, cr) @@ -292,10 +204,9 @@ return function(update_freq) local draw_dynamic = function(cr, trigger) update(cr, trigger) - for c = 1, NUM_PHYSICAL_CORES do - local this_core = cores[c] - CompoundDial.draw_dynamic(this_core.dials, cr) - Common.text_ring_draw_dynamic(this_core.text_ring, cr) + for _, this_core in pairs(cores) do + CompoundDial.draw_dynamic(this_core.loads, cr) + Common.text_ring_draw_dynamic(this_core.coretemp, cr) end Common.text_rows_draw_dynamic(cpu_status, cr) diff --git a/main.lua b/main.lua index 663f64e..c6ff7da 100644 --- a/main.lua +++ b/main.lua @@ -36,8 +36,7 @@ local using_ac = function() return Util.read_file('/sys/class/power_supply/BAT0/status', nil, '*l') ~= 'Discharging' end -local updates = -2 -- this accounts for the first few spazzy iterations -local draw +local draw_dynamic function conky_start(update_interval) conky_set_update_interval(update_interval) @@ -62,7 +61,7 @@ function conky_start(update_interval) local STATS_FILE = '/tmp/.conky_pacman' - draw = function(cr, _updates) + draw_dynamic = function(cr, _updates) draw_static(cr) local t1 = _updates % (update_freq * 10) @@ -83,6 +82,8 @@ function conky_start(update_interval) end end +local updates = -2 -- this accounts for the first few spazzy iterations + function conky_main() local _cw = conky_window if not _cw then return end @@ -92,7 +93,7 @@ function conky_main() local cr = __cairo_create(cs) updates = updates + 1 - draw(cr, updates) + draw_dynamic(cr, updates) __cairo_surface_destroy(cs) __cairo_destroy(cr)