feat: request_perf() worker-side timing hostcall; restore demo System Info

Units run in the wasm sandbox, so my_pid/parent_pid/context.server->request_count
read as sandbox stubs — the demo System Info counters were broken, and there was
no authoritative server-side request timing available to unit code (client-side
measurement cannot see queue/dispatch latency).

Add a request_perf() unit API backed by a new uce_host_request_perf hostcall.
The native worker answers it live, returning a DValue:
  worker_pid, parent_pid, request_count,
  accept_us  = (time_start - time_init)*1e6   (entry -> dispatch wait),
  running_us = (now - time_start)*1e6         (since dispatch, live),
  total_us   = (now - time_init)*1e6          (since the request entered UCE),
  workspace_birth_us.
time_init is captured at request entry (handle_request, with a handle_complete
fallback); a RequestPerfSnapshot {pids, request_count, time_init, time_start} is
threaded from wasm_backend_serve through wasm_worker_serve onto the workspace,
and the hostcall computes the live deltas at call time. Wired like uce_host_units
(sized DValue hostcall): core_hostcalls.syms + sys.cpp/sys.h request_perf().

site/demo/index.uce System Info now uses request_perf() and shows the real worker
PID, an incrementing per-worker request count, and the timing counters.

Implemented via the pi agent (gpt-5.3-codex-spark); a review of the live numbers
caught accept_us mistakenly computed as (now - time_init) (== total_us), fixed to
the dispatch wait (time_start - time_init). Independently verified on the host:
System Info shows non-zero PIDs, incrementing count, accept_us ~50us << total_us
~2.4ms with accept+running==total; run_cli_tests --include-wasm-kill => 87 passed,
0 failed, 0 skipped.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
root
2026-06-15 08:18:04 +00:00
co-authored by Claude Opus 4.8
parent 83ab9e10f7
commit 4f84ac544d
7 changed files with 94 additions and 15 deletions
+17
View File
@@ -33,6 +33,7 @@ int uce_host_server_start_http(const char* key, size_t key_len, const char* bind
int uce_host_server_stop(const char* key, size_t key_len);
size_t uce_host_memcache_command(uint64_t sockfd, const char* command, size_t command_len, char* buf, size_t cap);
size_t uce_host_mysql(const char* in, size_t in_len, char* out, size_t cap);
size_t uce_host_request_perf(const char* in, size_t in_len, char* out, size_t cap);
}
static String wasm_current_unit_file()
@@ -117,6 +118,22 @@ bool config_map_bool(StringMap& cfg, String key, bool fallback) { return(config_
u64 config_u64(String key, u64 fallback) { return(context ? config_map_u64(context->server->config, key, fallback) : fallback); }
f64 config_f64(String key, f64 fallback) { return(context ? config_map_f64(context->server->config, key, fallback) : fallback); }
bool config_bool(String key, bool fallback) { return(context ? config_map_bool(context->server->config, key, fallback) : fallback); }
DValue request_perf()
{
size_t required = uce_host_request_perf("", 0, 0, 0);
if(required == 0)
return(DValue());
String encoded_response(required, 0);
size_t got = uce_host_request_perf("", 0, &encoded_response[0], required);
if(got == 0 || got > required)
return(DValue());
DValue response;
String decode_error;
if(ucb_decode(encoded_response, response, &decode_error))
return(response);
return(DValue());
}
f64 time_precise() { return(uce_host_time_precise()); }
u64 time() { return(uce_host_time()); }
// The native build shells out to `date`; the wasm core has no shell, so it