rusage and pthreads
Hi, I'm trying to figure out the interactions between rusage and pthreads. Peeking around in the kernel (7.2) I see updates occurring in various places. kern_clock.c, for instance, appears to increment the memory occupancy (*rss) counters. This would make it appear that every thread gets part of the count, but also that only the process that happens to have the CPU at that moment gets its count updated, even if it holds the memory. Am I misreading this? And the context switch counters also appear to be updated per-thread, but in mi_switch(), in kern_synch.c. Is this true? If the answer is yes, it's per-thread, then how does a process report its usages without putting the requisite code in each thread, along with the machinery to divert from whatever the thread is doing (even waiting on I/O) to get the report at (nearly) the same time in all threads? Is there a big design hole here? Mark Terribile ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: rusage and pthreads
On Jan 18, 2011, at 4:07 PM, Mark Terribile wrote: I'm trying to figure out the interactions between rusage and pthreads. There largely isn't any-- struct rusage is per-process, not per thread. Peeking around in the kernel (7.2) I see updates occurring in various places. kern_clock.c, for instance, appears to increment the memory occupancy (*rss) counters. This would make it appear that every thread gets part of the count, but also that only the process that happens to have the CPU at that moment gets its count updated, even if it holds the memory. Am I misreading this? Nope. statclock() is fired off periodically (with some fuzz, to avoid clever games by processes trying to avoid being sampled) to update the stats for the currently running process. And the context switch counters also appear to be updated per-thread, but in mi_switch(), in kern_synch.c. Is this true? Probably. If the answer is yes, it's per-thread, then how does a process report its usages without putting the requisite code in each thread, along with the machinery to divert from whatever the thread is doing (even waiting on I/O) to get the report at (nearly) the same time in all threads? The process doesn't have userland threads updating this information. The kernel keeps track of it, and it updates the information periodically when the scheduler does context switches, when statclock() fires off, when disk I/O completes, etc. Regards, -- -Chuck ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: rusage and pthreads
Chuck, I'm trying to figure out the interactions between rusage and pthreads. There largely isn't any-- struct rusage is per-process, not per thread. Peeking around in the kernel (7.2) I see updates occurring in various places. kern_clock.c, for instance, appears to increment the memory occupancy (*rss) counters. This would make it appear that every thread gets part of the count, but also that only the process that happens to have the CPU at that moment gets its count updated, even if it holds the memory. Am I misreading this? Nope. statclock() is fired off periodically (with some fuzz, to avoid clever games by processes trying to avoid being sampled) to update the stats for the currently running process. And the context switch counters also appear to be updated per-thread, but in mi_switch(), in kern_synch.c. Is this true? Probably. If the answer is yes, it's per-thread, then how does a process report its usages without putting the requisite code in each thread, along with the machinery to divert from whatever the thread is doing (even waiting on I/O) to get the report at (nearly) the same time in all threads? The process doesn't have userland threads updating this information. The kernel keeps track of it, and it updates the information periodically when the scheduler does context switches, when statclock() fires off, when disk I/O completes, etc. I'm looking at kern_clock.c::statclock(int usermode) The code in question begins struct rusage* ru; struct vmspace* vm; struct thread *td; struct proc *p; ... td = curthread; p = td-td_proc; and continues further down ru = td-td_ru; ru-ru_ixrss += pgtok(vm-vm_tsize); ru-ru_idrss += pgtok(vm-vm_dsize); ru-ru_isrss += pgtok(vm-vm_ssize); This looks to me like it's accumulating the data in per-thread counters. What's more, it's consistent with what I'm seeing on the user side. Note that this is 7.2; if 8.x behaves differently I'd like to know. Mark Terribile ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: rusage and pthreads
Chuck, I forgot to add: Nope. statclock() is fired off periodically (with some fuzz, to avoid clever games by processes trying to avoid being sampled) to update the stats for the currently running process. Which would mean that a process that is occupying memory but doesn't happen to be running on that clock tick doesn't have its memory counted toward the total ... right? Mark ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: rusage and pthreads
On Jan 18, 2011, at 5:01 PM, Mark Terribile wrote: and continues further down ru = td-td_ru; ru-ru_ixrss += pgtok(vm-vm_tsize); ru-ru_idrss += pgtok(vm-vm_dsize); ru-ru_isrss += pgtok(vm-vm_ssize); This looks to me like it's accumulating the data in per-thread counters. What's more, it's consistent with what I'm seeing on the user side. Note that this is 7.2; if 8.x behaves differently I'd like to know. I wonder if all of the threads in a process might be pointing to the same struct rusage? Nope, checking kern/kern_resource.c kern_getrusage(), there is a per-proc struct rusage_ext which gets the sum of the per-thread td-td_ru counters via rufetch() / ruxagg()...so you're right that the counters are now per-thread. Which would mean that a process that is occupying memory but doesn't happen to be running on that clock tick doesn't have its memory counted toward the total ... right? That's right. Regards, -- -Chuck ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org