Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 72 additions & 2 deletions src/ui/http_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include <windows.h>
#include <process.h>
#include <psapi.h> /* GetProcessMemoryInfo */
#include <tlhelp32.h> /* CreateToolhelp32Snapshot, Process32First/Next */
#else
#include <sys/stat.h>
#include <unistd.h>
Expand Down Expand Up @@ -501,7 +502,7 @@ static void handle_processes(cbm_http_conn_t *c) {
int pos = 0;

#ifdef _WIN32
/* Windows: GetProcessMemoryInfo + GetProcessTimes */
/* Windows: GetProcessMemoryInfo + GetProcessTimes for the current process */
PROCESS_MEMORY_COUNTERS pmc;
FILETIME ft_create, ft_exit, ft_kernel, ft_user;
double user_s = 0, sys_s = 0;
Expand All @@ -519,8 +520,77 @@ static void handle_processes(cbm_http_conn_t *c) {
}
http_appendf(buf, sizeof(buf), &pos,
"{\"self_pid\":%d,\"self_rss_mb\":%.1f,"
"\"self_user_cpu_s\":%.1f,\"self_sys_cpu_s\":%.1f,\"processes\":[]}",
"\"self_user_cpu_s\":%.1f,\"self_sys_cpu_s\":%.1f,\"processes\":[",
(int)_getpid(), (double)rss_bytes / (1024.0 * 1024.0), user_s, sys_s);

/* Enumerate all codebase-memory-mcp.exe processes via toolhelp snapshot */
int proc_count = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap != INVALID_HANDLE_VALUE) {
PROCESSENTRY32 pe;
pe.dwSize = sizeof(pe);
for (BOOL ok = Process32First(hSnap, &pe); ok; ok = Process32Next(hSnap, &pe)) {
if (_stricmp(pe.szExeFile, "codebase-memory-mcp.exe") == 0) {
HANDLE hProc = OpenProcess(
PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, pe.th32ProcessID);
if (hProc) {
PROCESS_MEMORY_COUNTERS ppmc;
FILETIME ftc, fte, ftk, ftu;
double cpu_user = 0, cpu_sys = 0;
size_t proc_rss = 0;

if (GetProcessMemoryInfo(hProc, &ppmc, sizeof(ppmc)))
proc_rss = ppmc.WorkingSetSize;

if (GetProcessTimes(hProc, &ftc, &fte, &ftk, &ftu)) {
ULARGE_INTEGER pu, pk;
pu.LowPart = ftu.dwLowDateTime;
pu.HighPart = ftu.dwHighDateTime;
pk.LowPart = ftk.dwLowDateTime;
pk.HighPart = ftk.dwHighDateTime;
cpu_user = (double)pu.QuadPart / 1e7;
cpu_sys = (double)pk.QuadPart / 1e7;
}

/* Elapsed time since process creation */
FILETIME now_ft;
GetSystemTimeAsFileTime(&now_ft);
ULARGE_INTEGER now_uli, start_uli;
now_uli.LowPart = now_ft.dwLowDateTime;
now_uli.HighPart = now_ft.dwHighDateTime;
start_uli.LowPart = ftc.dwLowDateTime;
start_uli.HighPart = ftc.dwHighDateTime;
ULONGLONG elapsed_100ns = now_uli.QuadPart - start_uli.QuadPart;
DWORD elapsed_sec = (DWORD)(elapsed_100ns / 10000000ULL);

if (proc_count > 0)
buf[pos++] = ',';
http_appendf(buf, sizeof(buf), &pos,
"{\"pid\":%lu,\"cpu\":%.1f,\"rss_mb\":%.1f,"
"\"elapsed\":\"%lu-%02lu:%02lu:%02lu\","
"\"command\":\"codebase-memory-mcp\","
"\"is_self\":%s}",
pe.th32ProcessID, cpu_user + cpu_sys,
(double)proc_rss / (1024.0 * 1024.0),
elapsed_sec / 86400,
(elapsed_sec % 86400) / 3600,
(elapsed_sec % 3600) / 60,
elapsed_sec % 60,
pe.th32ProcessID == (DWORD)_getpid()
? "true" : "false");
if (pos >= (int)sizeof(buf)) {
pos = (int)sizeof(buf) - 1;
}
proc_count++;
CloseHandle(hProc);
}
}
}
CloseHandle(hSnap);
}

http_appendf(buf, sizeof(buf), &pos, "]}");
#else
struct rusage ru;
getrusage(RUSAGE_SELF, &ru);
Expand Down
Loading