mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-12 16:10:54 +00:00
libsysprof-profile: bridge ring data to capture file
This commit is contained in:
@ -36,9 +36,15 @@
|
|||||||
#include "sysprof-controlfd-instrument-private.h"
|
#include "sysprof-controlfd-instrument-private.h"
|
||||||
#include "sysprof-recording-private.h"
|
#include "sysprof-recording-private.h"
|
||||||
|
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
# include "mapped-ring-buffer.h"
|
||||||
|
# include "mapped-ring-buffer-source-private.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
struct _SysprofControlfdInstrument
|
struct _SysprofControlfdInstrument
|
||||||
{
|
{
|
||||||
SysprofInstrument parent_instance;
|
SysprofInstrument parent_instance;
|
||||||
|
|
||||||
#ifdef G_OS_UNIX
|
#ifdef G_OS_UNIX
|
||||||
GUnixConnection *connection;
|
GUnixConnection *connection;
|
||||||
char read_buf[10];
|
char read_buf[10];
|
||||||
@ -48,6 +54,37 @@ struct _SysprofControlfdInstrument
|
|||||||
G_DEFINE_FINAL_TYPE (SysprofControlfdInstrument, sysprof_controlfd_instrument, SYSPROF_TYPE_INSTRUMENT)
|
G_DEFINE_FINAL_TYPE (SysprofControlfdInstrument, sysprof_controlfd_instrument, SYSPROF_TYPE_INSTRUMENT)
|
||||||
|
|
||||||
#ifdef G_OS_UNIX
|
#ifdef G_OS_UNIX
|
||||||
|
typedef struct _RingData
|
||||||
|
{
|
||||||
|
SysprofCaptureWriter *writer;
|
||||||
|
GArray *source_ids;
|
||||||
|
guint id;
|
||||||
|
} RingData;
|
||||||
|
|
||||||
|
static void
|
||||||
|
ring_data_free (gpointer data)
|
||||||
|
{
|
||||||
|
RingData *ring_data = data;
|
||||||
|
|
||||||
|
for (guint i = 0; i < ring_data->source_ids->len; i++)
|
||||||
|
{
|
||||||
|
guint *id = &g_array_index (ring_data->source_ids, guint, i);
|
||||||
|
|
||||||
|
if (*id == ring_data->id)
|
||||||
|
{
|
||||||
|
*id = 0;
|
||||||
|
g_array_remove_index_fast (ring_data->source_ids, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ring_data->id = 0;
|
||||||
|
|
||||||
|
g_clear_pointer (&ring_data->writer, sysprof_capture_writer_unref);
|
||||||
|
g_array_unref (ring_data->source_ids);
|
||||||
|
g_free (ring_data);
|
||||||
|
}
|
||||||
|
|
||||||
static DexFuture *
|
static DexFuture *
|
||||||
sysprof_controlfd_instrument_prepare (SysprofInstrument *instrument,
|
sysprof_controlfd_instrument_prepare (SysprofInstrument *instrument,
|
||||||
SysprofRecording *recording)
|
SysprofRecording *recording)
|
||||||
@ -122,10 +159,36 @@ sysprof_controlfd_recording_free (gpointer data)
|
|||||||
g_free (state);
|
g_free (state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
sysprof_controlfd_instrument_frame_cb (gconstpointer data,
|
||||||
|
gsize *length,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
const SysprofCaptureFrame *fr = data;
|
||||||
|
RingData *ring_data = user_data;
|
||||||
|
|
||||||
|
g_assert (ring_data != NULL);
|
||||||
|
g_assert (ring_data->source_ids != NULL);
|
||||||
|
g_assert (ring_data->writer != NULL);
|
||||||
|
g_assert (ring_data->id > 0);
|
||||||
|
|
||||||
|
if G_UNLIKELY (*length < sizeof *fr ||
|
||||||
|
*length < fr->len ||
|
||||||
|
fr->type >= SYSPROF_CAPTURE_FRAME_LAST)
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
|
||||||
|
_sysprof_capture_writer_add_raw (ring_data->writer, fr);
|
||||||
|
|
||||||
|
*length = fr->len;
|
||||||
|
|
||||||
|
return G_SOURCE_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
static DexFuture *
|
static DexFuture *
|
||||||
sysprof_controlfd_instrument_record_fiber (gpointer user_data)
|
sysprof_controlfd_instrument_record_fiber (gpointer user_data)
|
||||||
{
|
{
|
||||||
SysprofControlfdRecording *state = user_data;
|
SysprofControlfdRecording *state = user_data;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
g_assert (state != NULL);
|
g_assert (state != NULL);
|
||||||
g_assert (SYSPROF_IS_RECORDING (state->recording));
|
g_assert (SYSPROF_IS_RECORDING (state->recording));
|
||||||
@ -135,9 +198,8 @@ sysprof_controlfd_instrument_record_fiber (gpointer user_data)
|
|||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
g_autoptr(DexFuture) future = dex_input_stream_read_bytes (state->stream, 10, 0);
|
g_autoptr(DexFuture) future = dex_input_stream_read_bytes (state->stream, 10, 0);
|
||||||
//g_autoptr(MappedRinBuffer) ring_buffer = NULL;
|
g_autoptr(MappedRingBuffer) ring_buffer = NULL;
|
||||||
g_autoptr(GBytes) bytes = NULL;
|
g_autoptr(GBytes) bytes = NULL;
|
||||||
g_autoptr(GError) error = NULL;
|
|
||||||
const guint8 *data;
|
const guint8 *data;
|
||||||
gsize len;
|
gsize len;
|
||||||
|
|
||||||
@ -147,18 +209,47 @@ sysprof_controlfd_instrument_record_fiber (gpointer user_data)
|
|||||||
&error);
|
&error);
|
||||||
|
|
||||||
if (error != NULL)
|
if (error != NULL)
|
||||||
return dex_future_new_for_error (g_steal_pointer (&error));
|
goto handle_error;
|
||||||
|
|
||||||
if (!(bytes = dex_await_boxed (dex_ref (future), &error)))
|
if (!(bytes = dex_await_boxed (dex_ref (future), &error)))
|
||||||
return dex_future_new_for_error (g_steal_pointer (&error));
|
goto handle_error;
|
||||||
|
|
||||||
data = g_bytes_get_data (bytes, &len);
|
data = g_bytes_get_data (bytes, &len);
|
||||||
if (len != 10 || memcmp (data, "CreatRing\0", 10) != 0)
|
if (len != 10 || memcmp (data, "CreatRing\0", 10) != 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if ((ring_buffer = mapped_ring_buffer_new_reader (0)))
|
||||||
|
{
|
||||||
|
int fd = mapped_ring_buffer_get_fd (ring_buffer);
|
||||||
|
SysprofCaptureWriter *writer = _sysprof_recording_writer (state->recording);
|
||||||
|
RingData *ring_data;
|
||||||
|
|
||||||
|
ring_data = g_new0 (RingData, 1);
|
||||||
|
ring_data->writer = sysprof_capture_writer_ref (writer);
|
||||||
|
ring_data->source_ids = g_array_ref (state->source_ids);
|
||||||
|
ring_data->id = mapped_ring_buffer_create_source_full (ring_buffer,
|
||||||
|
sysprof_controlfd_instrument_frame_cb,
|
||||||
|
ring_data,
|
||||||
|
(GDestroyNotify)ring_data_free);
|
||||||
|
|
||||||
|
g_array_append_val (state->source_ids, ring_data->id);
|
||||||
|
|
||||||
|
g_unix_connection_send_fd (G_UNIX_CONNECTION (state->stream), fd, NULL, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
handle_error:
|
||||||
|
while (state->source_ids->len > 0)
|
||||||
|
{
|
||||||
|
guint id = g_array_index (state->source_ids, guint, state->source_ids->len-1);
|
||||||
|
state->source_ids->len--;
|
||||||
|
g_source_remove (id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error != NULL)
|
||||||
|
return dex_future_new_for_error (g_steal_pointer (&error));
|
||||||
|
|
||||||
|
return dex_future_new_for_boolean (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -177,10 +268,14 @@ sysprof_controlfd_instrument_record (SysprofInstrument *instrument,
|
|||||||
{
|
{
|
||||||
SysprofControlfdInstrument *self = (SysprofControlfdInstrument *)instrument;
|
SysprofControlfdInstrument *self = (SysprofControlfdInstrument *)instrument;
|
||||||
SysprofControlfdRecording *state;
|
SysprofControlfdRecording *state;
|
||||||
|
SysprofSpawnable *spawnable;
|
||||||
|
|
||||||
g_assert (SYSPROF_IS_CONTROLFD_INSTRUMENT (self));
|
g_assert (SYSPROF_IS_CONTROLFD_INSTRUMENT (self));
|
||||||
g_assert (SYSPROF_IS_RECORDING (recording));
|
g_assert (SYSPROF_IS_RECORDING (recording));
|
||||||
|
|
||||||
|
if (!(spawnable = _sysprof_recording_get_spawnable (recording)))
|
||||||
|
return dex_future_new_for_boolean (TRUE);
|
||||||
|
|
||||||
state = g_new0 (SysprofControlfdRecording, 1);
|
state = g_new0 (SysprofControlfdRecording, 1);
|
||||||
state->recording = g_object_ref (recording);
|
state->recording = g_object_ref (recording);
|
||||||
state->cancellable = dex_cancellable_new_from_cancellable (cancellable);
|
state->cancellable = dex_cancellable_new_from_cancellable (cancellable);
|
||||||
|
|||||||
Reference in New Issue
Block a user