[gjs/wip/chergert/sysprof-3: 2/3] profiler: record duration of GC sweeps



commit 7d2fb9389d2a70b9dd1bd7470e44961a6504aa19
Author: Christian Hergert <chergert redhat com>
Date:   Mon Jun 3 14:09:44 2019 -0700

    profiler: record duration of GC sweeps
    
    Now that we are using sysprof-capture-3, we can record marks from the
    various subsystems in GJS. This adds marks to the capture when we perform
    a GC sweep operation.
    
    Related to GNOME/Initiatives#10

 gjs/context-private.h  |  5 ++++-
 gjs/context.cpp        | 20 ++++++++++++++++++++
 gjs/profiler-private.h |  4 ++++
 gjs/profiler.cpp       | 13 +++++++++++++
 4 files changed, 41 insertions(+), 1 deletion(-)
---
diff --git a/gjs/context-private.h b/gjs/context-private.h
index 10dcf688..274352fa 100644
--- a/gjs/context-private.h
+++ b/gjs/context-private.h
@@ -117,6 +117,8 @@ class GjsContextPrivate {
     bool m_should_profile : 1;
     bool m_should_listen_sigusr2 : 1;
 
+    int64_t m_sweep_begin_time;
+
     void schedule_gc_internal(bool force_gc);
     static gboolean trigger_gc_if_needed(void* data);
     static gboolean drain_job_queue_idle_handler(void* data);
@@ -148,7 +150,6 @@ class GjsContextPrivate {
     GJS_USE const GjsAtoms& atoms(void) const { return m_atoms; }
     GJS_USE bool destroying(void) const { return m_destroying; }
     GJS_USE bool sweeping(void) const { return m_in_gc_sweep; }
-    void set_sweeping(bool value) { m_in_gc_sweep = value; }
     GJS_USE const char* program_name(void) const { return m_program_name; }
     void set_program_name(char* value) { m_program_name = value; }
     void set_search_path(char** value) { m_search_path = value; }
@@ -194,6 +195,8 @@ class GjsContextPrivate {
     void register_unhandled_promise_rejection(uint64_t id, GjsAutoChar&& stack);
     void unregister_unhandled_promise_rejection(uint64_t id);
 
+    void set_sweeping(bool value);
+
     static void trace(JSTracer* trc, void* data);
 
     void free_profiler(void);
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 0ac7fb68..6e2d54af 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -609,6 +609,26 @@ void GjsContextPrivate::schedule_gc_if_needed(void) {
     schedule_gc_internal(false);
 }
 
+void GjsContextPrivate::set_sweeping(bool value) {
+    // If we have a profiler enabled, record the duration of GC sweep
+    if (this->m_profiler != nullptr) {
+        int64_t now = g_get_monotonic_time() * 1000L;
+
+        if (value) {
+            m_sweep_begin_time = now;
+        } else {
+            if (m_sweep_begin_time != 0) {
+                _gjs_profiler_add_mark(this->m_profiler, m_sweep_begin_time,
+                                       now - m_sweep_begin_time, "GJS", "Sweep",
+                                       nullptr);
+                m_sweep_begin_time = 0;
+            }
+        }
+    }
+
+    m_in_gc_sweep = value;
+}
+
 void GjsContextPrivate::exit(uint8_t exit_code) {
     g_assert(!m_should_exit);
     m_should_exit = true;
diff --git a/gjs/profiler-private.h b/gjs/profiler-private.h
index 20cb9f46..0697be25 100644
--- a/gjs/profiler-private.h
+++ b/gjs/profiler-private.h
@@ -33,6 +33,10 @@ G_BEGIN_DECLS
 GjsProfiler *_gjs_profiler_new(GjsContext *context);
 void _gjs_profiler_free(GjsProfiler *self);
 
+void _gjs_profiler_add_mark(GjsProfiler* self, gint64 time, gint64 duration,
+                            const char* group, const char* name,
+                            const char* message);
+
 GJS_USE
 bool _gjs_profiler_is_running(GjsProfiler *self);
 
diff --git a/gjs/profiler.cpp b/gjs/profiler.cpp
index b332b859..a6883aaf 100644
--- a/gjs/profiler.cpp
+++ b/gjs/profiler.cpp
@@ -639,3 +639,16 @@ gjs_profiler_set_filename(GjsProfiler *self,
     g_free(self->filename);
     self->filename = g_strdup(filename);
 }
+
+void _gjs_profiler_add_mark(GjsProfiler* self, gint64 time_nsec,
+                            gint64 duration_nsec, const char* group,
+                            const char* name, const char* message) {
+    g_return_if_fail(self);
+    g_return_if_fail(group);
+    g_return_if_fail(name);
+
+    if (self->running && self->capture != nullptr) {
+        sysprof_capture_writer_add_mark(self->capture, time_nsec, -1, self->pid,
+                                        duration_nsec, group, name, message);
+    }
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]