mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 18:56:29 +00:00
cpu_load_display: enable strict conversions
Besides raising the warning level, the patch updates the coding style ('with_' pattern, using, type safety, constness).
This commit is contained in:
parent
c629c54153
commit
b11116088a
@ -25,33 +25,35 @@
|
||||
|
||||
namespace Cpu_load_display {
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
class Timeline;
|
||||
class Cpu;
|
||||
class Cpu_registry;
|
||||
template <typename> class Scene;
|
||||
|
||||
typedef Genode::Xml_node Xml_node;
|
||||
typedef Genode::Color Color;
|
||||
|
||||
using Genode::max;
|
||||
struct Subject_id { unsigned value; };
|
||||
struct Activity { uint64_t value; };
|
||||
};
|
||||
|
||||
|
||||
class Cpu_load_display::Timeline : public Genode::List<Timeline>::Element
|
||||
class Cpu_load_display::Timeline : public List<Timeline>::Element
|
||||
{
|
||||
public:
|
||||
|
||||
enum { HISTORY_LEN = 32 };
|
||||
static constexpr unsigned HISTORY_LEN = 32;
|
||||
|
||||
typedef Genode::String<160> Label;
|
||||
using Label = String<160>;
|
||||
|
||||
struct Index { unsigned value; };
|
||||
|
||||
private:
|
||||
|
||||
unsigned const _subject_id = 0;
|
||||
Subject_id const _subject_id;
|
||||
|
||||
unsigned _activity[HISTORY_LEN];
|
||||
Activity _activity[HISTORY_LEN] { };
|
||||
|
||||
unsigned _sum_activity = 0;
|
||||
Activity _sum_activity { };
|
||||
|
||||
Label _label;
|
||||
|
||||
@ -65,45 +67,40 @@ class Cpu_load_display::Timeline : public Genode::List<Timeline>::Element
|
||||
* to a hash function.
|
||||
*/
|
||||
unsigned int const a = 1588635695, q = 2, r = 1117695901;
|
||||
return (a*(_subject_id % q) - r*(_subject_id / q)) & 255;
|
||||
return (a*(_subject_id.value % q) - r*(_subject_id.value / q)) & 255;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Timeline(unsigned subject_id, Label const &label)
|
||||
Timeline(Subject_id subject_id, Label const &label)
|
||||
:
|
||||
_subject_id(subject_id), _label(label)
|
||||
{
|
||||
Genode::memset(_activity, 0, sizeof(_activity));
|
||||
}
|
||||
{ }
|
||||
|
||||
void activity(unsigned long recent_activity, unsigned now)
|
||||
void activity(Activity recent_activity, unsigned now)
|
||||
{
|
||||
unsigned const i = now % HISTORY_LEN;
|
||||
|
||||
_sum_activity -= _activity[i];
|
||||
_sum_activity.value -= _activity[i].value;
|
||||
|
||||
_activity[i] = recent_activity;
|
||||
|
||||
_sum_activity += recent_activity;
|
||||
_sum_activity.value += recent_activity.value;
|
||||
}
|
||||
|
||||
unsigned long activity(unsigned i) const
|
||||
Activity activity(Index const i) const
|
||||
{
|
||||
return _activity[i % HISTORY_LEN];
|
||||
return _activity[i.value % HISTORY_LEN];
|
||||
}
|
||||
|
||||
bool has_subject_id(unsigned subject_id) const
|
||||
bool has_subject_id(Subject_id const subject_id) const
|
||||
{
|
||||
return _subject_id == subject_id;
|
||||
return _subject_id.value == subject_id.value;
|
||||
}
|
||||
|
||||
bool idle() const { return _sum_activity == 0; }
|
||||
bool idle() const { return _sum_activity.value == 0; }
|
||||
|
||||
bool kernel() const
|
||||
{
|
||||
return _label == Label("kernel");
|
||||
}
|
||||
bool kernel() const { return _label == Label("kernel"); }
|
||||
|
||||
enum Color_type { COLOR_TOP, COLOR_BOTTOM };
|
||||
|
||||
@ -119,58 +116,58 @@ class Cpu_load_display::Timeline : public Genode::List<Timeline>::Element
|
||||
};
|
||||
|
||||
|
||||
class Cpu_load_display::Cpu : public Genode::List<Cpu>::Element
|
||||
class Cpu_load_display::Cpu : public List<Cpu>::Element
|
||||
{
|
||||
public:
|
||||
|
||||
using Affinity = Point<>;
|
||||
|
||||
private:
|
||||
|
||||
Genode::Allocator &_heap;
|
||||
Genode::Point<> const _pos;
|
||||
Genode::List<Timeline> _timelines { };
|
||||
Allocator &_heap;
|
||||
Affinity const _pos;
|
||||
List<Timeline> _timelines { };
|
||||
|
||||
Timeline *_lookup_timeline(Xml_node subject)
|
||||
void _with_timeline(Xml_node const &subject, auto const &fn)
|
||||
{
|
||||
unsigned long const subject_id = subject.attribute_value("id", 0UL);
|
||||
Subject_id const subject_id { subject.attribute_value("id", 0U) };
|
||||
|
||||
Timeline::Label const label =
|
||||
subject.attribute_value("label", Timeline::Label());
|
||||
|
||||
for (Timeline *t = _timelines.first(); t; t = t->next()) {
|
||||
if (t->has_subject_id(subject_id))
|
||||
return t;
|
||||
}
|
||||
if (t->has_subject_id(subject_id)) {
|
||||
fn(*t);
|
||||
return; } }
|
||||
|
||||
/* add new timeline */
|
||||
Timeline *t = new (_heap) Timeline(subject_id, label);
|
||||
_timelines.insert(t);
|
||||
return t;
|
||||
Timeline &t = *new (_heap) Timeline(subject_id, label);
|
||||
_timelines.insert(&t);
|
||||
fn(t);
|
||||
}
|
||||
|
||||
unsigned long _activity(Xml_node subject)
|
||||
Activity _activity(Xml_node const &subject)
|
||||
{
|
||||
try {
|
||||
Xml_node activity = subject.sub_node("activity");
|
||||
return activity.attribute_value("recent", 0UL);
|
||||
} catch (Xml_node::Nonexistent_sub_node) { }
|
||||
Activity result { };
|
||||
subject.with_optional_sub_node("activity", [&] (Xml_node const &activity) {
|
||||
result = { activity.attribute_value("recent", 0U) }; });
|
||||
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Cpu(Genode::Allocator &heap, Genode::Point<> pos)
|
||||
: _heap(heap), _pos(pos) { }
|
||||
Cpu(Allocator &heap, Affinity pos) : _heap(heap), _pos(pos) { }
|
||||
|
||||
bool has_pos(Genode::Point<> pos) const
|
||||
bool has_pos(Affinity const pos) const { return pos == _pos; }
|
||||
|
||||
void import_trace_subject(Xml_node const &subject, unsigned now)
|
||||
{
|
||||
return pos == _pos;
|
||||
}
|
||||
Activity const activity = _activity(subject);
|
||||
|
||||
void import_trace_subject(Xml_node subject, unsigned now)
|
||||
{
|
||||
unsigned long const activity = _activity(subject);
|
||||
|
||||
if (activity)
|
||||
_lookup_timeline(subject)->activity(activity, now);
|
||||
if (activity.value)
|
||||
_with_timeline(subject, [&] (Timeline &timeline) {
|
||||
timeline.activity(activity, now); });
|
||||
}
|
||||
|
||||
void advance(unsigned now)
|
||||
@ -180,28 +177,27 @@ class Cpu_load_display::Cpu : public Genode::List<Cpu>::Element
|
||||
|
||||
next = t->next();
|
||||
|
||||
t->activity(0, now);
|
||||
t->activity({ 0 }, now);
|
||||
|
||||
if (t->idle()) {
|
||||
|
||||
_timelines.remove(t);
|
||||
Genode::destroy(_heap, t);
|
||||
destroy(_heap, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long activity_sum(unsigned i) const
|
||||
Activity activity_sum(Timeline::Index const i) const
|
||||
{
|
||||
unsigned long sum = 0;
|
||||
uint64_t sum = 0;
|
||||
|
||||
for (Timeline const *t = _timelines.first(); t; t = t->next())
|
||||
sum += t->activity(i);
|
||||
sum += t->activity(i).value;
|
||||
|
||||
return sum;
|
||||
return { sum };
|
||||
}
|
||||
|
||||
template <typename FN>
|
||||
void for_each_timeline(FN const &fn) const
|
||||
void for_each_timeline(auto const &fn) const
|
||||
{
|
||||
for (Timeline const *t = _timelines.first(); t; t = t->next())
|
||||
fn(*t);
|
||||
@ -213,55 +209,51 @@ class Cpu_load_display::Cpu_registry
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Allocator &_heap;
|
||||
Allocator &_heap;
|
||||
|
||||
Genode::List<Cpu> _cpus { };
|
||||
List<Cpu> _cpus { };
|
||||
|
||||
static Genode::Point<> _cpu_pos(Xml_node subject)
|
||||
static Cpu::Affinity _cpu_pos(Xml_node const &subject)
|
||||
{
|
||||
try {
|
||||
Xml_node affinity = subject.sub_node("affinity");
|
||||
return Genode::Point<>(affinity.attribute_value("xpos", 0UL),
|
||||
affinity.attribute_value("ypos", 0UL));
|
||||
} catch (Xml_node::Nonexistent_sub_node) { }
|
||||
Cpu::Affinity result { 0, 0 };
|
||||
subject.with_optional_sub_node("affinity", [&] (Xml_node const &affinity) {
|
||||
result = Cpu::Affinity::from_xml(affinity); });
|
||||
|
||||
return Genode::Point<>(0, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
Cpu *_lookup_cpu(Xml_node subject)
|
||||
void _with_cpu(Xml_node const &subject, auto const &fn)
|
||||
{
|
||||
/* find CPU that matches the affinity of the subject */
|
||||
Genode::Point<> cpu_pos = _cpu_pos(subject);
|
||||
Cpu::Affinity const cpu_pos = _cpu_pos(subject);
|
||||
for (Cpu *cpu = _cpus.first(); cpu; cpu = cpu->next()) {
|
||||
if (cpu->has_pos(cpu_pos))
|
||||
return cpu;
|
||||
}
|
||||
if (cpu->has_pos(cpu_pos)) {
|
||||
fn(*cpu);
|
||||
return; } }
|
||||
|
||||
/* add new CPU */
|
||||
Cpu *cpu = new (_heap) Cpu(_heap, cpu_pos);
|
||||
_cpus.insert(cpu);
|
||||
return cpu;
|
||||
Cpu &cpu = *new (_heap) Cpu(_heap, cpu_pos);
|
||||
_cpus.insert(&cpu);
|
||||
fn(cpu);
|
||||
}
|
||||
|
||||
void _import_trace_subject(Xml_node subject, unsigned now)
|
||||
void _import_trace_subject(Xml_node const &subject, unsigned now)
|
||||
{
|
||||
Cpu *cpu = _lookup_cpu(subject);
|
||||
|
||||
cpu->import_trace_subject(subject, now);
|
||||
_with_cpu(subject, [&] (Cpu &cpu) {
|
||||
cpu.import_trace_subject(subject, now); });
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Cpu_registry(Genode::Allocator &heap) : _heap(heap) { }
|
||||
Cpu_registry(Allocator &heap) : _heap(heap) { }
|
||||
|
||||
void import_trace_subjects(Xml_node node, unsigned now)
|
||||
void import_trace_subjects(Xml_node const &node, unsigned now)
|
||||
{
|
||||
node.for_each_sub_node("subject", [&] (Xml_node subject) {
|
||||
node.for_each_sub_node("subject", [&] (Xml_node const &subject) {
|
||||
_import_trace_subject(subject, now); });
|
||||
}
|
||||
|
||||
template <typename FN>
|
||||
void for_each_cpu(FN const &fn) const
|
||||
void for_each_cpu(auto const &fn) const
|
||||
{
|
||||
for (Cpu const *cpu = _cpus.first(); cpu; cpu = cpu->next())
|
||||
fn(*cpu);
|
||||
@ -280,21 +272,21 @@ class Cpu_load_display::Scene : public Nano3d::Scene<PT>
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Env &_env;
|
||||
Env &_env;
|
||||
|
||||
Gui::Area const _size;
|
||||
|
||||
Genode::Attached_rom_dataspace _config { _env, "config" };
|
||||
Attached_rom_dataspace _config { _env, "config" };
|
||||
|
||||
void _handle_config() { _config.update(); }
|
||||
|
||||
Genode::Signal_handler<Scene> _config_handler;
|
||||
Signal_handler<Scene> _config_handler;
|
||||
|
||||
Genode::Attached_rom_dataspace _trace_subjects { _env, "trace_subjects" };
|
||||
Attached_rom_dataspace _trace_subjects { _env, "trace_subjects" };
|
||||
|
||||
unsigned _now = 0;
|
||||
|
||||
Genode::Heap _heap { _env.ram(), _env.rm() };
|
||||
Heap _heap { _env.ram(), _env.rm() };
|
||||
|
||||
Cpu_registry _cpu_registry { _heap };
|
||||
|
||||
@ -307,17 +299,14 @@ class Cpu_load_display::Scene : public Nano3d::Scene<PT>
|
||||
|
||||
_cpu_registry.advance(++_now);
|
||||
|
||||
try {
|
||||
Xml_node subjects(_trace_subjects.local_addr<char>());
|
||||
_cpu_registry.import_trace_subjects(subjects, _now);
|
||||
} catch (...) { Genode::error("failed to import trace subjects"); }
|
||||
_cpu_registry.import_trace_subjects(_trace_subjects.xml(), _now);
|
||||
}
|
||||
|
||||
Genode::Signal_handler<Scene> _trace_subjects_handler;
|
||||
Signal_handler<Scene> _trace_subjects_handler;
|
||||
|
||||
public:
|
||||
|
||||
Scene(Genode::Env &env, Genode::uint64_t update_rate_ms,
|
||||
Scene(Env &env, uint64_t update_rate_ms,
|
||||
Gui::Point pos, Gui::Area size)
|
||||
:
|
||||
Nano3d::Scene<PT>(env, update_rate_ms, pos, size),
|
||||
@ -335,19 +324,18 @@ class Cpu_load_display::Scene : public Nano3d::Scene<PT>
|
||||
|
||||
Polygon::Shaded_painter _shaded_painter { _heap, _size.h };
|
||||
|
||||
long _activity_sum[Timeline::HISTORY_LEN];
|
||||
long _y_level[Timeline::HISTORY_LEN];
|
||||
long _y_curr[Timeline::HISTORY_LEN];
|
||||
static constexpr unsigned HISTORY_LEN = Timeline::HISTORY_LEN;
|
||||
|
||||
void _plot_cpu(Genode::Surface<PT> &pixel,
|
||||
Genode::Surface<Genode::Pixel_alpha8> &alpha,
|
||||
Activity _activity_sum [HISTORY_LEN];
|
||||
int _y_level [HISTORY_LEN];
|
||||
int _y_curr [HISTORY_LEN];
|
||||
|
||||
void _plot_cpu(Surface<PT> &pixel, Surface<Pixel_alpha8> &alpha,
|
||||
Cpu const &cpu, Gui::Rect rect)
|
||||
{
|
||||
enum { HISTORY_LEN = Timeline::HISTORY_LEN };
|
||||
|
||||
/* calculate activity sum for each point in history */
|
||||
for (unsigned i = 0; i < HISTORY_LEN; i++)
|
||||
_activity_sum[i] = cpu.activity_sum(i);
|
||||
_activity_sum[i] = cpu.activity_sum(Timeline::Index{i});
|
||||
|
||||
for (unsigned i = 0; i < HISTORY_LEN; i++)
|
||||
_y_level[i] = 0;
|
||||
@ -374,9 +362,11 @@ class Cpu_load_display::Scene : public Nano3d::Scene<PT>
|
||||
unsigned const t = (_now - i - 0) % HISTORY_LEN;
|
||||
unsigned const prev_t = (_now - i + 1) % HISTORY_LEN;
|
||||
|
||||
unsigned long const activity = timeline.activity(t);
|
||||
uint64_t const activity = timeline.activity(Timeline::Index{t}).value;
|
||||
|
||||
int const dy = _activity_sum[t] ? (activity*h) / _activity_sum[t] : 0;
|
||||
int const dy = _activity_sum[t].value
|
||||
? int((activity*h) / _activity_sum[t].value)
|
||||
: 0;
|
||||
|
||||
_y_curr[t] = _y_level[t] + dy;
|
||||
|
||||
@ -392,24 +382,29 @@ class Cpu_load_display::Scene : public Nano3d::Scene<PT>
|
||||
int const y2 = rect.y1() + h - _y_level[prev_t];
|
||||
int const y3 = rect.y1() + h - _y_level[t];
|
||||
|
||||
typedef Polygon::Shaded_painter::Point Point;
|
||||
Point points[4];
|
||||
points[0] = Point(x0, y0, top_color);
|
||||
points[1] = Point(x1, y1, top_color);
|
||||
points[2] = Point(x1, y2, y1 == y2 ? top_color : bottom_color);
|
||||
points[3] = Point(x0, y3, y3 == y0 ? top_color : bottom_color);
|
||||
_shaded_painter.paint(pixel, alpha, points, 4);
|
||||
using Point = Polygon::Shaded_painter::Point;
|
||||
{
|
||||
Point const points[4] {
|
||||
Point(x0, y0, top_color),
|
||||
Point(x1, y1, top_color),
|
||||
Point(x1, y2, y1 == y2 ? top_color : bottom_color),
|
||||
Point(x0, y3, y3 == y0 ? top_color : bottom_color) };
|
||||
|
||||
_shaded_painter.paint(pixel, alpha, points, 4);
|
||||
}
|
||||
|
||||
/* drop shadow */
|
||||
Color const black (0, 0, 0, 100);
|
||||
Color const translucent (0, 0, 0, 0);
|
||||
{
|
||||
Color const black (0, 0, 0, 100);
|
||||
Color const translucent (0, 0, 0, 0);
|
||||
Point const points[4] {
|
||||
Point(x0, y3 - 5, translucent),
|
||||
Point(x1, y2 - 5, translucent),
|
||||
Point(x1, y2, black),
|
||||
Point(x0, y3, black) };
|
||||
|
||||
points[0] = Point(x0, y3 - 5, translucent);
|
||||
points[1] = Point(x1, y2 - 5, translucent);
|
||||
points[2] = Point(x1, y2, black);
|
||||
points[3] = Point(x0, y3, black);
|
||||
|
||||
_shaded_painter.paint(pixel, alpha, points, 4);
|
||||
_shaded_painter.paint(pixel, alpha, points, 4);
|
||||
}
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
@ -417,7 +412,6 @@ class Cpu_load_display::Scene : public Nano3d::Scene<PT>
|
||||
/* raise level by the values of the current timeline */
|
||||
for (unsigned i = 0; i < HISTORY_LEN; i++)
|
||||
_y_level[i] = _y_curr[i];
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@ -426,22 +420,22 @@ class Cpu_load_display::Scene : public Nano3d::Scene<PT>
|
||||
/**
|
||||
* Scene interface
|
||||
*/
|
||||
void render(Genode::Surface<PT> &pixel,
|
||||
Genode::Surface<Genode::Pixel_alpha8> &alpha) override
|
||||
void render(Surface<PT> &pixel, Surface<Pixel_alpha8> &alpha) override
|
||||
{
|
||||
/* background */
|
||||
Color const top_color = Color(10, 10, 10, 20);
|
||||
Color const bottom_color = Color(10, 10, 10, 100);
|
||||
Color const top_color { 10, 10, 10, 20 };
|
||||
Color const bottom_color { 10, 10, 10, 100 };
|
||||
|
||||
unsigned const w = pixel.size().w;
|
||||
unsigned const h = pixel.size().h;
|
||||
|
||||
typedef Polygon::Shaded_painter::Point Point;
|
||||
Point points[4];
|
||||
points[0] = Point(0, 0, top_color);
|
||||
points[1] = Point(w - 1, 0, top_color);
|
||||
points[2] = Point(w - 1, h - 1, bottom_color);
|
||||
points[3] = Point(0, h - 1, bottom_color);
|
||||
using Point = Polygon::Shaded_painter::Point;
|
||||
|
||||
Point const points[4] { Point(0, 0, top_color),
|
||||
Point(w - 1, 0, top_color),
|
||||
Point(w - 1, h - 1, bottom_color),
|
||||
Point(0, h - 1, bottom_color) };
|
||||
|
||||
_shaded_painter.paint(pixel, alpha, points, 4);
|
||||
|
||||
/* determine number of CPUs */
|
||||
@ -452,22 +446,21 @@ class Cpu_load_display::Scene : public Nano3d::Scene<PT>
|
||||
return;
|
||||
|
||||
/* plot graphs for the CPUs below each other */
|
||||
enum { GAP = 8 };
|
||||
int const GAP = 8;
|
||||
Gui::Point const step(0, _size.h/num_cpus);
|
||||
Gui::Area const size(_size.w, step.y - GAP);
|
||||
Gui::Point point(0, GAP/2);
|
||||
|
||||
_cpu_registry.for_each_cpu([&] (Cpu const &cpu) {
|
||||
_plot_cpu(pixel, alpha, cpu, Gui::Rect(point, size));
|
||||
point = point + step;
|
||||
});
|
||||
point = point + step; });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
enum { UPDATE_RATE_MS = 250 };
|
||||
Genode::uint64_t const UPDATE_RATE_MS = 250;
|
||||
|
||||
static Cpu_load_display::Scene<Genode::Pixel_rgb888>
|
||||
scene(env, UPDATE_RATE_MS,
|
||||
|
@ -2,5 +2,3 @@ TARGET = cpu_load_display
|
||||
SRC_CC = main.cc
|
||||
LIBS = base
|
||||
INC_DIR += $(PRG_DIR)
|
||||
|
||||
CC_CXX_WARN_STRICT_CONVERSION =
|
||||
|
Loading…
Reference in New Issue
Block a user