I'm trying to implement a syscall which allows me to get the number of threads for the current process. I am new to the Linux kernel, and so my understanding of it is limited.
Currently, I am trying to iterate through all the task_structs, and compare their thread group leader's PID with the current thread group leader's PID:
// ...
int nthreads = 0;
struct task_struct *task_it;
for_each_process(task_it) {
if (task_it->group_leader->pid == current->group_leader->pid) {
nthreads++;
}
}
// ...
However, this doesn't seem to be working (a quick test spawning some pthreads is still giving 1. What about the group_leader is common to all threads in the same process?
The problem with your code is that what the kernel calls a PID (the pid field of task_struct) is what userspace calls a TID (ie. it's what's returned by sys_gettid() and is unique per thread). What userspace calls a PID is called a TGID in the kernel (for "task group ID") - that's what the sys_getpid() syscall returns.
You don't need to actually check the TGID, though - just comparing the struct task_struct * pointers is enough:
if (task_it->group_leader == current->group_leader) {
By the way, you could just iterate over the thread_group list that current is a member of (with while_each_thread()), then you wouldn't need any test at all. Or even better, just use get_nr_threads(current).
Note that all methods that loop over the task lists need to be wrapped in rcu_read_lock(); / rcu_read_unlock(); to be correct.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With