Determine Process Info Programmatically in Darwin/OSX
I have a class with the following member functions:
/// caller pid
virtual pid_t Pid() const = 0;
/// physical memory size in KB
virtual uint64_t Size() const = 0;
/// resident memory for this process
virtual uint64_t Rss() const = 0;
/// cpu used by this process
virtual double PercentCpu() const = 0;
/// memory used by this process
virtual double PercentMemory() const = 0;
/// number of threads in this process
virtual int32_t Lwps() const = 0;
This class' duty is to return process information about caller. Physical memory size can easily determined by a sysctl call, and pid is trivial, but the remaining calls have eluded me, aside from invoking a popen on ps or top and parsing the output - which isn't acceptable. Any help would be greatly appreciated.
Requirements:
Compiles on g++ 4.0
No obj-c
OSX 10.5
Solution 1:
Process info comes from pidinfo
:
cristi:~ diciu$ grep proc_pidinfo /usr/include/libproc.h
int proc_pidinfo(int pid, int flavor, uint64_t arg, void *buffer, int buffersize);
cpu load comes from host_statistics
:
cristi:~ diciu$ grep -r host_statistics /usr/include/
/usr/include/mach/host_info.h:/* host_statistics() */
/usr/include/mach/mach_host.defs:routine host_statistics(
/usr/include/mach/mach_host.h:/* Routine host_statistics */
/usr/include/mach/mach_host.h:kern_return_t host_statistics
For more details, check out sources for top
and lsof
, they are open source (you need to register as an Apple developer but that's free of charge):
https://opensource.apple.com/source/top/top-111.20.1/libtop.c.auto.html
Later edit: All these interfaces are version specific, so you need to take that into account when writing production code (libproc.h):
/*
* This header file contains private interfaces to obtain process information.
* These interfaces are subject to change in future releases.
*/
Solution 2:
Since you say no Objective-C we'll rule out most of the MacOS frameworks.
You can get CPU time using getrusage(), which gives the total amount of User and System CPU time charged to your process. To get a CPU percentage you'd need to snapshot the getrusage values once per second (or however granular you want to be).
#include <sys/resource.h>
struct rusage r_usage;
if (getrusage(RUSAGE_SELF, &r_usage)) {
/* ... error handling ... */
}
printf("Total User CPU = %ld.%ld\n",
r_usage.ru_utime.tv_sec,
r_usage.ru_utime.tv_usec);
printf("Total System CPU = %ld.%ld\n",
r_usage.ru_stime.tv_sec,
r_usage.ru_stime.tv_usec);
There is an RSS field in the getrusage structure, but is appears to always be zero in MacOS X 10.5. Michael Knight wrote a blog post several years ago about how to determine the RSS.
Solution 3:
I think most of these values are available in the Mach API, but it's been a while since I've poked around in there. Alternatively, you could just look at the source code for the "ps" or "top" commands, and see how they do it.