[newlib-cygwin] Cygwin: proc: Provides correct number of thread rather than 0

Takashi Yano tyan0@sourceware.org
Sun Sep 6 11:16:36 GMT 2026


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=9756b333189bdd1dfd4889d0f784d568732b1d94

commit 9756b333189bdd1dfd4889d0f784d568732b1d94
Author: Takashi Yano <takashi.yano@nifty.ne.jp>
Date:   Fri Sep 4 09:47:50 2026 +0900

    Cygwin: proc: Provides correct number of thread rather than 0
    
    Currently, /proc/<pid>/stat always reports 0 as the number of thread.
    However, get_process_state() does know the thread count for the
    process, so expose that value in /proc/<pid>/stat. Additionally, add
    a "Threads:" entry to /proc/<pid>/status.
    
    Fixes: 9ba913a56dd6 ("* fhandler_proc.cc (proc_listing_array): Add 'loadavg', 'meminfo', and 'stat'.")
    Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
    Reviewed-by: Mark Geisert <mark@maxrnd.com>

Diff:
---
 winsup/cygwin/fhandler/proc.cc    |  4 ++--
 winsup/cygwin/fhandler/process.cc | 18 ++++++++++++------
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/winsup/cygwin/fhandler/proc.cc b/winsup/cygwin/fhandler/proc.cc
index af3cfdb16..9227631db 100644
--- a/winsup/cygwin/fhandler/proc.cc
+++ b/winsup/cygwin/fhandler/proc.cc
@@ -437,12 +437,12 @@ format_proc_version (void *, char *&destbuf)
 static off_t
 format_proc_loadavg (void *, char *&destbuf)
 {
-  extern int get_process_state (DWORD dwProcessId);
+  extern int get_process_state (DWORD dwProcessId, DWORD *num_threads);
   unsigned int running = 0;
   winpids pids ((DWORD) 0);
 
   for (unsigned i = 0; i < pids.npids; i++)
-    switch (get_process_state (pids[i]->dwProcessId)) {
+    switch (get_process_state (pids[i]->dwProcessId, NULL)) {
       case 'O':
       case 'R':
 	running++;
diff --git a/winsup/cygwin/fhandler/process.cc b/winsup/cygwin/fhandler/process.cc
index e00cae58d..537a4b370 100644
--- a/winsup/cygwin/fhandler/process.cc
+++ b/winsup/cygwin/fhandler/process.cc
@@ -81,7 +81,7 @@ static const virt_tab_t process_tab[] =
 
 static const int PROCESS_LINK_COUNT =
   (sizeof (process_tab) / sizeof (virt_tab_t)) - 1;
-int get_process_state (DWORD dwProcessId);
+int get_process_state (DWORD dwProcessId, DWORD *num_threads);
 static bool get_mem_values (DWORD dwProcessId, size_t &vmsize, size_t &vmrss,
 			    size_t &vmtext, size_t &vmdata, size_t &vmlib,
 			    size_t &vmshare);
@@ -1121,6 +1121,7 @@ format_process_stat (void *data, char *&destbuf)
 {
   _pinfo *p = (_pinfo *) data;
   char cmd[NAME_MAX + 1];
+  DWORD num_threads = 0;
   int state = 'R';
   unsigned long fault_count = 0UL,
 		vmsize = 0UL, vmrss = 0UL, vmmaxrss = 0UL;
@@ -1155,7 +1156,7 @@ format_process_stat (void *data, char *&destbuf)
   else if (p->process_state & PID_STOPPED)
     state = 'T';
   else
-    state = get_process_state (p->dwProcessId);
+    state = get_process_state (p->dwProcessId, &num_threads);
 
   int nice = 0, prio = 0;
 
@@ -1241,14 +1242,14 @@ format_process_stat (void *data, char *&destbuf)
 				   "%d %d %d %d "
 				   "%d %u %lu %lu %u %u "
 				   "%U %U %U %U "
-				   "%d %d %d %d "
+				   "%d %d %u %d "
 				   "%U "
 				   "%lu %ld %lu\n",
 			  p->pid, cmd, state,
 			  p->ppid, p->pgid, p->sid, tty_nr,
 			  -1, 0, fault_count, fault_count, 0, 0,
 			  utime, stime, utime, stime,
-			  prio, nice, 0, 0,
+			  prio, nice, num_threads, 0,
 			  start_time,
 			  vmsize, vmrss, vmmaxrss
 			  );
@@ -1259,6 +1260,7 @@ format_process_status (void *data, char *&destbuf)
 {
   _pinfo *p = (_pinfo *) data;
   char cmd[NAME_MAX + 1];
+  DWORD num_threads = 0;
   int state = 'R';
   const char *state_str = "unknown";
   size_t vmsize = 0, vmrss = 0, vmdata = 0, vmlib = 0, vmtext = 0, vmshare = 0;
@@ -1281,7 +1283,7 @@ format_process_status (void *data, char *&destbuf)
   else if (p->process_state & PID_STOPPED)
     state = 'T';
   else
-    state = get_process_state (p->dwProcessId);
+    state = get_process_state (p->dwProcessId, &num_threads);
   switch (state)
     {
     case 'O':
@@ -1327,6 +1329,7 @@ format_process_status (void *data, char *&destbuf)
 				   "VmStk:\t%8lu kB\n"
 				   "VmExe:\t%8lu kB\n"
 				   "VmLib:\t%8lu kB\n"
+				   "Threads:\t%u\n"
 				   "SigPnd:\t%016lx\n"
 				   "SigBlk:\t%016lx\n"
 				   "SigIgn:\t%016lx\n",
@@ -1340,6 +1343,7 @@ format_process_status (void *data, char *&destbuf)
 			  vmsize * kb_per_page, 0UL, vmrss * kb_per_page,
 			  vmdata * kb_per_page, 0UL, vmtext * kb_per_page,
 			  vmlib * kb_per_page,
+			  num_threads,
 			  pnd, blk, ign
 			  );
 }
@@ -1516,7 +1520,7 @@ format_process_mountinfo (void *data, char *&destbuf)
 }
 
 int
-get_process_state (DWORD dwProcessId)
+get_process_state (DWORD dwProcessId, DWORD *num_threads)
 {
   /* This isn't really heavy magic - just go through the processes' threads
      one by one and return a value accordingly.  Errors are silently ignored. */
@@ -1554,6 +1558,8 @@ get_process_state (DWORD dwProcessId)
 	{
 	  SYSTEM_THREADS *st;
 	  st = &sp->Threads[0];
+	  if (num_threads)
+	    *num_threads = sp->NumberOfThreads;
 	  state = 'S';
 	  for (unsigned i = 0; i < sp->NumberOfThreads; i++)
 	    {


More information about the Cygwin-cvs mailing list