!threads: split cpuTime into user and system time#813
Conversation
There was a problem hiding this comment.
Code Review
This pull request splits the single thread CPU time tracking into separate user and system CPU times, updating the thread structures, syscall dispatching, and thread iteration logic accordingly. Feedback on the changes highlights a critical bug in the newly added threads_updateCpuTime function, where an inverted NULL check will cause a NULL pointer dereference. Additionally, it is recommended to hold the spinlock for the entire duration of the time update to prevent data races, and to replace the runtime NULL check with a debug assertion.
Unit Test Results11 305 tests - 2 10 597 ✅ - 2 1h 0m 37s ⏱️ + 8m 10s For more details on these failures, see this check. Results for commit ef90a2b. ± Comparison against base commit fb914a8. This pull request removes 3 and adds 1 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
7402e53 to
9859532
Compare
| hal_spinlockSet(&threads_common.spinlock, &sc); | ||
| now = _proc_gettimeRaw(); | ||
| hal_spinlockClear(&threads_common.spinlock, &sc); |
There was a problem hiding this comment.
Since thread_t already tracks lastTime, you may take now directly from hal_timerGetUs() and detect non-monotonicity in DEBUG by comparing lastTime with now, instead of calling _proc_gettimeRaw(). That way you wouldn't need a spinlock.
There was a problem hiding this comment.
Then I'm essentially reimplementing what _proc_gettimeRaw does, without writing to threads_common.prev.
I don't really get the point of it; sure, it will save some time, but then, what is this function for?
There was a problem hiding this comment.
Why take spinlock twice for each syscall when you can simply not?
_proc_gettimeRaw() checks non-monotonicity in threads.c from a common prev, since there is no other place to store this information. In your case however, you already store lastTime in the thread, so you can track it from there. You are concerned about reimplementing a two line function.
There was a problem hiding this comment.
ok, @etiaro (and the tin man) have a point that systemTime and userTime should be synchronized due to use in threadsinfo, so this becomes irrelevant
| typedef enum threadTimeKind { | ||
| kSystem, | ||
| kUser, | ||
| } threadTimeKind_t; |
There was a problem hiding this comment.
Not sure about the naming of this enum. Usually named kernel enums follow xyz_t -> values: xyz_a, xyz_b, xyz_c etc.
There was a problem hiding this comment.
There are two conventions, one is the one you mentioned, the other one is the one I used.
I don't think we have guidelines regarding enum definition styles.
There was a problem hiding this comment.
New enums follow the style I have described, look in the code. Your convention is not used anywhere except for message types, which are exported. Besides, kSystem is simply cryptic.
9859532 to
34a9bd6
Compare
TASK: RTOS-1382
34a9bd6 to
ef90a2b
Compare
etiaro
left a comment
There was a problem hiding this comment.
Please ensure all kernel/userspace boundaries are included, as we don't always pass through a syscall return, e.g. through a few calls of hal_jmp.
Consider what should happen on execve syscalls (currently the time will go over to the exec'd process, but maybe that's fine? Is it standardized in any way?).
Another boundaries are user interrupts and exceptions (especially pageFault, as we pretend to support lazy-allocations which would make it happen in regular execution).
Not sure what to do about these, maybe nothing, maybe leave a memo in a comment at least.
|
@etiaro Linux differentiates between 'user time' vs 'system time' and 'irq time', we can do that too I think. |
TASK: RTOS-1382
Description
Motivation and Context
Types of changes
How Has This Been Tested?
Checklist:
Special treatment