[PATCH] Cygwin: proc: Provides correct number of thread rather than 0
Takashi Yano
takashi.yano@nifty.ne.jp
Fri Sep 4 01:24:44 GMT 2026
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.
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
Reviewed-by:
---
winsup/cygwin/fhandler/proc.cc | 4 ++--
winsup/cygwin/fhandler/process.cc | 18 ++++++++++++------
winsup/cygwin/release/3.7.0 | 3 +++
3 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/winsup/cygwin/fhandler/proc.cc b/winsup/cygwin/fhandler/proc.cc
index f1cd468fc..12a43afe2 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++)
{
diff --git a/winsup/cygwin/release/3.7.0 b/winsup/cygwin/release/3.7.0
index 3f6a0ecd7..831c8d189 100644
--- a/winsup/cygwin/release/3.7.0
+++ b/winsup/cygwin/release/3.7.0
@@ -26,6 +26,9 @@ What's new:
runs on a pty rather than on the console device originating from the pseudo
console.
+- Expose the number of threads in the process in /proc/<pid>/stat and
+ /proc/<pid>/status.
+
Fixes:
------
--
2.51.0
More information about the Cygwin-patches
mailing list