Another step towards dropping GLib as a dependency of
libsysprof-capture.
Unlike the previous commit which replaced GLib integer types with the
bitwise equivalent C standard types, `stdbool` is potentially a different
width from `gboolean`, so this is an ABI break.
It therefore involves some changes to callback functions in the tests
and tools, and in libsysprof.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #40
This is an almost entirely mechanical* conversion from (for example)
`gint` → `int`, `guint8` → `uint8_t`, etc.
It is not entirely complete, as many GLib functions are still used in
libsysprof-capture, which necessitate some use of GLib types.
It also avoids renaming `gboolean` → `bool` as that’s a slightly more
controversial change which will happen in the following commit.
*Code was manually realigned afterwards.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #40
As preparation for dropping the GLib dependency from libsysprof-capture,
move the `GSource` which links a `MappedRingBuffer` to a `GMainContext`
from libsysprof-capture to libsysprof.
This requires adding one new piece of API to libsysprof-capture to check
whether the `MappedRingBuffer` is empty.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #40
In preparation for dropping the GLib dependency from libsysprof-capture,
move the autocleanup definitions up to libsysprof. Add a new header for
them.
This is slightly awkward in the tools, which depend on
libsysprof-capture but not libsysprof. Rather than make them depend on
libsysprof (which might be disabled at configure time), include the
`sysprof-capture-autocleanups.h` file between source directories.
`SYSPROF_COMPILATION` needs to be defined for this to work.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #40
This is a convenience function to call sysprof_collector_log() while also
formatting the message.
Ideally we'd be able to avoid the string format if we are not currently
collecting data, but that can be left for a future commit. We don't have
recursive locks so we need to duplicate the structure setup.
When trying to build gjs with --werror, I get the following error:
In file included from /nix/store/snc19nr462570ssx03v455p164vyz15s-sysprof-3.36.0-dev/include/sysprof-3/sysprof-capture-condition.h:59,
from /nix/store/snc19nr462570ssx03v455p164vyz15s-sysprof-3.36.0-dev/include/sysprof-3/sysprof-capture.h:66,
from ../gjs/profiler.cpp:53:
/nix/store/snc19nr462570ssx03v455p164vyz15s-sysprof-3.36.0-dev/include/sysprof-3/sysprof-capture-types.h:76:40: error: invalid suffix on literal; C++11 requires a space between literal and string macro [-Werror=literal-suffix]
76 | #define SYSPROF_CAPTURE_ADDRESS_FORMAT "0x%016"G_GINT64_MODIFIER"x"
| ^
cc1plus: all warnings being treated as errors
If we backport to an older GLib release, we won't have the newer atomic
helpers available. It's really not too much burden to do that manually if
it means we can run on older systems.
If we're running on a GCC older than 4.9, then we won't have the
stdatomic.h available. We can just use a full barrier instead using
__sync_synchronize() to get the same effect, albeit slower.
We want to be backtracing directly into the capture buffer, but also need
to skip a small number of frames.
If we call the backtrace before filling in information, we can capture to
the position *before* ev->addrs and then overwrite that data right after.
128 is a bit much and can slow us down considerably with user-space stack
traces. This can mess up the tree a bit, but we can alter how we view
things later on if we need to so that it is easier to read.
This ensures that the producer can produce as soon as the reader has moved
past that data. Now that the callback has a mutable consumption value, they
can read the whole data in one shot anyway.
This ideally should be dynamic in the future to copy out data at a rate
that keeps us around 33% usage rate so that we can still burst if we need
to but keep things empty enough to not loose data.
This frame type can be used to communicate with the peer over the mapped
ring buffer to denote that writing is finished and it can free any
resources for the mapping.
This removes the 8 bytes of framing data from the MappedRingBuffer which
means we can write more data without racing. But also this means that we
can eventually use the mapped ring buffer as our normal buffer for
capture writing (to be done later).
This is a simplified API for the inferior to use (such as from a
LD_PRELOAD) that will use mmap()'d ring buffer created by Sysprof. Doing
so can reduce the amount of overhead in the inferior enough to make some
workloads useful. For example, collecting memory statistics and backtraces
is now fast enough to be useful.
This is the start of a ring buffer to coordinate between processes without
the overhead of writing directly to files within the inferior process.
Instead, the parent process can monitor the ring buffer for framing
information and pass that along to the capture writer.