/src/gstreamer/subprojects/glib-2.86.3/glib/gtrace.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright © 2020 Endless Mobile, Inc. |
3 | | * |
4 | | * SPDX-License-Identifier: LGPL-2.1-or-later |
5 | | * |
6 | | * This library is free software; you can redistribute it and/or |
7 | | * modify it under the terms of the GNU Lesser General Public |
8 | | * License as published by the Free Software Foundation; either |
9 | | * version 2.1 of the License, or (at your option) any later version. |
10 | | * |
11 | | * This library is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | | * Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU Lesser General Public |
17 | | * License along with this library; if not, see <http://www.gnu.org/licenses/>. |
18 | | * |
19 | | * Author: Philip Withnall <withnall@endlessm.com> |
20 | | */ |
21 | | |
22 | | /* |
23 | | * The performance tracing functions allow for the performance of code using |
24 | | * GLib to be measured by passing metrics from the current process to an |
25 | | * external measurement process such as `sysprof-cli` or `sysprofd`. |
26 | | * |
27 | | * They are designed to execute quickly, especially in the common case where no |
28 | | * measurement process is connected. They are guaranteed to not block the caller |
29 | | * and are guaranteed to have zero runtime cost if tracing support is disabled |
30 | | * at configure time. |
31 | | * |
32 | | * Tracing information can be provided as ‘marks’ with a start time and |
33 | | * duration; or as marks with a start time and no duration. Marks with a |
34 | | * duration are intended to show the execution time of a piece of code. Marks |
35 | | * with no duration are intended to show an instantaneous performance problem, |
36 | | * such as an unexpectedly large allocation, or that a slow path has been taken |
37 | | * in some code. |
38 | | * |
39 | | * |[<!-- language="C" --> |
40 | | * gint64 begin_time_nsec G_GNUC_UNUSED; |
41 | | * |
42 | | * begin_time_nsec = G_TRACE_CURRENT_TIME; |
43 | | * |
44 | | * // some code which might take a while |
45 | | * |
46 | | * g_trace_mark (begin_time_nsec, G_TRACE_CURRENT_TIME - begin_time_nsec, |
47 | | * "GLib", "GSource.dispatch", |
48 | | * "%s ⇒ %s", g_source_get_name (source), need_destroy ? "destroy" : "keep"); |
49 | | * ]| |
50 | | * |
51 | | * The tracing API is currently internal to GLib. |
52 | | * |
53 | | * Since: 2.66 |
54 | | */ |
55 | | |
56 | | #include "config.h" |
57 | | |
58 | | #include "gtrace-private.h" |
59 | | |
60 | | #include <stdarg.h> |
61 | | |
62 | | /* |
63 | | * g_trace_mark: |
64 | | * @begin_time_nsec: start time of the mark, as returned by %G_TRACE_CURRENT_TIME |
65 | | * @duration_nsec: duration of the mark, in nanoseconds |
66 | | * @group: name of the group for categorising this mark |
67 | | * @name: name of the mark |
68 | | * @message_format: format for the detailed message for the mark, in `printf()` format |
69 | | * @...: arguments to substitute into @message_format; none of these should have |
70 | | * side effects |
71 | | * |
72 | | * Add a mark to the trace, starting at @begin_time_nsec and having length |
73 | | * @duration_nsec (which may be zero). The @group should typically be `GLib`, |
74 | | * and the @name should concisely describe the call site. |
75 | | * |
76 | | * All of the arguments to this function must not have side effects, as the |
77 | | * entire function call may be dropped if sysprof support is not available. |
78 | | * |
79 | | * Since: 2.66 |
80 | | */ |
81 | | void |
82 | | (g_trace_mark) (gint64 begin_time_nsec, |
83 | | gint64 duration_nsec, |
84 | | const gchar *group, |
85 | | const gchar *name, |
86 | | const gchar *message_format, |
87 | | ...) |
88 | 0 | { |
89 | | #ifdef HAVE_SYSPROF |
90 | | va_list args; |
91 | | |
92 | | va_start (args, message_format); |
93 | | sysprof_collector_mark_vprintf (begin_time_nsec, duration_nsec, group, name, message_format, args); |
94 | | va_end (args); |
95 | | #endif /* HAVE_SYSPROF */ |
96 | 0 | } |
97 | | |
98 | | /* |
99 | | * g_trace_define_int64_counter: |
100 | | * @group: name of the group for categorising this counter |
101 | | * @name: name of the counter |
102 | | * @description: description for the counter |
103 | | * |
104 | | * Defines a new counter with integer values. |
105 | | * |
106 | | * The name should be unique within all counters defined with |
107 | | * the same @group. The description will be shown in the sysprof UI. |
108 | | * |
109 | | * To add entries for this counter to a trace, use |
110 | | * g_trace_set_int64_counter(). |
111 | | * |
112 | | * Returns: ID of the counter, for use with g_trace_set_int64_counter(), |
113 | | * guaranteed to never be zero |
114 | | * |
115 | | * Since: 2.68 |
116 | | */ |
117 | | guint |
118 | | (g_trace_define_int64_counter) (const char *group, |
119 | | const char *name, |
120 | | const char *description) |
121 | 0 | { |
122 | | #ifdef HAVE_SYSPROF |
123 | | SysprofCaptureCounter counter; |
124 | | |
125 | | counter.id = sysprof_collector_request_counters (1); |
126 | | |
127 | | /* sysprof not enabled? */ |
128 | | if (counter.id == 0) |
129 | | return (guint) -1; |
130 | | |
131 | | counter.type = SYSPROF_CAPTURE_COUNTER_INT64; |
132 | | counter.value.v64 = 0; |
133 | | g_strlcpy (counter.category, group, sizeof counter.category); |
134 | | g_strlcpy (counter.name, name, sizeof counter.name); |
135 | | g_strlcpy (counter.description, description, sizeof counter.description); |
136 | | |
137 | | sysprof_collector_define_counters (&counter, 1); |
138 | | |
139 | | g_assert (counter.id != 0); |
140 | | |
141 | | return counter.id; |
142 | | #else |
143 | 0 | return (guint) -1; |
144 | 0 | #endif |
145 | 0 | } |
146 | | |
147 | | /* |
148 | | * g_trace_set_int64_counter: |
149 | | * @id: ID of the counter |
150 | | * @val: the value to set the counter to |
151 | | * |
152 | | * Adds a counter value to a trace. |
153 | | * |
154 | | * The ID must be obtained via g_trace_define_int64_counter() |
155 | | * before using this function. |
156 | | * |
157 | | * Since: 2.68 |
158 | | */ |
159 | | void |
160 | | (g_trace_set_int64_counter) (guint id, |
161 | | gint64 val) |
162 | 0 | { |
163 | | #ifdef HAVE_SYSPROF |
164 | | SysprofCaptureCounterValue value; |
165 | | |
166 | | g_return_if_fail (id != 0); |
167 | | |
168 | | /* Ignore setting the counter if we failed to define it in the first place. */ |
169 | | if (id == (guint) -1) |
170 | | return; |
171 | | |
172 | | value.v64 = val; |
173 | | sysprof_collector_set_counters (&id, &value, 1); |
174 | | #endif |
175 | 0 | } |