summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorentin Noël <tintou@noel.tf>2023-01-04 18:54:57 +0100
committerNiels De Graef <nielsdegraef@gmail.com>2023-01-15 18:07:15 +0000
commitbc03cbab8498de1583f6489665234edc819aa8fd (patch)
tree58978351b69415df04e58eb00362606472eab4e8
parenta49d1e8950d6ff26e19da7f28be6e2d80406b05b (diff)
downloadfolks-bc03cbab8498de1583f6489665234edc819aa8fd.tar.gz
profiling: Use sysprof as the profiling library
Instead of abusing the posix access function.
-rw-r--r--backends/bluez/bluez-backend.vala4
-rw-r--r--backends/bluez/bluez-persona-store.vala34
-rw-r--r--backends/dummy/lib/dummy-backend.vala4
-rw-r--r--backends/dummy/lib/dummy-persona-store.vala4
-rw-r--r--backends/eds/eds-backend.vala4
-rw-r--r--backends/eds/lib/edsf-persona-store.vala4
-rw-r--r--backends/key-file/kf-backend.vala4
-rw-r--r--backends/key-file/kf-persona-store.vala4
-rw-r--r--backends/ofono/ofono-backend.vala4
-rw-r--r--backends/ofono/ofono-persona-store.vala4
-rw-r--r--backends/telepathy/lib/tpf-persona-store.vala15
-rw-r--r--backends/telepathy/tp-backend.vala4
-rw-r--r--folks/backend-store.vala8
-rw-r--r--folks/individual-aggregator.vala4
-rw-r--r--folks/internal.vala49
-rw-r--r--folks/meson.build3
-rw-r--r--meson.build5
-rw-r--r--meson_options.txt2
-rw-r--r--vapi/sysprof-capture-4.vapi322
19 files changed, 405 insertions, 77 deletions
diff --git a/backends/bluez/bluez-backend.vala b/backends/bluez/bluez-backend.vala
index 5d659ba1..7c9744aa 100644
--- a/backends/bluez/bluez-backend.vala
+++ b/backends/bluez/bluez-backend.vala
@@ -658,7 +658,7 @@ public class Folks.Backends.BlueZ.Backend : Folks.Backend
*/
public override async void prepare () throws DBusError
{
- Internal.profiling_start ("preparing BlueZ.Backend");
+ var profiling = Internal.profiling_start ("preparing BlueZ.Backend");
if (this._is_prepared || this._prepare_pending)
{
@@ -786,7 +786,7 @@ public class Folks.Backends.BlueZ.Backend : Folks.Backend
this._prepare_pending = false;
}
- Internal.profiling_end ("preparing BlueZ.Backend");
+ Internal.profiling_end ((owned) profiling);
}
/**
diff --git a/backends/bluez/bluez-persona-store.vala b/backends/bluez/bluez-persona-store.vala
index 7c455c58..5e0a3d13 100644
--- a/backends/bluez/bluez-persona-store.vala
+++ b/backends/bluez/bluez-persona-store.vala
@@ -752,22 +752,23 @@ public class Folks.Backends.BlueZ.PersonaStore : Folks.PersonaStore
org.bluez.obex.PhonebookAccess? obex_pbap = null;
var success = true;
- try
+ if (this._update_contacts_cancellable != null)
{
- if (this._update_contacts_cancellable != null)
- {
- /* There’s an ongoing _update_contacts() call. Since downloading
- * the address book takes a long time (tens of seconds), we don’t
- * want to cancel the ongoing operation. Just return
- * immediately. */
- debug ("Not updating contacts due to ongoing update operation.");
- return;
- }
+ /* There’s an ongoing _update_contacts() call. Since downloading
+ * the address book takes a long time (tens of seconds), we don’t
+ * want to cancel the ongoing operation. Just return
+ * immediately. */
+ debug ("Not updating contacts due to ongoing update operation.");
+ return;
+ }
+
+ var profiling = Internal.profiling_start ("updating BlueZ.PersonaStore (ID: %s) " +
+ "contacts", this.id);
- Internal.profiling_start ("updating BlueZ.PersonaStore (ID: %s) " +
- "contacts", this.id);
+ debug ("Updating contacts.");
- debug ("Updating contacts.");
+ try
+ {
string path;
HashTable<string, Variant> props;
@@ -889,8 +890,7 @@ public class Folks.Backends.BlueZ.PersonaStore : Folks.PersonaStore
success == true && this._photos_up_to_date == false;
this._schedule_update_contacts (new_download_photos);
- Internal.profiling_end ("updating BlueZ.PersonaStore (ID: %s) " +
- "contacts", this.id);
+ Internal.profiling_end ((owned) profiling);
}
}
@@ -1044,7 +1044,7 @@ public class Folks.Backends.BlueZ.PersonaStore : Folks.PersonaStore
*/
public override async void prepare () throws PersonaStoreError
{
- Internal.profiling_start ("preparing BlueZ.PersonaStore (ID: %s)",
+ var profiling = Internal.profiling_start ("preparing BlueZ.PersonaStore (ID: %s)",
this.id);
if (this._is_prepared || this._prepare_pending)
@@ -1108,7 +1108,7 @@ public class Folks.Backends.BlueZ.PersonaStore : Folks.PersonaStore
this._prepare_pending = false;
}
- Internal.profiling_end ("preparing BlueZ.PersonaStore (ID: %s)", this.id);
+ Internal.profiling_end ((owned) profiling);
}
/**
diff --git a/backends/dummy/lib/dummy-backend.vala b/backends/dummy/lib/dummy-backend.vala
index 5ba8dafc..bbd5fa89 100644
--- a/backends/dummy/lib/dummy-backend.vala
+++ b/backends/dummy/lib/dummy-backend.vala
@@ -238,7 +238,7 @@ public class FolksDummy.Backend : Folks.Backend
*/
public override async void prepare () throws GLib.Error
{
- Internal.profiling_start ("preparing Dummy.Backend");
+ var profiling = Internal.profiling_start ("preparing Dummy.Backend");
if (this._is_prepared || this._prepare_pending)
{
@@ -262,7 +262,7 @@ public class FolksDummy.Backend : Folks.Backend
this._prepare_pending = false;
}
- Internal.profiling_end ("preparing Dummy.Backend");
+ Internal.profiling_end ((owned) profiling);
}
/**
diff --git a/backends/dummy/lib/dummy-persona-store.vala b/backends/dummy/lib/dummy-persona-store.vala
index 5772160d..7c63430d 100644
--- a/backends/dummy/lib/dummy-persona-store.vala
+++ b/backends/dummy/lib/dummy-persona-store.vala
@@ -572,7 +572,7 @@ public class FolksDummy.PersonaStore : Folks.PersonaStore
*/
public override async void prepare () throws PersonaStoreError
{
- Internal.profiling_start ("preparing Dummy.PersonaStore (ID: %s)",
+ var profiling = Internal.profiling_start ("preparing Dummy.PersonaStore (ID: %s)",
this.id);
if (this._is_prepared == true || this._prepare_pending == true)
@@ -606,7 +606,7 @@ public class FolksDummy.PersonaStore : Folks.PersonaStore
this._prepare_pending = false;
}
- Internal.profiling_end ("preparing Dummy.PersonaStore");
+ Internal.profiling_end ((owned) profiling);
}
diff --git a/backends/eds/eds-backend.vala b/backends/eds/eds-backend.vala
index 5f2c632e..fd008148 100644
--- a/backends/eds/eds-backend.vala
+++ b/backends/eds/eds-backend.vala
@@ -196,7 +196,7 @@ public class Folks.Backends.Eds.Backend : Folks.Backend
*/
public override async void prepare () throws GLib.Error
{
- Internal.profiling_start ("preparing Eds.Backend");
+ var profiling = Internal.profiling_start ("preparing Eds.Backend");
if (this._is_prepared || this._prepare_pending)
{
@@ -231,7 +231,7 @@ public class Folks.Backends.Eds.Backend : Folks.Backend
this._prepare_pending = false;
}
- Internal.profiling_end ("preparing Eds.Backend");
+ Internal.profiling_end ((owned) profiling);
}
/**
diff --git a/backends/eds/lib/edsf-persona-store.vala b/backends/eds/lib/edsf-persona-store.vala
index 2193c0ed..0f4a2086 100644
--- a/backends/eds/lib/edsf-persona-store.vala
+++ b/backends/eds/lib/edsf-persona-store.vala
@@ -697,7 +697,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
*/
public override async void prepare () throws PersonaStoreError
{
- Internal.profiling_start ("preparing Edsf.PersonaStore (ID: %s)",
+ var profiling = Internal.profiling_start ("preparing Edsf.PersonaStore (ID: %s)",
this.id);
if (this._is_prepared == true || this._prepare_pending == true)
@@ -1020,7 +1020,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
this._prepare_pending = false;
}
- Internal.profiling_end ("preparing Edsf.PersonaStore");
+ Internal.profiling_end ((owned) profiling);
}
private PersonaDetail _eds_field_name_to_folks_persona_detail (
diff --git a/backends/key-file/kf-backend.vala b/backends/key-file/kf-backend.vala
index 79ac5eda..940003b2 100644
--- a/backends/key-file/kf-backend.vala
+++ b/backends/key-file/kf-backend.vala
@@ -173,7 +173,7 @@ public class Folks.Backends.Kf.Backend : Folks.Backend
*/
public override async void prepare () throws GLib.Error
{
- Internal.profiling_start ("preparing Kf.Backend");
+ var profiling = Internal.profiling_start ("preparing Kf.Backend");
if (this._is_prepared || this._prepare_pending)
{
@@ -221,7 +221,7 @@ public class Folks.Backends.Kf.Backend : Folks.Backend
this._prepare_pending = false;
}
- Internal.profiling_end ("preparing Kf.Backend");
+ Internal.profiling_end ((owned) profiling);
}
/**
diff --git a/backends/key-file/kf-persona-store.vala b/backends/key-file/kf-persona-store.vala
index fd6de12d..d234990a 100644
--- a/backends/key-file/kf-persona-store.vala
+++ b/backends/key-file/kf-persona-store.vala
@@ -183,7 +183,7 @@ public class Folks.Backends.Kf.PersonaStore : Folks.PersonaStore
*/
public override async void prepare ()
{
- Internal.profiling_start ("preparing Kf.PersonaStore (ID: %s)", this.id);
+ var profiling = Internal.profiling_start ("preparing Kf.PersonaStore (ID: %s)", this.id);
if (this._is_prepared || this._prepare_pending)
{
@@ -316,7 +316,7 @@ public class Folks.Backends.Kf.PersonaStore : Folks.PersonaStore
this._prepare_pending = false;
}
- Internal.profiling_end ("preparing Kf.PersonaStore (ID: %s)", this.id);
+ Internal.profiling_end ((owned) profiling);
}
/**
diff --git a/backends/ofono/ofono-backend.vala b/backends/ofono/ofono-backend.vala
index 9983b018..f0f374b8 100644
--- a/backends/ofono/ofono-backend.vala
+++ b/backends/ofono/ofono-backend.vala
@@ -167,7 +167,7 @@ public class Folks.Backends.Ofono.Backend : Folks.Backend
*/
public override async void prepare () throws DBusError
{
- Internal.profiling_start ("preparing Ofono.Backend");
+ var profiling = Internal.profiling_start ("preparing Ofono.Backend");
if (this._is_prepared || this._prepare_pending)
{
@@ -213,7 +213,7 @@ public class Folks.Backends.Ofono.Backend : Folks.Backend
this._prepare_pending = false;
}
- Internal.profiling_end ("preparing Ofono.Backend");
+ Internal.profiling_end ((owned) profiling);
}
/**
diff --git a/backends/ofono/ofono-persona-store.vala b/backends/ofono/ofono-persona-store.vala
index 711ec7b2..ae3dd6fb 100644
--- a/backends/ofono/ofono-persona-store.vala
+++ b/backends/ofono/ofono-persona-store.vala
@@ -192,7 +192,7 @@ public class Folks.Backends.Ofono.PersonaStore : Folks.PersonaStore
*/
public override async void prepare () throws IOError, DBusError
{
- Internal.profiling_start ("preparing Ofono.PersonaStore (ID: %s)",
+ var profiling = Internal.profiling_start ("preparing Ofono.PersonaStore (ID: %s)",
this.id);
if (this._is_prepared || this._prepare_pending)
@@ -252,7 +252,7 @@ public class Folks.Backends.Ofono.PersonaStore : Folks.PersonaStore
this._prepare_pending = false;
}
- Internal.profiling_end ("preparing Ofono.PersonaStore (ID: %s)", this.id);
+ Internal.profiling_end ((owned) profiling);
}
/**
diff --git a/backends/telepathy/lib/tpf-persona-store.vala b/backends/telepathy/lib/tpf-persona-store.vala
index 510c0bac..2f390f12 100644
--- a/backends/telepathy/lib/tpf-persona-store.vala
+++ b/backends/telepathy/lib/tpf-persona-store.vala
@@ -467,7 +467,7 @@ public class Tpf.PersonaStore : Folks.PersonaStore
*/
public override async void prepare () throws GLib.Error
{
- Internal.profiling_start ("preparing Tpf.PersonaStore (ID: %s)", this.id);
+ var profiling_prepare = Internal.profiling_start ("preparing Tpf.PersonaStore (ID: %s)", this.id);
if (this._is_prepared || this._prepare_pending)
{
@@ -542,15 +542,15 @@ public class Tpf.PersonaStore : Folks.PersonaStore
this._logger_invalidated_cb);
this._logger.favourite_contacts_changed.connect (
this._favourite_contacts_changed_cb);
- Internal.profiling_start ("initialising favourite contacts in " +
+
+ var profiling = Internal.profiling_start ("initialising favourite contacts in " +
"Tpf.PersonaStore (ID: %s)", this.id);
this._initialise_favourite_contacts.begin ((o, r) =>
{
try
{
this._initialise_favourite_contacts.end (r);
- Internal.profiling_end ("initialising favourite " +
- "contacts in Tpf.PersonaStore (ID: %s)", this.id);
+ Internal.profiling_end ((owned) profiling);
}
catch (GLib.Error e)
{
@@ -591,7 +591,7 @@ public class Tpf.PersonaStore : Folks.PersonaStore
this._prepare_pending = false;
}
- Internal.profiling_end ("preparing Tpf.PersonaStore (ID: %s)", this.id);
+ Internal.profiling_end ((owned) profiling_prepare);
}
private void _account_manager_invalidated_cb (uint domain, int code,
@@ -750,7 +750,7 @@ public class Tpf.PersonaStore : Folks.PersonaStore
debug ("_notify_connection_cb_async() for Tpf.PersonaStore %p ('%s').",
this, this.id);
- Internal.profiling_start ("notify connection for Tpf.PersonaStore " +
+ var profiling = Internal.profiling_start ("notify connection for Tpf.PersonaStore " +
"(ID: %s)", this.id);
/* Ensure the connection is prepared as necessary. */
@@ -852,8 +852,7 @@ public class Tpf.PersonaStore : Folks.PersonaStore
this._self_contact_changed_cb (this._conn, null);
this._contact_list_state_changed_cb (this._conn, null);
- Internal.profiling_end ("notify connection for Tpf.PersonaStore " +
- "(ID: %s)", this.id);
+ Internal.profiling_end ((owned) profiling);
}
private void _marshall_supported_fields ()
diff --git a/backends/telepathy/tp-backend.vala b/backends/telepathy/tp-backend.vala
index 7877ca02..71cfc84d 100644
--- a/backends/telepathy/tp-backend.vala
+++ b/backends/telepathy/tp-backend.vala
@@ -155,7 +155,7 @@ public class Folks.Backends.Tp.Backend : Folks.Backend
*/
public override async void prepare () throws GLib.Error
{
- Internal.profiling_start ("preparing Tp.Backend");
+ var profiling = Internal.profiling_start ("preparing Tp.Backend");
if (this._is_prepared || this._prepare_pending)
{
@@ -192,7 +192,7 @@ public class Folks.Backends.Tp.Backend : Folks.Backend
this._prepare_pending = false;
}
- Internal.profiling_end ("preparing Tp.Backend");
+ Internal.profiling_end ((owned) profiling);
}
/**
diff --git a/folks/backend-store.vala b/folks/backend-store.vala
index e3f97177..11c37ac9 100644
--- a/folks/backend-store.vala
+++ b/folks/backend-store.vala
@@ -276,7 +276,7 @@ public class Folks.BackendStore : Object {
*/
public async void prepare ()
{
- Internal.profiling_start ("preparing BackendStore");
+ var profiling = Internal.profiling_start ("preparing BackendStore");
/* (re-)load the list of disabled backends */
yield this._load_disabled_backend_names ();
@@ -287,7 +287,7 @@ public class Folks.BackendStore : Object {
this.notify_property ("is-prepared");
}
- Internal.profiling_end ("preparing BackendStore");
+ Internal.profiling_end ((owned) profiling);
}
/**
@@ -305,7 +305,7 @@ public class Folks.BackendStore : Object {
{
assert (Module.supported());
- Internal.profiling_start ("loading backends in BackendStore");
+ var profiling = Internal.profiling_start ("loading backends in BackendStore");
yield this.prepare ();
@@ -400,7 +400,7 @@ public class Folks.BackendStore : Object {
yield;
}
- Internal.profiling_end ("loading backends in BackendStore");
+ Internal.profiling_end ((owned) profiling);
}
/* This method is not safe to call multiple times concurrently, since there's
diff --git a/folks/individual-aggregator.vala b/folks/individual-aggregator.vala
index fb801001..831507b7 100644
--- a/folks/individual-aggregator.vala
+++ b/folks/individual-aggregator.vala
@@ -695,7 +695,7 @@ public class Folks.IndividualAggregator : Object
*/
public async void prepare () throws GLib.Error
{
- Internal.profiling_start ("preparing IndividualAggregator");
+ var profiling = Internal.profiling_start ("preparing IndividualAggregator");
/* Once this async function returns, all the {@link Backend}s will have
* been prepared (though no {@link PersonaStore}s are guaranteed to be
@@ -751,7 +751,7 @@ public class Folks.IndividualAggregator : Object
this._prepare_pending = false;
}
- Internal.profiling_end ("preparing IndividualAggregator");
+ Internal.profiling_end ((owned) profiling);
}
/**
diff --git a/folks/internal.vala b/folks/internal.vala
index 1d4030f2..35ec807a 100644
--- a/folks/internal.vala
+++ b/folks/internal.vala
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Collabora Ltd.
+ * Copyright 2011,2023 Collabora Ltd.
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -16,6 +16,7 @@
*
* Authors:
* Raul Gutierrez Segales <raul.gutierrez.segales@collabora.co.uk>
+ * Corentin Noël <corentin.noel@collabora.com>
*/
using GLib;
@@ -38,17 +39,6 @@ namespace Folks.Internal
return true;
}
-#if ENABLE_PROFILING
- /* See: http://people.gnome.org/~federico/news-2006-03.html#timeline-tools */
- [PrintfFormat]
- private static void profiling_markv (string format, va_list args)
- {
- var formatted = format.vprintf (args);
- var str = "MARK: %s-%p: %s".printf (Environment.get_prgname (), Thread.self<void> (), formatted);
- access (str, F_OK);
- }
-#endif
-
/**
* Emit a profiling point.
*
@@ -57,14 +47,27 @@ namespace Folks.Internal
*
* @param format printf-style message format
* @param ... message arguments
- * @since 0.7.2
*/
[PrintfFormat]
- public static void profiling_point (string format, ...)
+ public inline void profiling_point (string format, ...)
{
#if ENABLE_PROFILING
var args = va_list ();
- Internal.profiling_markv (format, args);
+ Sysprof.Collector.log (0, "folks", format.vprintf(args));
+#endif
+ }
+
+ [Compact]
+ public class ProfileBlock
+ {
+#if ENABLE_PROFILING
+ internal string name;
+ internal int64 start;
+
+ internal ProfileBlock (owned string name) {
+ this.name = (owned) name;
+ this.start = Sysprof.CAPTURE_CURRENT_TIME;
+ }
#endif
}
@@ -79,13 +82,14 @@ namespace Folks.Internal
*
* @param format printf-style message format
* @param ... message arguments
- * @since 0.7.2
*/
- public static void profiling_start (string format, ...)
+ public inline ProfileBlock? profiling_start (string format, ...)
{
#if ENABLE_PROFILING
var args = va_list ();
- Internal.profiling_markv ("START: " + format, args);
+ return new ProfileBlock (format.vprintf (args));
+#else
+ return null;
#endif
}
@@ -98,15 +102,12 @@ namespace Folks.Internal
* This is typically used in a pair with {@link Internal.profiling_start} to
* delimit blocks of processing which need timing.
*
- * @param format printf-style message format
- * @param ... message arguments
- * @since 0.7.2
+ * @param block the ProfileBlock given by profiling_start
*/
- public static void profiling_end (string format, ...)
+ public inline void profiling_end (owned ProfileBlock? block)
{
#if ENABLE_PROFILING
- var args = va_list ();
- Internal.profiling_markv ("END: " + format, args);
+ Sysprof.Collector.mark (block.start, Sysprof.CAPTURE_CURRENT_TIME - block.start, "folks", block.name);
#endif
}
}
diff --git a/folks/meson.build b/folks/meson.build
index 821a3099..b86f3cc7 100644
--- a/folks/meson.build
+++ b/folks/meson.build
@@ -16,7 +16,8 @@ libfolks_internal_deps = [
libfolks_internal_vala_flags = []
if get_option('profiling')
- libfolks_internal_vala_flags += '-DENABLE_PROFILING'
+ libfolks_internal_vala_flags += '--define=ENABLE_PROFILING'
+ libfolks_internal_deps += sysprof_dep
endif
libfolks_internal = static_library('folks-internal',
diff --git a/meson.build b/meson.build
index 9971f7a2..36329572 100644
--- a/meson.build
+++ b/meson.build
@@ -135,6 +135,11 @@ if inspect_tool_enabled
)
endif
+if get_option('profiling')
+ sysprof_dep = dependency('sysprof-capture-4', version: '>= 3.38.0')
+ add_project_arguments(['--vapidir', meson.current_source_dir() / 'vapi'], language: 'vala')
+endif
+
# Configuration
#-------------------------------------------------
conf = configuration_data()
diff --git a/meson_options.txt b/meson_options.txt
index f631e6bd..361f30cf 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -8,7 +8,7 @@ option('zeitgeist', type: 'boolean', value: false, description: 'build Zeitgeist
option('import_tool', type: 'boolean', value: true, description: 'Enable building the meta-contact import tool')
option('inspect_tool', type: 'boolean', value: true, description: 'Enable building the data inspection tool')
# Profiling
-option('profiling', type: 'boolean', value: false, description: 'Enable profiling code')
+option('profiling', type: 'boolean', value: false, description: 'Enable profiling using sysprof')
# Test options
option('tests', type: 'boolean', value: true, description: 'Build tests programs')
option('installed_tests', type: 'boolean', value: false, description: 'Install test programs')
diff --git a/vapi/sysprof-capture-4.vapi b/vapi/sysprof-capture-4.vapi
new file mode 100644
index 00000000..fac018f0
--- /dev/null
+++ b/vapi/sysprof-capture-4.vapi
@@ -0,0 +1,322 @@
+[CCode (cheader_filename = "sysprof-capture.h")]
+namespace Sysprof {
+ [SimpleType]
+ public struct Address : uint64 {
+ public bool is_context_switch (out AddressContext context);
+ public int compare (Sysprof.Address b);
+ }
+
+ [SimpleType]
+ public struct CaptureAddress : uint64 {
+ public int compare (Sysprof.CaptureAddress b);
+ }
+
+ namespace Collector {
+ public void init ();
+ public bool is_active ();
+ public void allocate (Sysprof.CaptureAddress alloc_addr, int64 alloc_size, Sysprof.BacktraceFunc backtrace_func);
+ public void sample (Sysprof.BacktraceFunc backtrace_func);
+ public void mark (int64 time, int64 duration, string group, string mark, string? message = null);
+ [ PrintfFormat ]
+ public void mark_printf (int64 time, int64 duration, string group, string mark, string message_format, ...);
+ public void mark_vprintf (int64 time, int64 duration, string group, string mark, string message_format, va_list args);
+ public void log (int severity, string domain, string message);
+ [ PrintfFormat ]
+ public void log_printf (int severity, string domain, string message_format, ...);
+ public uint request_counters (uint n_counters);
+ public void define_counters (Sysprof.CaptureCounter[] counters);
+ public void set_counters ([CCode (array_length = false)] uint[] counters_ids, Sysprof.CaptureCounterValue[] values);
+ }
+
+ [CCode (ref_function = "sysprof_capture_condition_ref", unref_function = "sysprof_capture_condition_unref", has_type_id = false)]
+ public class CaptureCondition {
+ public CaptureCondition.and (Sysprof.CaptureCondition left, Sysprof.CaptureCondition right);
+ public CaptureCondition.or (Sysprof.CaptureCondition left, Sysprof.CaptureCondition right);
+ public CaptureCondition.where_counter_in (uint[] counters);
+ public CaptureCondition.where_file (string path);
+ public CaptureCondition.where_pid_in (int32[] pids);
+ public CaptureCondition.where_time_between (int64 begin_time, int64 end_time);
+ public CaptureCondition.where_type_in (Sysprof.CaptureFrameType[] types);
+ public Sysprof.CaptureCondition copy ();
+ public bool match (Sysprof.CaptureFrame frame);
+ }
+
+ [CCode (ref_function = "sysprof_capture_cursor_ref", unref_function = "sysprof_capture_cursor_unref", has_type_id = false)]
+ public class CaptureCursor {
+ public CaptureCursor (Sysprof.CaptureReader reader);
+ public unowned Sysprof.CaptureReader get_reader ();
+ public void add_condition (Sysprof.CaptureCondition condition);
+ public void @foreach (Sysprof.CaptureCursorCallback callback);
+ public void reset ();
+ public void reverse ();
+ }
+
+ [CCode (ref_function = "sysprof_capture_reader_ref", unref_function = "sysprof_capture_reader_unref", has_type_id = false)]
+ public class CaptureReader {
+ public CaptureReader (string filename);
+ public CaptureReader.from_fd (int fd);
+ public bool get_stat (out unowned Sysprof.CaptureStat st_buf);
+ public bool peek_frame (out Sysprof.CaptureFrame frame);
+ public bool peek_type (out Sysprof.CaptureFrameType type);
+ public bool read_file_fd (string path, int fd);
+ public bool reset ();
+ public bool save_as (string filename);
+ public bool skip ();
+ public bool splice (Sysprof.CaptureWriter dest);
+ public int64 get_end_time ();
+ public int64 get_start_time ();
+ public int get_byte_order ();
+ public string get_filename ();
+ public string get_time ();
+ public string[] list_files ();
+ public Sysprof.CaptureReader copy ();
+ public unowned Sysprof.CaptureAllocation read_allocation ();
+ public unowned Sysprof.CaptureCounterDefine read_counter_define ();
+ public unowned Sysprof.CaptureCounterSet read_counter_set ();
+ public unowned Sysprof.CaptureExit read_exit ();
+ public unowned Sysprof.CaptureFileChunk find_file (string path);
+ public unowned Sysprof.CaptureFileChunk read_file ();
+ public unowned Sysprof.CaptureFork read_fork ();
+ public unowned Sysprof.CaptureJitmap read_jitmap ();
+ public unowned Sysprof.CaptureLog read_log ();
+ public unowned Sysprof.CaptureMap read_map ();
+ public unowned Sysprof.CaptureMark read_mark ();
+ public unowned Sysprof.CaptureMetadata read_metadata ();
+ public unowned Sysprof.CaptureProcess read_process ();
+ public unowned Sysprof.CaptureSample read_sample ();
+ public unowned Sysprof.CaptureTimestamp read_timestamp ();
+ public void set_stat (Sysprof.CaptureStat st_buf);
+ }
+
+ [CCode (ref_function = "sysprof_capture_writer_ref", unref_function = "sysprof_capture_writer_unref", has_type_id = false)]
+ public class CaptureWriter {
+ public CaptureWriter (string filename, size_t buffer_size);
+ public CaptureWriter.from_env (size_t buffer_size);
+ public CaptureWriter.from_fd (int fd, size_t buffer_size);
+ public bool add_allocation_copy (int64 time, int cpu, int32 pid, int32 tid, Sysprof.CaptureAddress[] alloc_addr, Sysprof.CaptureAddress[] addrs);
+ public bool add_allocation (int64 time, int cpu, int32 pid, int32 tid, Sysprof.CaptureAddress[] alloc_addr, Sysprof.BacktraceFunc backtrace_func);
+ public bool add_exit (int64 time, int cpu, int32 pid);
+ public bool add_file_fd (int64 time, int cpu, int32 pid, string path, int fd);
+ public bool add_file (int64 time, int cpu, int32 pid, string path, bool is_last, uint8[] data);
+ public bool add_fork (int64 time, int cpu, int32 pid, int32 child_pid);
+ public bool add_jitmap (string name);
+ public bool add_log (int64 time, int cpu, int32 pid, int severity, string domain, string message);
+ public bool add_map (int64 time, int cpu, int32 pid, uint64 start, uint64 end, uint64 offset, uint64 inode, string filename);
+ public bool add_mark (int64 time, int cpu, int32 pid, uint64 duration, string group, string name, string message);
+ public bool add_metadata (int64 time, int cpu, int32 pid, string id, string metadata, ssize_t metadata_len = -1);
+ public bool add_process (int64 time, int cpu, int32 pid, string cmdline);
+ public bool add_sample (int64 time, int cpu, int32 pid, int32 tid, Sysprof.CaptureAddress[] addrs);
+ public bool add_timestamp (int64 time, int cpu, int32 pid);
+ public bool cat (Sysprof.CaptureReader reader);
+ public bool define_counters (int64 time, int cpu, int32 pid, Sysprof.CaptureCounter[] counters);
+ public bool flush ();
+ public bool save_as (string filename);
+ public bool set_counters (int64 time, int cpu, int32 pid, Sysprof.CaptureCounter[] counters, Sysprof.CaptureCounterValue[] values);
+ public bool splice (Sysprof.CaptureWriter dest);
+ public size_t get_buffer_size ();
+ public Sysprof.CaptureReader create_reader ();
+ public uint request_counter (uint n_counters);
+ public void stat (out Sysprof.CaptureStat stat);
+ }
+
+ [Compact]
+ public class CaptureJitmapIter {
+ void* p1;
+ void* p2;
+ uint u1;
+ void* p3;
+ void* p4;
+ [CCode (cname="sysprof_capture_jitmap_iter_init")]
+ public CaptureJitmapIter (Sysprof.CaptureJitmap jitmap);
+ public bool next (ref Sysprof.CaptureAddress addr, out unowned string[] path);
+ }
+
+ public struct CaptureStat {
+ size_t frame_count[16];
+ }
+
+ public struct CaptureCounterValue {
+ int64 v64;
+ double vdbl;
+ }
+
+ public struct CaptureFileHeader {
+ uint32 magic;
+ uint32 version;
+ uint32 little_endian;
+ uint32 padding;
+ char capture_time[64];
+ int64 time;
+ int64 end_time;
+ char suffix[168];
+ }
+
+ public struct CaptureFrame {
+ uint16 len;
+ int16 cpu;
+ int32 pid;
+ int64 time;
+ uint32 type;
+ uint32 padding1;
+ uint32 padding2;
+ uint8[] data;
+ }
+
+ public struct CaptureMap {
+ Sysprof.CaptureFrame frame;
+ uint64 start;
+ uint64 end;
+ uint64 offset;
+ uint64 inode;
+ char[] filename;
+ }
+
+ public struct CaptureJitmap {
+ Sysprof.CaptureFrame frame;
+ uint32 n_jitmaps;
+ uint8[] data;
+ }
+
+ public struct CaptureProcess {
+ Sysprof.CaptureFrame frame;
+ char[] cmdline;
+ }
+
+ public struct CaptureSample {
+ Sysprof.CaptureFrame frame;
+ uint32 n_addrs;
+ uint32 padding1;
+ int32 tid;
+ Sysprof.CaptureAddress[] addrs;
+ }
+
+ public struct CaptureFork {
+ Sysprof.CaptureFrame frame;
+ int32 child_pid;
+ }
+
+ public struct CaptureExit {
+ Sysprof.CaptureFrame frame;
+ }
+
+ public struct CaptureTimestamp {
+ Sysprof.CaptureFrame frame;
+ }
+
+ public struct CaptureCounter {
+ char category[32];
+ char name[32];
+ char description[52];
+ uint32 id;
+ uint32 type;
+ }
+
+ public struct CaptureCounterDefine {
+ Sysprof.CaptureFrame frame;
+ uint32 n_counters;
+ uint32 padding1;
+ uint32 padding2;
+ Sysprof.CaptureCounter[] counters;
+ }
+
+ public struct CaptureCounterValues {
+ uint32 ids[8];
+ Sysprof.CaptureCounterValue values[8];
+ }
+
+ public struct CaptureCounterSet {
+ Sysprof.CaptureFrame frame;
+ uint32 n_values;
+ uint32 padding1;
+ uint32 padding2;
+ Sysprof.CaptureCounterValues[] values;
+ }
+
+ public struct CaptureMark {
+ Sysprof.CaptureFrame frame;
+ int64 duration;
+ char group[24];
+ char name[40];
+ char[] message;
+ }
+
+ public struct CaptureMetadata {
+ Sysprof.CaptureFrame frame;
+ char id[40];
+ char[] metadata;
+ }
+
+ public struct CaptureLog {
+ Sysprof.CaptureFrame frame;
+ uint32 severity;
+ uint32 padding1;
+ uint32 padding2;
+ char domain[32];
+ char[] message;
+ }
+
+ public struct CaptureFileChunk {
+ Sysprof.CaptureFrame frame;
+ uint32 is_last;
+ uint32 padding1;
+ uint32 len;
+ char path[256];
+ uint8[] data;
+ }
+
+ public struct CaptureAllocation {
+ Sysprof.CaptureFrame frame;
+ Sysprof.CaptureAddress alloc_addr;
+ int64 alloc_size;
+ int32 tid;
+ uint32 n_addrs;
+ uint32 padding1;
+ Sysprof.CaptureAddress[] addrs;
+ }
+
+ public enum CaptureFrameType {
+ TIMESTAMP,
+ SAMPLE,
+ MAP,
+ PROCESS,
+ FORK,
+ EXIT,
+ JITMAP,
+ CTRDEF,
+ CTRSET,
+ MARK,
+ METADATA,
+ LOG,
+ FILE_CHUNK,
+ ALLOCATION,
+ }
+
+ public enum AddressContext {
+ NONE,
+ HYPERVISOR,
+ KERNEL,
+ USER,
+ GUEST,
+ GUEST_KERNEL,
+ GUEST_USER;
+ public unowned string to_string ();
+ }
+
+ [CCode (cheader_filename = "sysprof-capture.h", instance_pos = 2.9)]
+ public delegate int BacktraceFunc (ref Sysprof.CaptureAddress[] addrs);
+ [CCode (cheader_filename = "sysprof-capture.h", instance_pos = 1.9)]
+ public delegate bool CaptureCursorCallback (Sysprof.CaptureFrame frame);
+ [CCode (cname = "SYSPROF_CAPTURE_CURRENT_TIME")]
+ public const int64 CAPTURE_CURRENT_TIME;
+ [CCode (cname = "SYSPROF_CAPTURE_COUNTER_INT64")]
+ public const uint32 CAPTURE_COUNTER_INT64;
+ [CCode (cname = "SYSPROF_CAPTURE_COUNTER_DOUBLE")]
+ public const uint32 CAPTURE_COUNTER_DOUBLE;
+ [CCode (cname = "SYSPROF_CAPTURE_ADDRESS_FORMAT")]
+ public const string CAPTURE_ADDRESS_FORMAT;
+ [CCode (cname = "SYSPROF_CAPTURE_JITMAP_MARK")]
+ public const uint64 CAPTURE_JITMAP_MARK;
+ public static int memfd_create (string desc);
+ [CCode (cname = "sysprof_getpagesize")]
+ public static size_t get_page_size ();
+}