| @@ -0,0 +1,44 @@ | ||
| +/* profiler.h | ||
| + * | ||
| + * Copyright (C) 2016 Christian Hergert <christian@hergert.me> | ||
| + * | ||
| + * This file is free software; you can redistribute it and/or modify it | ||
| + * under the terms of the GNU Lesser General Public License as published | ||
| + * by the Free Software Foundation; either version 2 of the License, or | ||
| + * (at your option) any later version. | ||
| + * | ||
| + * This file is distributed in the hope that it will be useful, but | ||
| + * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| + * Lesser General Public License for more details. | ||
| + * | ||
| + * You should have received a copy of the GNU General Public License | ||
| + * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| + */ | ||
| + | ||
| +#ifndef GJS_PROFILER_H | ||
| +#define GJS_PROFILER_H | ||
| + | ||
| +#include <gjs/context.h> | ||
| +#include <signal.h> | ||
| + | ||
| +G_BEGIN_DECLS | ||
| + | ||
| +#define GJS_TYPE_PROFILER (gjs_profiler_get_type()) | ||
| + | ||
| +typedef struct _GjsProfiler GjsProfiler; | ||
| + | ||
| +GType gjs_profiler_get_type (void); | ||
| +GjsProfiler *gjs_profiler_new (GjsContext *context); | ||
| +void gjs_profiler_free (GjsProfiler *self); | ||
| +void gjs_profiler_set_filename (GjsProfiler *self, | ||
| + const gchar *filename); | ||
| +void gjs_profiler_start (GjsProfiler *self); | ||
| +void gjs_profiler_stop (GjsProfiler *self); | ||
| +gboolean gjs_profiler_is_running (GjsProfiler *self); | ||
| +void gjs_profiler_setup_signals (void); | ||
| +gboolean gjs_profiler_chain_signal (siginfo_t *info); | ||
| + | ||
| +G_END_DECLS | ||
| + | ||
| +#endif /* GJS_PROFILER_H */ |
| @@ -0,0 +1,65 @@ | ||
| +/* sp-capture-reader.h | ||
| + * | ||
| + * Copyright (C) 2016 Christian Hergert <christian@hergert.me> | ||
| + * | ||
| + * This file is free software; you can redistribute it and/or modify it | ||
| + * under the terms of the GNU Lesser General Public License as published | ||
| + * by the Free Software Foundation; either version 2 of the License, or | ||
| + * (at your option) any later version. | ||
| + * | ||
| + * This file is distributed in the hope that it will be useful, but | ||
| + * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| + * Lesser General Public License for more details. | ||
| + * | ||
| + * You should have received a copy of the GNU General Public License | ||
| + * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| + */ | ||
| + | ||
| +#ifndef SP_CAPTURE_READER_H | ||
| +#define SP_CAPTURE_READER_H | ||
| + | ||
| +#include "sp-capture-types.h" | ||
| + | ||
| +G_BEGIN_DECLS | ||
| + | ||
| +typedef struct _SpCaptureReader SpCaptureReader; | ||
| + | ||
| +SpCaptureReader *sp_capture_reader_new (const gchar *filename, | ||
| + GError **error); | ||
| +SpCaptureReader *sp_capture_reader_new_from_fd (int fd, | ||
| + GError **error); | ||
| +SpCaptureReader *sp_capture_reader_ref (SpCaptureReader *self); | ||
| +void sp_capture_reader_unref (SpCaptureReader *self); | ||
| +const gchar *sp_capture_reader_get_filename (SpCaptureReader *self); | ||
| +const gchar *sp_capture_reader_get_time (SpCaptureReader *self); | ||
| +gboolean sp_capture_reader_skip (SpCaptureReader *self); | ||
| +gboolean sp_capture_reader_peek_type (SpCaptureReader *self, | ||
| + SpCaptureFrameType *type); | ||
| +const SpCaptureMap *sp_capture_reader_read_map (SpCaptureReader *self); | ||
| +const SpCaptureExit *sp_capture_reader_read_exit (SpCaptureReader *self); | ||
| +const SpCaptureFork *sp_capture_reader_read_fork (SpCaptureReader *self); | ||
| +const SpCaptureTimestamp *sp_capture_reader_read_timestamp (SpCaptureReader *self); | ||
| +const SpCaptureProcess *sp_capture_reader_read_process (SpCaptureReader *self); | ||
| +const SpCaptureSample *sp_capture_reader_read_sample (SpCaptureReader *self); | ||
| +GHashTable *sp_capture_reader_read_jitmap (SpCaptureReader *self); | ||
| +gboolean sp_capture_reader_reset (SpCaptureReader *self); | ||
| +gboolean sp_capture_reader_splice (SpCaptureReader *self, | ||
| + SpCaptureWriter *dest, | ||
| + GError **error); | ||
| +gboolean sp_capture_reader_save_as (SpCaptureReader *self, | ||
| + const gchar *filename, | ||
| + GError **error); | ||
| + | ||
| +#ifndef SP_DISABLE_GOBJECT | ||
| +# define SP_TYPE_CAPTURE_READER (sp_capture_reader_get_type()) | ||
| + GType sp_capture_reader_get_type (void); | ||
| +#endif | ||
| + | ||
| +#if GLIB_CHECK_VERSION(2, 44, 0) | ||
| + G_DEFINE_AUTOPTR_CLEANUP_FUNC (SpCaptureReader, sp_capture_reader_unref) | ||
| +#endif | ||
| + | ||
| +G_END_DECLS | ||
| + | ||
| +#endif /* SP_CAPTURE_READER_H */ |
| @@ -0,0 +1,155 @@ | ||
| +/* sp-capture-types.h | ||
| + * | ||
| + * Copyright (C) 2016 Christian Hergert <christian@hergert.me> | ||
| + * | ||
| + * This file is free software; you can redistribute it and/or modify it | ||
| + * under the terms of the GNU Lesser General Public License as published | ||
| + * by the Free Software Foundation; either version 2 of the License, or | ||
| + * (at your option) any later version. | ||
| + * | ||
| + * This file is distributed in the hope that it will be useful, but | ||
| + * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| + * Lesser General Public License for more details. | ||
| + * | ||
| + * You should have received a copy of the GNU General Public License | ||
| + * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| + */ | ||
| + | ||
| +#ifndef SP_CAPTURE_FORMAT_H | ||
| +#define SP_CAPTURE_FORMAT_H | ||
| + | ||
| +#include <glib.h> | ||
| + | ||
| +#ifndef SP_DISABLE_GOBJECT | ||
| +# include <glib-object.h> | ||
| +#endif | ||
| + | ||
| +G_BEGIN_DECLS | ||
| + | ||
| +#define SP_CAPTURE_MAGIC (GUINT32_TO_LE(0xFDCA975E)) | ||
| +#define SP_CAPTURE_ALIGN (sizeof(SpCaptureAddress)) | ||
| + | ||
| +#if __WORDSIZE == 64 | ||
| +# define SP_CAPTURE_JITMAP_MARK G_GUINT64_CONSTANT(0xE000000000000000) | ||
| +# define SP_CAPTURE_ADDRESS_FORMAT "0x%016lx" | ||
| +#else | ||
| +# define SP_CAPTURE_JITMAP_MARK G_GUINT64_CONSTANT(0xE0000000) | ||
| +# define SP_CAPTURE_ADDRESS_FORMAT "0x%016llx" | ||
| +#endif | ||
| + | ||
| +#define SP_CAPTURE_CURRENT_TIME (g_get_monotonic_time() * 1000L) | ||
| + | ||
| +typedef struct _SpCaptureReader SpCaptureReader; | ||
| +typedef struct _SpCaptureWriter SpCaptureWriter; | ||
| + | ||
| +typedef guint64 SpCaptureAddress; | ||
| + | ||
| +typedef enum | ||
| +{ | ||
| + SP_CAPTURE_FRAME_TIMESTAMP = 1, | ||
| + SP_CAPTURE_FRAME_SAMPLE = 2, | ||
| + SP_CAPTURE_FRAME_MAP = 3, | ||
| + SP_CAPTURE_FRAME_PROCESS = 4, | ||
| + SP_CAPTURE_FRAME_FORK = 5, | ||
| + SP_CAPTURE_FRAME_EXIT = 6, | ||
| + SP_CAPTURE_FRAME_JITMAP = 7, | ||
| +} SpCaptureFrameType; | ||
| + | ||
| +#pragma pack(push, 1) | ||
| + | ||
| +typedef struct | ||
| +{ | ||
| + guint32 magic; | ||
| + guint8 version; | ||
| + guint32 little_endian : 1; | ||
| + guint32 padding : 23; | ||
| + gchar capture_time[64]; | ||
| + gchar suffix[184]; | ||
| +} SpCaptureFileHeader; | ||
| + | ||
| +typedef struct | ||
| +{ | ||
| + guint16 len; | ||
| + gint16 cpu; | ||
| + gint32 pid; | ||
| + gint64 time; | ||
| + guint8 type; | ||
| + guint64 padding : 56; | ||
| + guint8 data[0]; | ||
| +} SpCaptureFrame; | ||
| + | ||
| +typedef struct | ||
| +{ | ||
| + SpCaptureFrame frame; | ||
| + guint64 start; | ||
| + guint64 end; | ||
| + guint64 offset; | ||
| + guint64 inode; | ||
| + gchar filename[0]; | ||
| +} SpCaptureMap; | ||
| + | ||
| +typedef struct | ||
| +{ | ||
| + SpCaptureFrame frame; | ||
| + guint32 n_jitmaps; | ||
| + guint8 data[0]; | ||
| +} SpCaptureJitmap; | ||
| + | ||
| +typedef struct | ||
| +{ | ||
| + SpCaptureFrame frame; | ||
| + gchar cmdline[0]; | ||
| +} SpCaptureProcess; | ||
| + | ||
| +typedef struct | ||
| +{ | ||
| + SpCaptureFrame frame; | ||
| + guint16 n_addrs; | ||
| + guint64 padding : 48; | ||
| + SpCaptureAddress addrs[0]; | ||
| +} SpCaptureSample; | ||
| + | ||
| +typedef struct | ||
| +{ | ||
| + SpCaptureFrame frame; | ||
| + GPid child_pid; | ||
| +} SpCaptureFork; | ||
| + | ||
| +typedef struct | ||
| +{ | ||
| + SpCaptureFrame frame; | ||
| +} SpCaptureExit; | ||
| + | ||
| +typedef struct | ||
| +{ | ||
| + SpCaptureFrame frame; | ||
| +} SpCaptureTimestamp; | ||
| + | ||
| +#pragma pack(pop) | ||
| + | ||
| +G_STATIC_ASSERT (sizeof (SpCaptureFileHeader) == 256); | ||
| +G_STATIC_ASSERT (sizeof (SpCaptureFrame) == 24); | ||
| +G_STATIC_ASSERT (sizeof (SpCaptureMap) == 56); | ||
| +G_STATIC_ASSERT (sizeof (SpCaptureJitmap) == 28); | ||
| +G_STATIC_ASSERT (sizeof (SpCaptureProcess) == 24); | ||
| +G_STATIC_ASSERT (sizeof (SpCaptureSample) == 32); | ||
| +G_STATIC_ASSERT (sizeof (SpCaptureFork) == 28); | ||
| +G_STATIC_ASSERT (sizeof (SpCaptureExit) == 24); | ||
| +G_STATIC_ASSERT (sizeof (SpCaptureTimestamp) == 24); | ||
| + | ||
| +static inline gint | ||
| +sp_capture_address_compare (SpCaptureAddress a, | ||
| + SpCaptureAddress b) | ||
| +{ | ||
| + if (a < b) | ||
| + return -1; | ||
| + if (a > b) | ||
| + return 1; | ||
| + else | ||
| + return 0; | ||
| +} | ||
| + | ||
| +G_END_DECLS | ||
| + | ||
| +#endif /* SP_CAPTURE_FORMAT_H */ |
| @@ -0,0 +1,108 @@ | ||
| +/* sp-capture-writer.h | ||
| + * | ||
| + * Copyright (C) 2016 Christian Hergert <christian@hergert.me> | ||
| + * | ||
| + * This file is free software; you can redistribute it and/or modify it | ||
| + * under the terms of the GNU Lesser General Public License as published | ||
| + * by the Free Software Foundation; either version 2 of the License, or | ||
| + * (at your option) any later version. | ||
| + * | ||
| + * This file is distributed in the hope that it will be useful, but | ||
| + * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| + * Lesser General Public License for more details. | ||
| + * | ||
| + * You should have received a copy of the GNU General Public License | ||
| + * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| + */ | ||
| + | ||
| +#ifndef SP_CAPTURE_WRITER_H | ||
| +#define SP_CAPTURE_WRITER_H | ||
| + | ||
| +#include "sp-capture-types.h" | ||
| + | ||
| +G_BEGIN_DECLS | ||
| + | ||
| +typedef struct _SpCaptureWriter SpCaptureWriter; | ||
| + | ||
| +typedef struct | ||
| +{ | ||
| + /* | ||
| + * The number of frames indexed by SpCaptureFrameType | ||
| + */ | ||
| + gsize frame_count[16]; | ||
| + | ||
| + /* | ||
| + * Padding for future expansion. | ||
| + */ | ||
| + gsize padding[48]; | ||
| +} SpCaptureStat; | ||
| + | ||
| +SpCaptureWriter *sp_capture_writer_new (const gchar *filename, | ||
| + gsize buffer_size); | ||
| +SpCaptureWriter *sp_capture_writer_new_from_fd (int fd, | ||
| + gsize buffer_size); | ||
| +SpCaptureWriter *sp_capture_writer_ref (SpCaptureWriter *self); | ||
| +void sp_capture_writer_unref (SpCaptureWriter *self); | ||
| +void sp_capture_writer_stat (SpCaptureWriter *self, | ||
| + SpCaptureStat *stat); | ||
| +gboolean sp_capture_writer_add_map (SpCaptureWriter *self, | ||
| + gint64 time, | ||
| + gint cpu, | ||
| + GPid pid, | ||
| + guint64 start, | ||
| + guint64 end, | ||
| + guint64 offset, | ||
| + guint64 inode, | ||
| + const gchar *filename); | ||
| +guint64 sp_capture_writer_add_jitmap (SpCaptureWriter *self, | ||
| + const gchar *name); | ||
| +gboolean sp_capture_writer_add_process (SpCaptureWriter *self, | ||
| + gint64 time, | ||
| + gint cpu, | ||
| + GPid pid, | ||
| + const gchar *cmdline); | ||
| +gboolean sp_capture_writer_add_sample (SpCaptureWriter *self, | ||
| + gint64 time, | ||
| + gint cpu, | ||
| + GPid pid, | ||
| + const SpCaptureAddress *addrs, | ||
| + guint n_addrs); | ||
| +gboolean sp_capture_writer_add_fork (SpCaptureWriter *self, | ||
| + gint64 time, | ||
| + gint cpu, | ||
| + GPid pid, | ||
| + GPid child_pid); | ||
| +gboolean sp_capture_writer_add_exit (SpCaptureWriter *self, | ||
| + gint64 time, | ||
| + gint cpu, | ||
| + GPid pid); | ||
| +gboolean sp_capture_writer_add_timestamp (SpCaptureWriter *self, | ||
| + gint64 time, | ||
| + gint cpu, | ||
| + GPid pid); | ||
| +gboolean sp_capture_writer_flush (SpCaptureWriter *self); | ||
| +gboolean sp_capture_writer_save_as (SpCaptureWriter *self, | ||
| + const gchar *filename, | ||
| + GError **error); | ||
| +SpCaptureReader *sp_capture_writer_create_reader (SpCaptureWriter *self, | ||
| + GError **error); | ||
| +gboolean sp_capture_writer_splice (SpCaptureWriter *self, | ||
| + SpCaptureWriter *dest, | ||
| + GError **error); | ||
| +gboolean _sp_capture_writer_splice_from_fd (SpCaptureWriter *self, | ||
| + int fd, | ||
| + GError **error) G_GNUC_INTERNAL; | ||
| + | ||
| +#ifndef SP_DISABLE_GOBJECT | ||
| +# define SP_TYPE_CAPTURE_WRITER (sp_capture_writer_get_type()) | ||
| + GType sp_capture_writer_get_type (void); | ||
| +#endif | ||
| + | ||
| +#if GLIB_CHECK_VERSION(2, 44, 0) | ||
| + G_DEFINE_AUTOPTR_CLEANUP_FUNC (SpCaptureWriter, sp_capture_writer_unref) | ||
| +#endif | ||
| + | ||
| +G_END_DECLS | ||
| + | ||
| +#endif /* SP_CAPTURE_WRITER_H */ |