From c3029a6a1f51bd5876eabc8bc386dcca174fc9ab Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 5 Dec 2019 19:38:08 +0100 Subject: [PATCH] MenuApplets: Add CPUGraph, our first menu applet :^) This implements the WSCPUMonitor functionality in a separate process. --- Kernel/build-root-filesystem.sh | 1 + Kernel/makeall.sh | 2 + MenuApplets/CPUGraph/.gitignore | 1 + MenuApplets/CPUGraph/Makefile | 7 +++ MenuApplets/CPUGraph/main.cpp | 87 +++++++++++++++++++++++++++++++++ MenuApplets/Makefile.common | 14 ++++++ 6 files changed, 112 insertions(+) create mode 100644 MenuApplets/CPUGraph/.gitignore create mode 100755 MenuApplets/CPUGraph/Makefile create mode 100644 MenuApplets/CPUGraph/main.cpp create mode 100755 MenuApplets/Makefile.common diff --git a/Kernel/build-root-filesystem.sh b/Kernel/build-root-filesystem.sh index 5618d2351a3..c513e10b429 100755 --- a/Kernel/build-root-filesystem.sh +++ b/Kernel/build-root-filesystem.sh @@ -108,6 +108,7 @@ cp ../Servers/TTYServer/TTYServer mnt/bin/TTYServer cp ../Servers/TelnetServer/TelnetServer mnt/bin/TelnetServer cp ../Servers/ProtocolServer/ProtocolServer mnt/bin/ProtocolServer cp ../Shell/Shell mnt/bin/Shell +cp ../MenuApplets/CPUGraph/CPUGraph.MenuApplet mnt/bin/ echo "done" printf "installing shortcuts... " diff --git a/Kernel/makeall.sh b/Kernel/makeall.sh index 6d6321a9790..309aafac437 100755 --- a/Kernel/makeall.sh +++ b/Kernel/makeall.sh @@ -92,6 +92,8 @@ build_targets="$build_targets ../Shell" build_targets="$build_targets ../Userland" +build_targets="$build_targets ../MenuApplets/CPUGraph" + build_targets="$build_targets ." # the kernel (cd ../AK/Tests && $make_cmd clean) diff --git a/MenuApplets/CPUGraph/.gitignore b/MenuApplets/CPUGraph/.gitignore new file mode 100644 index 00000000000..699bfb17aa5 --- /dev/null +++ b/MenuApplets/CPUGraph/.gitignore @@ -0,0 +1 @@ +CPUGraph.MenuApplet diff --git a/MenuApplets/CPUGraph/Makefile b/MenuApplets/CPUGraph/Makefile new file mode 100755 index 00000000000..b90b7103a53 --- /dev/null +++ b/MenuApplets/CPUGraph/Makefile @@ -0,0 +1,7 @@ +include ../../Makefile.common + +OBJS = main.o + +APP = CPUGraph.MenuApplet + +include ../Makefile.common diff --git a/MenuApplets/CPUGraph/main.cpp b/MenuApplets/CPUGraph/main.cpp new file mode 100644 index 00000000000..8190c9aec00 --- /dev/null +++ b/MenuApplets/CPUGraph/main.cpp @@ -0,0 +1,87 @@ +#include +#include +#include +#include +#include +#include +#include + +NonnullRefPtr create_shared_bitmap(const Size& size) +{ + ASSERT(GWindowServerConnection::the().server_pid()); + ASSERT(!size.is_empty()); + size_t pitch = round_up_to_power_of_two(size.width() * sizeof(RGBA32), 16); + size_t size_in_bytes = size.height() * pitch; + auto shared_buffer = SharedBuffer::create_with_size(size_in_bytes); + ASSERT(shared_buffer); + shared_buffer->share_with(GWindowServerConnection::the().server_pid()); + return GraphicsBitmap::create_with_shared_buffer(GraphicsBitmap::Format::RGBA32, *shared_buffer, size); +} + +static void get_cpu_usage(unsigned& busy, unsigned& idle) +{ + busy = 0; + idle = 0; + + auto all_processes = CProcessStatisticsReader::get_all(); + + for (auto& it : all_processes) { + for (auto& jt : it.value.threads) { + if (it.value.pid == 0) + idle += jt.times_scheduled; + else + busy += jt.times_scheduled; + } + } +} + +int main(int argc, char** argv) +{ + GApplication app(argc, argv); + + Size applet_size(30, 16); + Rect applet_rect({}, applet_size); + + CircularQueue cpu_history; + + i32 applet_id = GWindowServerConnection::the().send_sync(applet_size)->applet_id(); + auto bitmap = create_shared_bitmap(applet_size); + + GWindowServerConnection::the().send_sync(applet_id, bitmap->shared_buffer_id()); + + unsigned last_busy = 0; + unsigned last_idle = 0; + + auto repaint = [&] { + 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); + cpu_history.enqueue(cpu); + + GPainter painter(*bitmap); + painter.fill_rect(applet_rect, Color::Black); + int i = cpu_history.capacity() - cpu_history.size(); + for (auto cpu_usage : cpu_history) { + painter.draw_line( + { applet_rect.x() + i, applet_rect.bottom() }, + { applet_rect.x() + i, (int)(applet_rect.y() + (applet_rect.height() - (cpu_usage * (float)applet_rect.height()))) }, + Color::from_rgb(0xaa6d4b)); + ++i; + } + + GWindowServerConnection::the().send_sync(applet_id, applet_rect); + }; + + repaint(); + + auto timer = CTimer::construct(1000, [&] { + repaint(); + }); + + return app.exec(); +} diff --git a/MenuApplets/Makefile.common b/MenuApplets/Makefile.common new file mode 100755 index 00000000000..23628b6a21e --- /dev/null +++ b/MenuApplets/Makefile.common @@ -0,0 +1,14 @@ +DEFINES += -DUSERLAND + +all: $(APP) + +$(APP): $(OBJS) + $(LD) -o $(APP) $(LDFLAGS) $(OBJS) -laudio -lgui -lipc -ldraw -lthread -lpthread -lcore -lc + +.cpp.o: + @echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $< + +-include $(OBJS:%.o=%.d) + +clean: + @echo "CLEAN"; rm -f $(APP) $(OBJS) *.d