5454#include <windows.h>
5555#include <process.h>
5656#include <psapi.h> /* GetProcessMemoryInfo */
57+ #include <tlhelp32.h> /* CreateToolhelp32Snapshot, Process32First/Next */
5758#else
5859#include <sys/stat.h>
5960#include <unistd.h>
@@ -560,7 +561,7 @@ static void handle_processes(cbm_http_conn_t *c) {
560561 int pos = 0 ;
561562
562563#ifdef _WIN32
563- /* Windows: GetProcessMemoryInfo + GetProcessTimes */
564+ /* Windows: GetProcessMemoryInfo + GetProcessTimes for the current process */
564565 PROCESS_MEMORY_COUNTERS pmc ;
565566 FILETIME ft_create , ft_exit , ft_kernel , ft_user ;
566567 double user_s = 0 , sys_s = 0 ;
@@ -578,8 +579,81 @@ static void handle_processes(cbm_http_conn_t *c) {
578579 }
579580 http_appendf (buf , sizeof (buf ), & pos ,
580581 "{\"self_pid\":%d,\"self_rss_mb\":%.1f,"
581- "\"self_user_cpu_s\":%.1f,\"self_sys_cpu_s\":%.1f,\"processes\":[]} " ,
582+ "\"self_user_cpu_s\":%.1f,\"self_sys_cpu_s\":%.1f,\"processes\":[" ,
582583 (int )_getpid (), (double )rss_bytes / (1024.0 * 1024.0 ), user_s , sys_s );
584+
585+ /* Enumerate all codebase-memory-mcp.exe processes via toolhelp snapshot */
586+ int proc_count = 0 ;
587+ HANDLE hSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS , 0 );
588+ if (hSnap != INVALID_HANDLE_VALUE ) {
589+ PROCESSENTRY32 pe ;
590+ pe .dwSize = sizeof (pe );
591+ for (BOOL ok = Process32First (hSnap , & pe ); ok ; ok = Process32Next (hSnap , & pe )) {
592+ if (_stricmp (pe .szExeFile , "codebase-memory-mcp.exe" ) == 0 ) {
593+ HANDLE hProc = OpenProcess (
594+ PROCESS_QUERY_INFORMATION | PROCESS_VM_READ ,
595+ FALSE, pe .th32ProcessID );
596+ if (hProc ) {
597+ PROCESS_MEMORY_COUNTERS ppmc ;
598+ FILETIME ftc , fte , ftk , ftu ;
599+ double cpu_user = 0 , cpu_sys = 0 ;
600+ size_t proc_rss = 0 ;
601+ DWORD elapsed_sec = 0 ;
602+
603+ if (GetProcessMemoryInfo (hProc , & ppmc , sizeof (ppmc )))
604+ proc_rss = ppmc .WorkingSetSize ;
605+
606+ if (GetProcessTimes (hProc , & ftc , & fte , & ftk , & ftu )) {
607+ ULARGE_INTEGER pu , pk ;
608+ pu .LowPart = ftu .dwLowDateTime ;
609+ pu .HighPart = ftu .dwHighDateTime ;
610+ pk .LowPart = ftk .dwLowDateTime ;
611+ pk .HighPart = ftk .dwHighDateTime ;
612+ cpu_user = (double )pu .QuadPart / 1e7 ;
613+ cpu_sys = (double )pk .QuadPart / 1e7 ;
614+
615+ /* 进程创建以来的运行时间 */
616+ FILETIME now_ft ;
617+ GetSystemTimeAsFileTime (& now_ft );
618+ ULARGE_INTEGER now_uli , start_uli ;
619+ now_uli .LowPart = now_ft .dwLowDateTime ;
620+ now_uli .HighPart = now_ft .dwHighDateTime ;
621+ start_uli .LowPart = ftc .dwLowDateTime ;
622+ start_uli .HighPart = ftc .dwHighDateTime ;
623+ /* 时钟偏移保护:防止创建时间微偏未来导致 unsigned 下溢 */
624+ if (now_uli .QuadPart > start_uli .QuadPart ) {
625+ ULONGLONG elapsed_100ns = now_uli .QuadPart - start_uli .QuadPart ;
626+ elapsed_sec = (DWORD )(elapsed_100ns / 10000000ULL );
627+ }
628+ }
629+
630+ if (proc_count > 0 )
631+ buf [pos ++ ] = ',' ;
632+ http_appendf (buf , sizeof (buf ), & pos ,
633+ "{\"pid\":%lu,\"cpu\":%.1f,\"rss_mb\":%.1f,"
634+ "\"elapsed\":\"%lu-%02lu:%02lu:%02lu\","
635+ "\"command\":\"codebase-memory-mcp\","
636+ "\"is_self\":%s}" ,
637+ pe .th32ProcessID , cpu_user + cpu_sys ,
638+ (double )proc_rss / (1024.0 * 1024.0 ),
639+ elapsed_sec / 86400 ,
640+ (elapsed_sec % 86400 ) / 3600 ,
641+ (elapsed_sec % 3600 ) / 60 ,
642+ elapsed_sec % 60 ,
643+ pe .th32ProcessID == (DWORD )_getpid ()
644+ ? "true" : "false" );
645+ if (pos >= (int )sizeof (buf )) {
646+ pos = (int )sizeof (buf ) - 1 ;
647+ }
648+ proc_count ++ ;
649+ CloseHandle (hProc );
650+ }
651+ }
652+ }
653+ CloseHandle (hSnap );
654+ }
655+
656+ http_appendf (buf , sizeof (buf ), & pos , "]}" );
583657#else
584658 struct rusage ru ;
585659 getrusage (RUSAGE_SELF , & ru );
0 commit comments