We can lose profiling timer events for a few reasons, for example
disabled interrupts or system slowness. This accounts for lost
time between CPU samples by adding a field lost_samples to each
profiling event which tracks how many samples were lost immediately
preceding the event.
Now that the profiling timer is independent from the scheduler the
user will get quite a few CPU samples from "within" the scheduler.
These events are less useful when just profiling a user-mode process
rather than the whole system. This patch adds an option to Profiler to
hide these events.
Previously Profiler would use the stack depth to draw the timeline
graphs. This is not an accurate representation of whether a thread
is "busy" or not. Instead this updates the timelines to use the
sample count.
The architecture here is a little bit convoluted. I ended up making a
new container widget (TimelineContainer) that works similarly to
GUI::ScrollableContainerWidget but has two subwidgets (a fixed header
that only scrolls vertically, and the timeline view that scrolls on
both axes.)
It would be nice to generalize this mechanism eventually and move it
back into LibGUI, but for now let's go with a special widget for
Profiler so we can continue iterating on the GUI. :^)