Skip to content

Commit 49d0430

Browse files
jeremypwJeremy Woottenzeebokleonardo-lemos
authored
Profiling: Enable profiling in code using google-perftools (#1539)
* Optionally link in profiler library * Get profiler to link properly * Add libprofiler.vapi and start/stop profiling in code * Amend comment and message * Add optional heap profiling * Default to profiling off * Amend comments, remove extra comma * Amend option descriptions * Fix heap profiling withut cpu profiling * Amend comments and path names * Correct dev library * More comments, customized output file names --------- Co-authored-by: Jeremy Wootten <jeremy@Proteus-EL07R6-9b3c42bb.localdomain> Co-authored-by: Ryan Kornheisl <ryan@skarva.tech> Co-authored-by: Leonardo Lemos <leonardolemos@live.com>
1 parent 96909fd commit 49d0430

File tree

5 files changed

+86
-0
lines changed

5 files changed

+86
-0
lines changed

meson.build

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,40 @@ if get_option('development') and git.found ()
7373
branch = output.stdout().strip()
7474
endif
7575

76+
# Profiler linking code taken from https://github.com/RidgeRun/gst-inference/blob/master/meson.build
77+
# with some amendments
78+
# 'libprofiler' and 'libtcmalloc' are provided by installing (e.g.) 'google-perftools' and 'libgoogle-pertools-dev'
79+
# Profiling is not active unless either the correct environment variables are set at runtime
80+
# or the profiling is switched on/off in the code using the CPU_PROFILING and HEAP_PROFILING conditional compilation flags
81+
# with the commands Profiler.start (<path-to-profile-output>) and Profiler.stop () and the corresponding HeapProfiler functions
82+
# It is advisable not to run cpu profiling at the same time as heap profiling
83+
# If meson options are changed then rebuild with 'cd .. && sudo rm -R ./build && build'
84+
# See https://github.com/gperftools/gperftools/blob/master/docs/cpuprofile.adoc
85+
# and https://github.com/gperftools/gperftools/blob/master/docs/heapprofile.adoc
86+
if get_option('cpu-profiling-enabled')
87+
profiler_dep = dependency ('libprofiler')
88+
if(profiler_dep.found())
89+
message('CPU profiling enabled: Building with profiling support.')
90+
add_global_link_arguments ('-lprofiler', language: 'c')
91+
add_project_arguments ('--define=PROFILING', language: 'vala')
92+
dependencies += profiler_dep
93+
else
94+
message('MESON_FAIL: CPU profiling requested but libprofiler (gperftools) not found.')
95+
endif
96+
endif
97+
if get_option('heap-profiling-enabled')
98+
heap_profiler_dep = dependency ('libtcmalloc')
99+
if(heap_profiler_dep.found())
100+
message('Heap profiling enabled: Building with heap profiling support.')
101+
add_global_link_arguments ('-ltcmalloc', language: 'c')
102+
add_project_arguments ('--define=HEAP_PROFILING', language: 'vala')
103+
dependencies += heap_profiler_dep
104+
else
105+
message('MESON_FAIL: Heap profiling requested but libtcmalloc (gperftools) not found.')
106+
endif
107+
endif
108+
109+
76110
subdir('data')
77111
subdir('src')
78112
if get_option('plugins')

meson_options.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
option('plugins', type : 'boolean', value : true)
22
option('have_pkexec', type : 'boolean', value : true, description : 'Allow launching with pkexec. Should not be used in FlatPak')
33
option('development', type : 'boolean', value : false, description : 'Build is a development branch')
4+
option('cpu-profiling-enabled', type : 'boolean', value : false, description: 'Enable cpu profiling')
5+
option('heap-profiling-enabled', type : 'boolean', value : false, description: 'Enable heap profiling')

src/Application.vala

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,39 @@ namespace Scratch {
200200
}
201201

202202
public static int main (string[] args) {
203+
// By default, profile whole app when profiling is enabled in meson_options.txt
204+
// These conditional statements can be moved to profile sections of code
205+
// The gperftools library must be installed (libgoogle-perftools-dev)
206+
// Amend the profile report paths as required
207+
#if PROFILING
208+
// Visualize the cpu profile with e.g. google-pprof --functions --gv /usr/bin/io.elementary.code <profile_path>
209+
// Use --focus=<regexp> and --ignore=<regexp> to filter/prune nodes displayed
210+
var profile_path = Path.build_filename (Environment.get_home_dir (), "CpuProfileCodeApplication.prof");
211+
// Start CPU profiling
212+
Profiler.start (profile_path);
213+
warning ("start cpu profiling - output to %s", profile_path);
214+
#endif
215+
#if HEAP_PROFILING
216+
// NOTE: Heap profiling at this point slows the program down **a lot** It will take tens of seconds to load.
217+
// The output path will have the suffix '.NNNN.heap' appended
218+
// Visualize the profile with e.g. google-pprof --gv /usr/bin/io.elementary.code <profile_path>
219+
// Use --focus=<regexp> and --ignore=<regexp> to filter/prune nodes displayed
220+
var heap_profile_path = Path.build_filename (Environment.get_home_dir (), "HeapProfileCodeApplication");
221+
// Start heap profiling
222+
HeapProfiler.start (heap_profile_path);
223+
warning ("start heap profiling - output to %s", heap_profile_path);
224+
#endif
225+
203226
return new Application ().run (args);
227+
228+
#if PROFILING
229+
Profiler.stop ();
230+
warning ("stop cpu profiling");
231+
#endif
232+
#if HEAP_PROFILING
233+
HeapProfiler.stop ();
234+
warning ("stop heap profiling");
235+
#endif
204236
}
205237
}
206238
}

vapi/libprofiler.vapi

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[CCode (cheader_filename = "gperftools/profiler.h")]
2+
namespace Profiler {
3+
[CCode (cname = "ProfilerStart")]
4+
public static void start (string path_to_output_file);
5+
[CCode (cname = "ProfilerStop")]
6+
public static void stop ();
7+
[CCode (cname = "ProfilerFlush")]
8+
public static void flush ();
9+
}

vapi/libtcmalloc.vapi

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[CCode (cheader_filename = "gperftools/heap-profiler.h")]
2+
namespace HeapProfiler {
3+
[CCode (cname = "HeapProfilerStart")]
4+
public static void start (string path_to_output_file_profix);
5+
[CCode (cname = "HeapProfilerStop")]
6+
public static void stop ();
7+
[CCode (cname = "HeapProfilerDump")]
8+
public static void dump (string reason);
9+
}

0 commit comments

Comments
 (0)