mirror of
https://github.com/subhobhai943/SUB-OS.git
synced 2026-10-25 16:52:29 +00:00
feat(cpp,gui): C++ Analytics Engine + live GUI Analytics app
Kernel (C++17 freestanding):
- New Analytics Engine (kernel/cpp/cpp_analytics.cpp): templated rolling
time-series (TimeSeries<N>) sampling four live channels -- CPU load %,
memory %, kernel-heap %, network pkt/interval -- with windowed statistics
(min/max/mean/stddev) computed in pure integer math (kernel is -mno-sse, so
no FP; stddev uses a Newton integer isqrt). Demonstrates virtual dispatch
via an Observer pattern (IAnalyticsObserver + a ThresholdAlarmObserver that
counts breaches) and RAII singletons.
- Extended cpp_containers.hpp with Optional<T>, Pair<A,B>, and the kmin/kmax/
kclamp/kswap algorithms.
- Full C fallback (cpp_fallback.c) so the engine is functionally identical on
aarch64/armv8i, which don't build the .cpp path.
- Wired cpp_analytics_init() into boot [8/14]; seeds a few samples so graphs
are populated immediately.
GUI:
- New "Analytics" desktop app (gui/gui_apps.c): a 2x2 grid of live line-charts
backed by the C++ engine, each with gridlines, a soft baseline fill, and
min/avg/max(/stddev) overlays; click a panel to focus one channel full-size,
click again to return. Throttled to ~2 Hz sampling off the compositor's
repaint cadence. Registered on the desktop and in the start menu.
Userland: new `cppstat [samples]` applet dumps the engine's per-channel stats
and Observer breach counters.
Verified in QEMU (x86_64): boots clean on x86_64/aarch64/armv8i; `cppstat`
prints live stats (CPU 6%, Mem 7%, Heap 22%, computed min/avg/max/stddev,
Observer breaches); the GUI Analytics window renders all four graphs with the
Kernel Heap curve visibly climbing 22->55% as windows open, compositor steady
at ~53 FPS.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX
This commit is contained in:
1 parent
cd840d5799
commit
5bd18c4733
9 files changed
+762
-2
No files matched your search
@@ -42,6 +42,89 @@ constexpr T&& forward(typename RemoveReference<T>::type&& arg) noexcept {
|
||||
return static_cast<T&&>(arg);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Freestanding numeric algorithms (namespaced to avoid clashing with the C
|
||||
// kmin/kmax macros/inlines the kernel exposes elsewhere).
|
||||
// -----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
constexpr const T& kmin(const T& a, const T& b) { return (a < b) ? a : b; }
|
||||
|
||||
template<typename T>
|
||||
constexpr const T& kmax(const T& a, const T& b) { return (a > b) ? a : b; }
|
||||
|
||||
template<typename T>
|
||||
constexpr const T& kclamp(const T& v, const T& lo, const T& hi) {
|
||||
return (v < lo) ? lo : ((v > hi) ? hi : v);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr void kswap(T& a, T& b) {
|
||||
T tmp = move(a);
|
||||
a = move(b);
|
||||
b = move(tmp);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Pair (Freestanding two-element tuple)
|
||||
// -----------------------------------------------------------------------------
|
||||
template<typename A, typename B>
|
||||
struct Pair {
|
||||
A first;
|
||||
B second;
|
||||
|
||||
constexpr Pair() : first(), second() {}
|
||||
constexpr Pair(const A& a, const B& b) : first(a), second(b) {}
|
||||
};
|
||||
|
||||
template<typename A, typename B>
|
||||
constexpr Pair<A, B> make_pair(const A& a, const B& b) { return Pair<A, B>(a, b); }
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Optional (Freestanding maybe-value, no heap)
|
||||
// -----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
class Optional {
|
||||
private:
|
||||
alignas(T) unsigned char m_storage[sizeof(T)];
|
||||
bool m_has;
|
||||
|
||||
T* ptr() { return reinterpret_cast<T*>(m_storage); }
|
||||
const T* ptr() const { return reinterpret_cast<const T*>(m_storage); }
|
||||
|
||||
public:
|
||||
constexpr Optional() noexcept : m_has(false) {}
|
||||
|
||||
Optional(const T& value) : m_has(true) {
|
||||
new (static_cast<void*>(m_storage)) T(value);
|
||||
}
|
||||
|
||||
Optional(const Optional& other) : m_has(other.m_has) {
|
||||
if (m_has) new (static_cast<void*>(m_storage)) T(*other.ptr());
|
||||
}
|
||||
|
||||
~Optional() { reset(); }
|
||||
|
||||
Optional& operator=(const Optional& other) {
|
||||
if (this != &other) {
|
||||
reset();
|
||||
m_has = other.m_has;
|
||||
if (m_has) new (static_cast<void*>(m_storage)) T(*other.ptr());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
if (m_has) { ptr()->~T(); m_has = false; }
|
||||
}
|
||||
|
||||
bool has_value() const noexcept { return m_has; }
|
||||
explicit operator bool() const noexcept { return m_has; }
|
||||
|
||||
T& value() { return *ptr(); }
|
||||
const T& value() const { return *ptr(); }
|
||||
T value_or(const T& fallback) const { return m_has ? *ptr() : fallback; }
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// UniquePtr (Freestanding Smart Pointer RAII)
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
Reference in new issue
Block a user