We already do this in most places, so the style should be consistent.
Also, Clang does not like it, as this could cause an unexpected compile
error if some statements are added to the default label or a new label
is added above it.
Previously Profiler was using timestamps to distinguish processes.
However it is possible that separate processes with the same PID exist
at the exact same timestamp (e.g. for execve). This changes Profiler
to use unique serial numbers for each event instead.
Hiding those frames doesn't really make sense. They're a major
contributor to a process' spent CPU time and show up in a lot of
profiles. That however is because those processes really do spend
quite a bit of time in the scheduler by doing lots of context
switches, like WindowServer when responding to IPC calls.
Instead of hiding these for aesthetic reasons we should instead
improve the scheduler.
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. :^)