-
-
Notifications
You must be signed in to change notification settings - Fork 330
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for total accumulated process CPU usage #1044
base: master
Are you sure you want to change the base?
Conversation
Most, if not all, CPU usage accounting for processes provides values that count from the creation of the process. This total value is useful for a variety of accounting tasks beyond the snapshot value that is currently available in sysinfo. This change adds a `fn total_cpu_usage` to `trait ProcessExt` to provide that value.
So for Windows, there is hope depending if there are queries to allow to get this information or not. For FreeBSD, might be more complicated depending if https://docs.rs/libc/latest/x86_64-unknown-freebsd/libc/struct.kinfo_proc.html has the information you need or not. Also one thing to check: are you sure that |
I believe those values are 64-bit counters in the kernel, and so won't reset for a large number of millennia. |
|
f17aae6
to
ae6505d
Compare
ae6505d
to
46b9b74
Compare
Would you like me to squash down some of the fixup commits? |
Hi, just to say I didn't forget about this PR. Still wondering if I want this feature or not. I don't have the need for it myself so it'd be complicated to find out when it's broken or to know what's to be expected when adding support for new platforms. |
FWIW I'm not the only user looking for this data (though that user would want other bits as well). |
I hear that, doesn't conflict the reasons I listed why I was hesitating. ;) |
79c0176
to
668c7f9
Compare
I saw this PR just now. Might I suggest that the API simply return the accumulated CPU use in seconds instead of a percentage? It should be easy enough to calculate a percentage from CPU-seconds, but the inverse would lose a lot of precision. If at all possible. Also, traditionally people like to see Reading the file changes I also cannot help but to note that skipping the percentage calculus would also make the changes smaller... 😀 |
That means we should likely provide an API to get CPU seconds as well separately in addition to getting total CPU percentage. Forcing both codes to exist would likely make it more clear, not sure.
I think it'd be better to not provide internals too much and just give the total time. Simpler to handle different OSes.
I think it's fine to keep it. Like I said above, keeping total CPU time on one side and total process time on the other will likely make things more clear (simpler I don't know). Anyway, @bruceg, after thinking about it for quite some time, I think having this feature is ok. What do you think about what @cederberg and I talked about? |
Sorry, I'm not entirely clear what "the API" being discussed references. The proposed method returns cumulative CPU seconds, so I think it's already doing what @cederberg is requesting. Am I misunderstanding? There is one way to reconcile the possible usages, though it is a breaking change. The method could return a new type that has methods to access both values. I don't believe there is a way to make the new type work like the |
In any case, I'd be happy to do whatever is needed to move the code forward to make it acceptable to all. |
I didn't double-check after reading:
but I should definitely have as you indeed don't return percentage but the total CPU seconds (in @cederberg: Does it look like what you want with this clarification? |
Right. I was confused by two things:
On another note, isn't the hard-coded |
src/freebsd/process.rs
Outdated
// from FreeBSD source /bin/ps/print.c | ||
let accum_cpu_usage = (kproc.ki_runtime as f64 / 1000000.0) as f32 | ||
+ kproc.ki_childtime.tv_sec as f32 | ||
+ kproc.ki_childtime.tv_usec as f32 / 1000000.0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is quite right. Here is the relevant code from FreeBSD:
secs = k->ki_p->ki_runtime / 1000000;
psecs = k->ki_p->ki_runtime % 1000000;
if (sumrusage) {
secs += k->ki_p->ki_childtime.tv_sec;
psecs += k->ki_p->ki_childtime.tv_usec;
}
It is clear that child time is only added if sumrusage
is true. It is set by the -S
switch:
-S Change the way the process times, namely cputime, systime, and
usertime, are calculated by summing all exited children to
their parent process.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, you're right, I thought this needed to account for the child's time, but that is handled separately.
Right, that confused me too, but that is essentially a copy of the calculations in
The relevant fields in |
Could I ask again why The source values are all integers. Floats are slow and prone to rounding errors. And if parts of a second is really of interest, we could just as well return milliseconds in a |
You are surely right, but what I'm after is a reference to |
I will defer to the judgement of @GuillaumeGomez on the correct type/units to use if he has an opinion. |
Ah, I had not seen that |
I'm seeing a bunch of tests failing on CI that I can't explain. In particular, this test on Ubuntu is failing now, but I haven't changed either the test or the code underlying it AFAICT. Any idea what might be going on? |
The
I was also surprised you used
About "Floats are slow", they are in fact not that slow. At same size, a float is always slower than an integer, however a smaller sized float is faster than an integer, so |
Agreed, I'm looking at them.
I used |
From what I can see, only FreeBSD seems to actually have a significant fractional part. We could keep using |
So, in the most recent commit, I added a
Note that some of this is applicable to the Linux side as well, but there we are only fetching the clock tick value through Edit: Technically there is a 5th option, which is to bump the MSRV to 1.70.0, but I figure that's a bridge too far given that it becomes a breaking change for some users. |
Next release will be a major one so it's definitely not a concern.
I had equivalent "static" info. For example in freebsd. I don't think using a static is a good tactic here. Why not creating a struct which query this information on initialization and then keep it around? If the object is destroyed/recreated, then we re-query the information, it's fine. In the documentation it's explicitly written that the |
I can set that up in the Edit: Handling the conversion in |
Hi, sorry forgot a bit about it. It seems like some test is failing on freebsd. Do you need help? |
Yes, I think I will. We opted to take another path to provide this value since we only need to support Linux and MacOS at this point, and so the motivating factor necessitating this change is effectively moot. We may come back to this if we ever need to support Windows, but that's a long ways down the road. |
Noted. I'll try to come back to this when I have enough time (hopefully in a few weeks...) then if you didn't before. |
Late to the party here. I'm definitely in team fn cpu_time(&self) -> u64; From what I can see the code otherwise looks right for all platforms, but I guess the PR might be out of sync slightly now. |
If you're interested into syncing the PR, I'm still interested into having this feature. |
Hello guys, as I understand after reading the messages, there is a function for getting utime and stime, which is not there yet. Is there any news on its creation? |
Most, if not all, CPU usage accounting for processes provides values that count from the creation of the process. This total value is useful for a variety of accounting tasks beyond the snapshot value that is currently available in sysinfo. This change adds a
fn total_cpu_usage
totrait ProcessExt
to provide that value.Note that this has explicit breaking stubs for the FreeBSD and Windows implementations, as I was unclear how best to implement those functions. I would be happy to fill those in to complete this PR but I would appreciate a little direction what the best implementation path is between storing a new field in
struct Process
or computing the value on-the-fly infn total_cpu_usage
.