From 57905e323c6c05c9d99eb946262c0459ec7016b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Lasersk=C3=B6ld?= Date: Thu, 2 Nov 2023 21:04:43 +0100 Subject: [PATCH] Started profiling stuff --- src/core/jobqueue.h | 21 +++++---- src/core/profiler.cpp | 21 +++++++++ src/core/profiler.h | 5 ++ src/core/threadname.cpp | 2 + src/core/timer.cpp | 3 ++ src/plugin/lsp/lspplugin.cpp | 4 ++ src/screen/deserializescreen.cpp | 6 +++ src/screen/guiscreen.cpp | 79 +++++++++++++++++++------------- src/screen/ncursesscreen.cpp | 13 ++++++ src/screen/serializescreen.cpp | 14 ++++++ src/settings.h | 7 ++- 11 files changed, 134 insertions(+), 41 deletions(-) diff --git a/src/core/jobqueue.h b/src/core/jobqueue.h index 3f025589..d0f37a3a 100644 --- a/src/core/jobqueue.h +++ b/src/core/jobqueue.h @@ -32,17 +32,20 @@ class JobQueue : public IJobQueue { } void work(bool shouldWait = true) override { - auto duration = ProfileDuration{}; - if (shouldWait) { - _waitMutex.lock(); - } - while (!_queue.empty() && _running) { - auto task = std::move(_queue.front()); - _queue.pop(); - task(); + { + auto duration = ProfileDuration{}; + if (shouldWait) { + _waitMutex.lock(); + } + while (!_queue.empty() && _running) { + auto task = std::move(_queue.front()); + _queue.pop(); + task(); + } } if (shouldWait) { + // auto duration = ProfileDuration{"JobQueue-wait"}; wait(); } } @@ -65,6 +68,7 @@ class JobQueue : public IJobQueue { private: //! Run and lock the current thread void loop() { + // auto profileDuration = ProfileDuration{}; setThreadName("jobs"); _threadId = std::this_thread::get_id(); while (_running) { @@ -93,5 +97,4 @@ class JobQueue : public IJobQueue { bool _running = true; std::thread::id _threadId = {}; std::thread _thread; - ProfileDuration _profileDuration{}; }; diff --git a/src/core/profiler.cpp b/src/core/profiler.cpp index 9ce19269..4f25ffe3 100644 --- a/src/core/profiler.cpp +++ b/src/core/profiler.cpp @@ -1,4 +1,5 @@ #include "profiler.h" +#include "core/threadname.h" #include #include #include @@ -66,6 +67,7 @@ struct ProfiledData { std::vector frames; std::vector instants; int id = generateProfilingThreadId(); + std::string name; }; struct GlobalData { @@ -98,11 +100,23 @@ struct GlobalData { auto file = std::ofstream{"medit_profile_log.json"}; file << "[\n"; + for (auto &data : threadFrameDatas) { + // Output the thread's meta information + + file << "{"; + file << "\"name\": \"thread_name\", "; + file << "\"ph\": \"M\", "; + file << "\"pid\": 1, "; // Assuming process id is 1 + file << "\"tid\": " << data->id << ", "; + file << "\"args\": {\"name\": \"" << data->name << "\"}"; + file << "}"; + for (auto &frame : data->frames) { file << frame << ",\n"; } } + file << "{}]\n"; threadFrameDatas.clear(); } @@ -199,3 +213,10 @@ void profileInstant(std::string_view value) { } localProfilingThreadData.instant(value); } + +void setProfilerThreadName(std::string name) { + if (!shouldEnableProfiling || !isThreadInitialized) { + return; + } + localProfilingThreadData.data->name = std::move(name); +} diff --git a/src/core/profiler.h b/src/core/profiler.h index bc9733bc..3ab77616 100644 --- a/src/core/profiler.h +++ b/src/core/profiler.h @@ -32,3 +32,8 @@ void profileInstant(std::string_view value); /// Just called once from main void enableProfiling(); + +void setProfilerThreadName(std::string name); + +#define PROFILE_FUNCTION() \ + auto profileDurationScopeVariable = ProfileDuration {} diff --git a/src/core/threadname.cpp b/src/core/threadname.cpp index dc5d1bc8..4b9aa816 100644 --- a/src/core/threadname.cpp +++ b/src/core/threadname.cpp @@ -1,4 +1,5 @@ #include "threadname.h" +#include "core/profiler.h" #include "os.h" #include #include @@ -11,6 +12,7 @@ void setThreadName(const std::string &name) { #ifdef MEDIT_USING_LINUX pthread_setname_np(pthread_self(), name.c_str()); #endif + setProfilerThreadName(name); } std::string getThreadName() { diff --git a/src/core/timer.cpp b/src/core/timer.cpp index a3f374e8..cc5769b5 100644 --- a/src/core/timer.cpp +++ b/src/core/timer.cpp @@ -1,4 +1,5 @@ #include "core/timer.h" +#include "core/profiler.h" #include "core/threadname.h" #include #include @@ -52,12 +53,14 @@ void Timer::stop() { } void Timer::loop() { + // auto duration = ProfileDuration{}; setThreadName("timer"); _isRunning = true; while (_isRunning) { { _mutex.lock(); while (!_triggers.empty()) { + auto duration = ProfileDuration{"Timer-task"}; auto nextTime = _triggers.front().time; if (nextTime < std::chrono::system_clock::now()) { auto next = std::move(_triggers.front()); diff --git a/src/plugin/lsp/lspplugin.cpp b/src/plugin/lsp/lspplugin.cpp index e5fa32fb..6a59c49c 100644 --- a/src/plugin/lsp/lspplugin.cpp +++ b/src/plugin/lsp/lspplugin.cpp @@ -3,6 +3,7 @@ #include "core/coreenvironment.h" #include "core/ijobqueue.h" #include "core/plugins.h" +#include "core/profiler.h" #include "files/project.h" #include "lsp/clientnotifications.h" #include "lsp/lspclient.h" @@ -230,6 +231,7 @@ LspPlugin::Instance *LspPlugin::createInstance(std::filesystem::path path) { void LspPlugin::handleSemanticsTokens(std::shared_ptr buffer, std::vector data) { + auto duration = ProfileDuration{}; struct Item { long *data; @@ -318,6 +320,7 @@ void LspPlugin::handleSemanticsTokens(std::shared_ptr buffer, void LspPlugin::requestSemanticsToken(std::shared_ptr buffer, Instance &instance) { + auto duration = ProfileDuration{}; auto params = SemanticTokensParams{}; params.textDocument.uri = pathToUri(buffer->path()); @@ -342,6 +345,7 @@ void LspPlugin::requestSemanticsToken(std::shared_ptr buffer, bool LspPlugin::updateBuffer(Buffer &buffer) { // TODO: Only update buffers with changed revision + auto duration = ProfileDuration{}; auto i = instance(buffer.path()); if (!i) { diff --git a/src/screen/deserializescreen.cpp b/src/screen/deserializescreen.cpp index 244f78bd..95e09425 100644 --- a/src/screen/deserializescreen.cpp +++ b/src/screen/deserializescreen.cpp @@ -1,6 +1,7 @@ #include "deserializescreen.h" #include "core/inarchive.h" #include "core/outarchive.h" +#include "core/profiler.h" #include "screen/cursorstyle.h" #include "syntax/palette.h" #include @@ -24,14 +25,17 @@ void DeserializeScreen::close() { } void DeserializeScreen::write(std::string_view data) { + PROFILE_FUNCTION(); handle(data); } void DeserializeScreen::unsubscribe() { + PROFILE_FUNCTION(); _callback = {}; } void DeserializeScreen::handle(std::string_view str) { + PROFILE_FUNCTION(); auto ss = std::istringstream{std::string{str}}; auto arch = InArchive{ss}; @@ -121,6 +125,7 @@ void DeserializeScreen::handle(std::string_view str) { } void DeserializeScreen::send(std::string_view str) { + PROFILE_FUNCTION(); // auto ss = std::stringstream{}; // ss << data; if (!_callback) { @@ -136,6 +141,7 @@ void DeserializeScreen::send(std::string_view str) { } void DeserializeScreen::screenCallback(IScreen::EventListT list) { + PROFILE_FUNCTION(); auto ss = std::ostringstream{}; { diff --git a/src/screen/guiscreen.cpp b/src/screen/guiscreen.cpp index dc26fcc1..9b7a27aa 100644 --- a/src/screen/guiscreen.cpp +++ b/src/screen/guiscreen.cpp @@ -284,6 +284,7 @@ struct GuiScreen::Buffer { // Make sure that the bottom line aligns with the window border void drawBottomLine(sdl::RendererView renderer) { + auto d = ProfileDuration{}; screen.render(renderer, 0, pixelHeight - screen.cache.charHeight, @@ -308,44 +309,58 @@ struct GuiScreen::Buffer { auto l = std::lock_guard{refreshMutex}; _tv(); - for (size_t y = 0; y < shownLines.size(); ++y) { - renderLine(y, shownLines.at(y)); - } + { + auto d = ProfileDuration{"Draw"}; + + { + auto d = ProfileDuration{"Render Lines"}; + for (size_t y = 0; y < shownLines.size(); ++y) { + renderLine(y, shownLines.at(y)); + } + } - renderer.drawColor(_styles.front().bg); - renderer.fillRect(); + renderer.drawColor(_styles.front().bg); + renderer.fillRect(); - auto rect = - sdl::Rect{0, 0, screen.canvas.width, screen.canvas.height - 1}; - screen.render(renderer, 0, 0, rect); - drawBottomLine(renderer); + auto rect = + sdl::Rect{0, 0, screen.canvas.width, screen.canvas.height - 1}; + { + auto d = ProfileDuration{"RenderScreen"}; + screen.render(renderer, 0, 0, rect); + } + drawBottomLine(renderer); - renderer.drawColor(sdl::White); + renderer.drawColor(sdl::White); - auto cellWidth = screen.cache.charWidth; - auto cellHeight = screen.cache.charHeight; + auto cellWidth = screen.cache.charWidth; + auto cellHeight = screen.cache.charHeight; - switch (cursorStyle) { - case CursorStyle::Beam: - renderer.fillRect( - sdl::Rect{static_cast(cellWidth * cursorPos.x()), - static_cast(cellHeight * cursorPos.y()), - 1, - static_cast(cellHeight)}); - break; - default: - // renderer.fillRect( - // sdl::Rect{static_cast(cellWidth * - // cursorPos.x()), - // static_cast(cellHeight * - // cursorPos.y()), - // static_cast(cellWidth), - // static_cast(cellHeight)}); - screen.renderCursor(renderer, rect, cursorPos.x(), cursorPos.y()); - break; + switch (cursorStyle) { + case CursorStyle::Beam: + renderer.fillRect( + sdl::Rect{static_cast(cellWidth * cursorPos.x()), + static_cast(cellHeight * cursorPos.y()), + 1, + static_cast(cellHeight)}); + break; + default: + // renderer.fillRect( + // sdl::Rect{static_cast(cellWidth * + // cursorPos.x()), + // static_cast(cellHeight * + // cursorPos.y()), + // static_cast(cellWidth), + // static_cast(cellHeight)}); + screen.renderCursor( + renderer, rect, cursorPos.x(), cursorPos.y()); + break; + } } - renderer.present(); + { + auto d = ProfileDuration{"Present"}; + renderer.present(); + } } size_t addStyle(const Color &fg, const Color &bg, size_t index) { @@ -418,6 +433,8 @@ struct GuiScreen::Buffer { } }(); + auto duration = ProfileDuration{}; + if (!e) { return NullEvent{}; } diff --git a/src/screen/ncursesscreen.cpp b/src/screen/ncursesscreen.cpp index b7a2bcac..2702333c 100644 --- a/src/screen/ncursesscreen.cpp +++ b/src/screen/ncursesscreen.cpp @@ -1,3 +1,4 @@ +#include "core/profiler.h" #include "core/threadname.h" #ifndef __EMSCRIPTEN__ #include "ncursesscreen.h" @@ -61,6 +62,7 @@ void reducedPalette() { } // namespace void NCursesScreen::init() { + PROFILE_FUNCTION(); ::initscr(); _tv.reset(); @@ -92,6 +94,7 @@ void NCursesScreen::init() { } void NCursesScreen::draw(size_t x, size_t y, FStringView rstr) { + PROFILE_FUNCTION(); auto str = rstr; _threadQueue.push_back([str, this, x, y] { _tv(); @@ -113,6 +116,7 @@ void NCursesScreen::draw(size_t x, size_t y, FStringView rstr) { } void NCursesScreen::refresh() { + PROFILE_FUNCTION(); _threadQueue.push_back([this] { _tv(); ::refresh(); @@ -120,6 +124,7 @@ void NCursesScreen::refresh() { } void NCursesScreen::clear() { + PROFILE_FUNCTION(); _threadQueue.push_back([this] { _tv(); ::clear(); @@ -127,6 +132,7 @@ void NCursesScreen::clear() { } void NCursesScreen::cursor(size_t x, size_t y) { + PROFILE_FUNCTION(); _threadQueue.push_back([this, x, y] { _tv(); ::move(y, x); @@ -140,6 +146,7 @@ NCursesScreen::NCursesScreen() _isRunning = true; loop(); }) { + PROFILE_FUNCTION(); using namespace std::literals; @@ -159,6 +166,7 @@ NCursesScreen::~NCursesScreen() { } void NCursesScreen::subscribe(CallbackT f) { + PROFILE_FUNCTION(); _callback = f; auto r = ResizeEvent(); @@ -168,6 +176,7 @@ void NCursesScreen::subscribe(CallbackT f) { } Event NCursesScreen::getInput() { + PROFILE_FUNCTION(); _tv(); const auto c = getch(); if (c == ERR) { @@ -248,6 +257,7 @@ void NCursesScreen::title(std::string title) { } void NCursesScreen::palette(const Palette &palette) { + PROFILE_FUNCTION(); _palette = palette; _threadQueue.push_back([this] { _tv(); @@ -256,12 +266,14 @@ void NCursesScreen::palette(const Palette &palette) { } void NCursesScreen::cursorStyle(CursorStyle style) { + PROFILE_FUNCTION(); if (_currentCursor != style) { // Not implemented } } size_t NCursesScreen::addStyle(const Color &fg, const Color &bg, size_t index) { + PROFILE_FUNCTION(); _tv(); if (!_hasColors) { return 1; @@ -293,6 +305,7 @@ size_t NCursesScreen::addStyle(const Color &fg, const Color &bg, size_t index) { } void NCursesScreen::loop() { + PROFILE_FUNCTION(); using namespace std::literals; for (; _isRunning;) { diff --git a/src/screen/serializescreen.cpp b/src/screen/serializescreen.cpp index 4246c992..b81510eb 100644 --- a/src/screen/serializescreen.cpp +++ b/src/screen/serializescreen.cpp @@ -1,6 +1,7 @@ #include "serializescreen.h" #include "core/inarchive.h" #include "core/outarchive.h" +#include "core/profiler.h" #include "syntax/palette.h" #include #include @@ -17,6 +18,7 @@ SerializeScreen::~SerializeScreen() { } void SerializeScreen::draw(size_t x, size_t y, FStringView str) { + PROFILE_FUNCTION(); auto ss = std::ostringstream{}; { auto arch = OutArchive{ss}; @@ -29,6 +31,7 @@ void SerializeScreen::draw(size_t x, size_t y, FStringView str) { } void SerializeScreen::refresh() { + PROFILE_FUNCTION(); auto ss = std::ostringstream{}; { auto arch = OutArchive{ss}; @@ -38,6 +41,7 @@ void SerializeScreen::refresh() { } void SerializeScreen::clear() { + PROFILE_FUNCTION(); auto ss = std::ostringstream{}; { auto arch = OutArchive{ss}; @@ -47,6 +51,7 @@ void SerializeScreen::clear() { } void SerializeScreen::cursor(size_t x, size_t y) { + PROFILE_FUNCTION(); auto ss = std::ostringstream{}; { auto arch = OutArchive{ss}; @@ -58,6 +63,7 @@ void SerializeScreen::cursor(size_t x, size_t y) { } void SerializeScreen::title(std::string title) { + PROFILE_FUNCTION(); auto ss = std::ostringstream{}; { auto arch = OutArchive{ss}; @@ -68,6 +74,7 @@ void SerializeScreen::title(std::string title) { } void SerializeScreen::palette(const Palette &palette) { + PROFILE_FUNCTION(); auto ss = std::ostringstream{}; { auto arch = OutArchive{ss}; @@ -80,6 +87,7 @@ void SerializeScreen::palette(const Palette &palette) { size_t SerializeScreen::addStyle(const Color &foreground, const Color &background, size_t index) { + PROFILE_FUNCTION(); auto ss = std::ostringstream{}; { auto arch = OutArchive{ss}; @@ -96,6 +104,7 @@ size_t SerializeScreen::addStyle(const Color &foreground, } void SerializeScreen::cursorStyle(CursorStyle style) { + PROFILE_FUNCTION(); auto ss = std::ostringstream{}; { auto arch = OutArchive{ss}; @@ -114,10 +123,12 @@ void SerializeScreen::unsubscribe() { } std::string SerializeScreen::clipboardData() { + PROFILE_FUNCTION(); return this->request("get/clipboard"); } void SerializeScreen::clipboardData(std::string text) { + PROFILE_FUNCTION(); auto ss = std::ostringstream{}; { auto arch = OutArchive{ss}; @@ -128,10 +139,12 @@ void SerializeScreen::clipboardData(std::string text) { } void SerializeScreen::send(std::string_view str) { + PROFILE_FUNCTION(); _connection->write(str); } std::string SerializeScreen::request(std::string_view method) { + PROFILE_FUNCTION(); auto id = ++_currentRequest; { auto ss = std::ostringstream{}; @@ -164,6 +177,7 @@ std::string SerializeScreen::request(std::string_view method) { // void SerializeScreen::receive(const nlohmann::json &json) { // void SerializeScreen::receive(Archive &arch) { void SerializeScreen::receive(std::string_view str) { + PROFILE_FUNCTION(); auto ss = std::istringstream{std::string{str}}; auto arch = InArchive{ss}; diff --git a/src/settings.h b/src/settings.h index f930d469..ae75d16d 100644 --- a/src/settings.h +++ b/src/settings.h @@ -103,9 +103,14 @@ medit -[flags] [file] std::exit(0); } else { - if (arg.rfind("-") != 0) { + if (arg.rfind("-", 0) != 0) { file = args.at(i); } + else { + std::cerr << helpStr << "\n"; + std::cerr << "invalid argument " << arg << "\n"; + std::exit(1); + } } } }