diff --git a/AK/CircularQueue.h b/AK/CircularQueue.h index 7eb1ebf594b..cd97965d48c 100644 --- a/AK/CircularQueue.h +++ b/AK/CircularQueue.h @@ -1,7 +1,7 @@ #pragma once -#include "Assertions.h" -#include "Types.h" +#include +#include namespace AK { @@ -19,15 +19,6 @@ public: int capacity() const { return Capacity; } - void dump() const - { - kprintf("CircularQueue<%zu>:\n", Capacity); - kprintf(" size: %zu\n", m_size); - for (int i = 0; i < Capacity; ++i) { - kprintf(" [%zu] %d %c\n", i, m_elements[i], i == m_head ? '*' : ' '); - } - } - void enqueue(const T& t) { m_elements[(m_head + m_size) % Capacity] = t; diff --git a/Servers/WindowServer/Makefile b/Servers/WindowServer/Makefile index 5a39579bf15..2d23b18e880 100644 --- a/Servers/WindowServer/Makefile +++ b/Servers/WindowServer/Makefile @@ -24,6 +24,7 @@ WINDOWSERVER_OBJS = \ WSCursor.o \ WSWindowFrame.o \ WSButton.o \ + WSCPUMonitor.o \ main.o APP = WindowServer diff --git a/Servers/WindowServer/WSCPUMonitor.cpp b/Servers/WindowServer/WSCPUMonitor.cpp new file mode 100644 index 00000000000..6bdd80274cc --- /dev/null +++ b/Servers/WindowServer/WSCPUMonitor.cpp @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include + +WSCPUMonitor::WSCPUMonitor() +{ + create_thread([] (void* context) -> int { + auto& monitor = *(WSCPUMonitor*)context; + for (;;) { + static unsigned last_busy; + static unsigned last_idle; + unsigned busy; + unsigned idle; + monitor.get_cpu_usage(busy, idle); + unsigned busy_diff = busy - last_busy; + unsigned idle_diff = idle - last_idle; + last_busy = busy; + last_idle = idle; + float cpu = (float)busy_diff / (float)(busy_diff + idle_diff); + monitor.m_cpu_history.enqueue(cpu); + monitor.m_dirty = true; + sleep(1); + } + }, this); +} + +void WSCPUMonitor::get_cpu_usage(unsigned& busy, unsigned& idle) +{ + busy = 0; + idle = 0; + + FILE* fp = fopen("/proc/all", "r"); + if (!fp) { + perror("failed to open /proc/all"); + ASSERT_NOT_REACHED(); + } + for (;;) { + char buf[BUFSIZ]; + char* ptr = fgets(buf, sizeof(buf), fp); + if (!ptr) + break; + auto parts = String(buf, Chomp).split(','); + if (parts.size() < 17) + break; + bool ok; + pid_t pid = parts[0].to_uint(ok); + ASSERT(ok); + unsigned nsched = parts[1].to_uint(ok); + ASSERT(ok); + + if (pid == 0) + idle += nsched; + else + busy += nsched; + } + int rc = fclose(fp); + ASSERT(rc == 0); +} + +void WSCPUMonitor::paint(Painter& painter, const Rect& rect) +{ + painter.fill_rect(rect, Color::Black); + int i = m_cpu_history.capacity() - m_cpu_history.size(); + for (auto cpu_usage : m_cpu_history) { + painter.draw_line( + { rect.x() + i, rect.bottom() }, + { rect.x() + i, (int)(rect.y() + (rect.height() - (cpu_usage * (float)rect.height()))) }, + Color::from_rgb(0xaa6d4b) + ); + ++i; + } +} diff --git a/Servers/WindowServer/WSCPUMonitor.h b/Servers/WindowServer/WSCPUMonitor.h new file mode 100644 index 00000000000..c2e57968a5a --- /dev/null +++ b/Servers/WindowServer/WSCPUMonitor.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +class Painter; +class Rect; + +class WSCPUMonitor { +public: + WSCPUMonitor(); + + bool is_dirty() const { return m_dirty; } + void set_dirty(bool dirty) { m_dirty = dirty; } + int capacity() const { return m_cpu_history.capacity(); } + void paint(Painter&, const Rect&); + +private: + void get_cpu_usage(unsigned& busy, unsigned& idle); + + CircularQueue m_cpu_history; + bool m_dirty { false }; +}; diff --git a/Servers/WindowServer/WSWindowManager.cpp b/Servers/WindowServer/WSWindowManager.cpp index 54e367d5428..5ca0f935399 100644 --- a/Servers/WindowServer/WSWindowManager.cpp +++ b/Servers/WindowServer/WSWindowManager.cpp @@ -22,8 +22,6 @@ //#define DEBUG_COUNTERS //#define RESIZE_DEBUG -static void get_cpu_usage(unsigned& busy, unsigned& idle); - static WSWindowManager* s_the; WSWindowManager& WSWindowManager::the() @@ -143,34 +141,13 @@ WSWindowManager::WSWindowManager() // NOTE: This ensures that the system menu has the correct dimensions. set_current_menubar(nullptr); - create_thread([] (void* context) -> int { - auto& wm = *(WSWindowManager*)context; - for (;;) { - static unsigned last_busy; - static unsigned last_idle; - unsigned busy; - unsigned idle; - get_cpu_usage(busy, idle); - unsigned busy_diff = busy - last_busy; - unsigned idle_diff = idle - last_idle; - last_busy = busy; - last_idle = idle; - float cpu = (float)busy_diff / (float)(busy_diff + idle_diff); - wm.m_cpu_history.enqueue(cpu); - sleep(1); - } - }, this); - WSMessageLoop::the().start_timer(300, [this] { static time_t last_update_time; - static int last_cpu_history_size = 0; - static int last_cpu_history_head_index = 0; time_t now = time(nullptr); - if (now != last_update_time || m_cpu_history.size() != last_cpu_history_size || m_cpu_history.head_index() != last_cpu_history_head_index) { + if (now != last_update_time || m_cpu_monitor.is_dirty()) { tick_clock(); last_update_time = now; - last_cpu_history_head_index = m_cpu_history.head_index(); - last_cpu_history_size = m_cpu_history.size(); + m_cpu_monitor.set_dirty(false); } }); @@ -202,39 +179,6 @@ const Font& WSWindowManager::app_menu_font() const return Font::default_bold_font(); } -void get_cpu_usage(unsigned& busy, unsigned& idle) -{ - busy = 0; - idle = 0; - - FILE* fp = fopen("/proc/all", "r"); - if (!fp) { - perror("failed to open /proc/all"); - ASSERT_NOT_REACHED(); - } - for (;;) { - char buf[BUFSIZ]; - char* ptr = fgets(buf, sizeof(buf), fp); - if (!ptr) - break; - auto parts = String(buf, Chomp).split(','); - if (parts.size() < 17) - break; - bool ok; - pid_t pid = parts[0].to_uint(ok); - ASSERT(ok); - unsigned nsched = parts[1].to_uint(ok); - ASSERT(ok); - - if (pid == 0) - idle += nsched; - else - busy += nsched; - } - int rc = fclose(fp); - ASSERT(rc == 0); -} - void WSWindowManager::tick_clock() { invalidate(menubar_rect()); @@ -926,17 +870,8 @@ void WSWindowManager::draw_menubar() m_back_painter->draw_text(time_rect, time_text, font(), TextAlignment::CenterRight, Color::Black); - Rect cpu_rect { time_rect.right() - font().width(time_text) - (int)m_cpu_history.capacity() - 10, time_rect.y() + 1, (int)m_cpu_history.capacity(), time_rect.height() - 2 }; - m_back_painter->fill_rect(cpu_rect, Color::Black); - int i = m_cpu_history.capacity() - m_cpu_history.size(); - for (auto cpu_usage : m_cpu_history) { - m_back_painter->draw_line( - { cpu_rect.x() + i, cpu_rect.bottom() }, - { cpu_rect.x() + i, (int)(cpu_rect.y() + (cpu_rect.height() - (cpu_usage * (float)cpu_rect.height()))) }, - Color::from_rgb(0xaa6d4b) - ); - ++i; - } + Rect cpu_rect { time_rect.right() - font().width(time_text) - m_cpu_monitor.capacity() - 10, time_rect.y() + 1, m_cpu_monitor.capacity(), time_rect.height() - 2 }; + m_cpu_monitor.paint(*m_back_painter, cpu_rect); } void WSWindowManager::draw_window_switcher() diff --git a/Servers/WindowServer/WSWindowManager.h b/Servers/WindowServer/WSWindowManager.h index 26d35362f9a..53fbb0b1b92 100644 --- a/Servers/WindowServer/WSWindowManager.h +++ b/Servers/WindowServer/WSWindowManager.h @@ -15,7 +15,7 @@ #include #include #include -#include +#include class WSAPIClientRequest; class WSScreen; @@ -216,11 +216,11 @@ private: WSWindowSwitcher m_switcher; - CircularQueue m_cpu_history; - String m_username; WeakPtr m_cursor_tracking_button; WeakPtr m_hovered_button; + + WSCPUMonitor m_cpu_monitor; }; template