Profile request thread runtime on demand
This commit is contained in:
@@ -47,6 +47,8 @@
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sched.h>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <dirent.h>
|
||||
@@ -126,6 +128,7 @@ struct WasmWorkerConfig
|
||||
u64 epoch_deadline_ticks = 200; // ticker period × ticks = CPU budget
|
||||
u64 mysql_persistent_pool_size = 8;
|
||||
bool profile_hostcall_cpu = false;
|
||||
bool profile_thread_runtime = false;
|
||||
bool verbose = false;
|
||||
// uce_host_* names (bare, without the "uce_host_" prefix) the sysadmin has
|
||||
// disabled via UCE_HOSTCALL_BLOCKLIST. A blocked hostcall resolves to a trap
|
||||
@@ -1224,6 +1227,9 @@ public:
|
||||
f64 time_start = 0;
|
||||
f64 workspace_wall_start = 0;
|
||||
f64 workspace_cpu_start = 0;
|
||||
struct rusage thread_runtime_start = {};
|
||||
int thread_cpu_start = -1;
|
||||
bool thread_runtime_profiled = false;
|
||||
bool active = false;
|
||||
} request_perf;
|
||||
|
||||
@@ -2351,6 +2357,25 @@ private:
|
||||
response["hostcall_us"] = (f64)self->hostcall_total_us;
|
||||
response["hostcall_cpu_profiled"].set_bool(self->worker.cfg.profile_hostcall_cpu);
|
||||
response["hostcall_cpu_us"] = (f64)self->hostcall_cpu_total_us;
|
||||
struct rusage runtime_now = {};
|
||||
bool thread_runtime_profiled = self->request_perf.thread_runtime_profiled && getrusage(RUSAGE_THREAD, &runtime_now) == 0;
|
||||
response["thread_runtime_profiled"].set_bool(thread_runtime_profiled);
|
||||
if(thread_runtime_profiled)
|
||||
{
|
||||
auto timeval_us = [](const struct timeval& value) -> int64_t {
|
||||
return((int64_t)value.tv_sec * 1000000 + value.tv_usec);
|
||||
};
|
||||
int cpu_now = sched_getcpu();
|
||||
response["thread_user_cpu_us"] = (f64)std::max<int64_t>(0, timeval_us(runtime_now.ru_utime) - timeval_us(self->request_perf.thread_runtime_start.ru_utime));
|
||||
response["thread_system_cpu_us"] = (f64)std::max<int64_t>(0, timeval_us(runtime_now.ru_stime) - timeval_us(self->request_perf.thread_runtime_start.ru_stime));
|
||||
response["thread_voluntary_context_switches"] = (f64)std::max<int64_t>(0, runtime_now.ru_nvcsw - self->request_perf.thread_runtime_start.ru_nvcsw);
|
||||
response["thread_involuntary_context_switches"] = (f64)std::max<int64_t>(0, runtime_now.ru_nivcsw - self->request_perf.thread_runtime_start.ru_nivcsw);
|
||||
response["thread_minor_faults"] = (f64)std::max<int64_t>(0, runtime_now.ru_minflt - self->request_perf.thread_runtime_start.ru_minflt);
|
||||
response["thread_major_faults"] = (f64)std::max<int64_t>(0, runtime_now.ru_majflt - self->request_perf.thread_runtime_start.ru_majflt);
|
||||
response["thread_cpu_start"] = (f64)self->request_perf.thread_cpu_start;
|
||||
response["thread_cpu_end"] = (f64)cpu_now;
|
||||
response["thread_cpu_migrated"].set_bool(self->request_perf.thread_cpu_start >= 0 && cpu_now >= 0 && self->request_perf.thread_cpu_start != cpu_now);
|
||||
}
|
||||
std::vector<u64> invoked_hostcalls;
|
||||
for(u64 i = 0; i < self->hostcall_operation_slots; i++)
|
||||
if(self->hostcall_operation_counts[i] > 0)
|
||||
@@ -3504,6 +3529,9 @@ inline WasmResponse wasm_worker_serve(WasmWorker& worker, const DValue& context_
|
||||
f64 serve_started = time_precise();
|
||||
auto workspace_start = std::chrono::steady_clock::now();
|
||||
f64 cpu_started = wasm_thread_cpu_time();
|
||||
struct rusage thread_runtime_start = {};
|
||||
bool thread_runtime_profiled = request && worker.cfg.profile_thread_runtime && getrusage(RUSAGE_THREAD, &thread_runtime_start) == 0;
|
||||
int thread_cpu_start = thread_runtime_profiled ? sched_getcpu() : -1;
|
||||
WasmWorkspace workspace(worker);
|
||||
f64 setup_cpu_finished = wasm_thread_cpu_time();
|
||||
workspace.workspace_setup_us = (u64)std::chrono::duration_cast<std::chrono::microseconds>(
|
||||
@@ -3515,6 +3543,9 @@ inline WasmResponse wasm_worker_serve(WasmWorker& worker, const DValue& context_
|
||||
workspace.set_perf_snapshot(my_pid, (u64)parent_pid, request->server ? request->server->request_count : 0,
|
||||
request->stats.time_init, request->stats.time_params, request->stats.time_input, request->stats.time_start,
|
||||
serve_started, cpu_started);
|
||||
workspace.request_perf.thread_runtime_start = thread_runtime_start;
|
||||
workspace.request_perf.thread_cpu_start = thread_cpu_start;
|
||||
workspace.request_perf.thread_runtime_profiled = thread_runtime_profiled;
|
||||
if(request->stats.time_start > 0 && serve_started > request->stats.time_start)
|
||||
workspace.dispatch_us = (u64)((serve_started - request->stats.time_start) * 1000000.0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user