summaryrefslogtreecommitdiff
path: root/src/shell_manager.cc
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2015-11-21 12:11:19 +0000
committerMaxime Coste <frrrwww@gmail.com>2015-11-21 12:11:19 +0000
commita8d2c93ac8f87845c981db23c61c8bf47e672709 (patch)
tree7781119ec827e5c55011c4a66c3760c33000488c /src/shell_manager.cc
parent9fe19fa72efb89a1fd09de4ca39c87ff66506804 (diff)
Add a profiling debug flag to get timings for hooks/shell eval
Diffstat (limited to 'src/shell_manager.cc')
-rw-r--r--src/shell_manager.cc25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/shell_manager.cc b/src/shell_manager.cc
index f23725a1..861b9a63 100644
--- a/src/shell_manager.cc
+++ b/src/shell_manager.cc
@@ -5,6 +5,8 @@
#include "event_manager.hh"
#include "file.hh"
+#include <chrono>
+
#include <cstring>
#include <sys/types.h>
#include <sys/wait.h>
@@ -87,9 +89,16 @@ std::pair<String, int> ShellManager::eval(
{
static const Regex re(R"(\bkak_(\w+)\b)");
- if (context.options()["debug"].get<DebugFlags>() & DebugFlags::Shell)
+ using Clock = std::chrono::steady_clock;
+ using TimePoint = Clock::time_point;
+
+ const DebugFlags debug_flags = context.options()["debug"].get<DebugFlags>();
+ const bool profile = debug_flags & DebugFlags::Profile;
+ if (debug_flags & DebugFlags::Shell)
write_to_debug_buffer(format("shell:\n{}\n----\n", cmdline));
+ auto start_time = profile ? Clock::now() : TimePoint{};
+
Vector<String> kak_env;
for (RegexIterator<const char*> it{cmdline.begin(), cmdline.end(), re}, end;
it != end; ++it)
@@ -113,6 +122,8 @@ std::pair<String, int> ShellManager::eval(
} catch (runtime_error&) {}
}
+ auto spawn_time = profile ? Clock::now() : TimePoint{};
+
Pipe child_stdin, child_stdout, child_stderr;
pid_t pid = spawn_process(cmdline, shell_context.params, kak_env,
child_stdin, child_stdout, child_stderr);
@@ -124,6 +135,8 @@ std::pair<String, int> ShellManager::eval(
write(child_stdin.write_fd(), input.data(), (int)input.length());
child_stdin.close_write_fd();
+ auto wait_time = profile ? Clock::now() : TimePoint{};
+
struct PipeReader : FDWatcher
{
PipeReader(Pipe& pipe, String& contents)
@@ -170,6 +183,16 @@ std::pair<String, int> ShellManager::eval(
if (not stderr_contents.empty())
write_to_debug_buffer(format("shell stderr: <<<\n{}>>>", stderr_contents));
+ if (profile)
+ {
+ TimePoint end_time = Clock::now();
+ auto full = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
+ auto spawn = std::chrono::duration_cast<std::chrono::milliseconds>(wait_time - spawn_time);
+ auto wait = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - wait_time);
+ write_to_debug_buffer(format("shell execution took {} ms (spawn: {}, wait: {})",
+ (size_t)full.count(), (size_t)spawn.count(), (size_t)wait.count()));
+ }
+
return { stdout_contents, WIFEXITED(status) ? WEXITSTATUS(status) : -1 };
}