b6e4c8cd86ebfba1fd095d570aeee8988cc65c52
[lttng-tools.git] / src / lib / lttng-ctl / buffer-usage.c
1 /*
2 * Copyright (C) 2017 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License, version 2.1 only,
6 * as published by the Free Software Foundation.
7 *
8 * This library is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11 * for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17
18 #include <lttng/condition/condition-internal.h>
19 #include <lttng/condition/buffer-usage-internal.h>
20 #include <common/macros.h>
21 #include <assert.h>
22
23 static
24 bool is_usage_condition(struct lttng_condition *condition)
25 {
26 enum lttng_condition_type type = lttng_condition_get_type(condition);
27
28 return type == LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW ||
29 type == LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH;
30 }
31
32 static
33 bool is_usage_evaluation(struct lttng_evaluation *evaluation)
34 {
35 enum lttng_condition_type type = lttng_evaluation_get_type(evaluation);
36
37 return type == LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW ||
38 type == LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH;
39 }
40
41 static
42 void lttng_condition_buffer_usage_destroy(struct lttng_condition *condition)
43 {
44 struct lttng_condition_buffer_usage *usage;
45
46 usage = container_of(condition, struct lttng_condition_buffer_usage,
47 parent);
48
49 free(usage->session_name);
50 free(usage->channel_name);
51 free(usage);
52 }
53
54 static
55 bool lttng_condition_buffer_usage_validate(struct lttng_condition *condition)
56 {
57 bool valid = false;
58 struct lttng_condition_buffer_usage *usage;
59
60 if (!condition) {
61 goto end;
62 }
63
64 usage = container_of(condition, struct lttng_condition_buffer_usage,
65 parent);
66 if (!usage->session_name) {
67 goto end;
68 }
69 if (!usage->channel_name) {
70 goto end;
71 }
72 if (!usage->threshold_percent.set && !usage->threshold_bytes.set) {
73 goto end;
74 }
75
76 valid = true;
77 end:
78 return valid;
79 }
80
81 static
82 struct lttng_condition *lttng_condition_buffer_usage_create(
83 enum lttng_condition_type type)
84 {
85 struct lttng_condition_buffer_usage *condition;
86
87 condition = zmalloc(sizeof(struct lttng_condition_buffer_usage));
88 if (!condition) {
89 goto end;
90 }
91
92 condition->parent.type = type;
93 condition->parent.validate = lttng_condition_buffer_usage_validate;
94 condition->parent.destroy = lttng_condition_buffer_usage_destroy;
95 end:
96 return &condition->parent;
97 }
98
99 struct lttng_condition *lttng_condition_buffer_usage_low_create(void)
100 {
101 return lttng_condition_buffer_usage_create(
102 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW);
103 }
104
105 struct lttng_condition *lttng_condition_buffer_usage_high_create(void)
106 {
107 return lttng_condition_buffer_usage_create(
108 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH);
109 }
110
111 enum lttng_condition_status
112 lttng_condition_buffer_usage_get_threshold_percentage(
113 struct lttng_condition *condition, double *threshold_percent)
114 {
115 struct lttng_condition_buffer_usage *usage;
116 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
117
118 if (!condition || !is_usage_condition(condition) ||
119 !threshold_percent) {
120 status = LTTNG_CONDITION_STATUS_INVALID;
121 goto end;
122 }
123
124 usage = container_of(condition, struct lttng_condition_buffer_usage,
125 parent);
126 if (!usage->threshold_percent.set) {
127 status = LTTNG_CONDITION_STATUS_UNSET;
128 goto end;
129 }
130 *threshold_percent = usage->threshold_percent.value;
131 end:
132 return status;
133 }
134
135 /* threshold_percent expressed as [0.0, 1.0]. */
136 enum lttng_condition_status
137 lttng_condition_buffer_usage_set_threshold_percentage(
138 struct lttng_condition *condition, double threshold_percent)
139 {
140 struct lttng_condition_buffer_usage *usage;
141 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
142
143 if (!condition || !is_usage_condition(condition) ||
144 threshold_percent < 0.0 || threshold_percent > 1.0) {
145 status = LTTNG_CONDITION_STATUS_INVALID;
146 goto end;
147 }
148
149 usage = container_of(condition, struct lttng_condition_buffer_usage,
150 parent);
151 usage->threshold_percent.set = true;
152 usage->threshold_bytes.set = false;
153 usage->threshold_percent.value = threshold_percent;
154 end:
155 return status;
156 }
157
158 enum lttng_condition_status
159 lttng_condition_buffer_usage_get_threshold(
160 struct lttng_condition *condition, uint64_t *threshold_bytes)
161 {
162 struct lttng_condition_buffer_usage *usage;
163 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
164
165 if (!condition || !is_usage_condition(condition) || !threshold_bytes) {
166 status = LTTNG_CONDITION_STATUS_INVALID;
167 goto end;
168 }
169
170 usage = container_of(condition, struct lttng_condition_buffer_usage,
171 parent);
172 if (!usage->threshold_bytes.set) {
173 status = LTTNG_CONDITION_STATUS_UNSET;
174 goto end;
175 }
176 *threshold_bytes = usage->threshold_bytes.value;
177 end:
178 return status;
179 }
180
181 enum lttng_condition_status
182 lttng_condition_buffer_usage_set_threshold(
183 struct lttng_condition *condition, uint64_t threshold_bytes)
184 {
185 struct lttng_condition_buffer_usage *usage;
186 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
187
188 if (!condition || !is_usage_condition(condition)) {
189 status = LTTNG_CONDITION_STATUS_INVALID;
190 goto end;
191 }
192
193 usage = container_of(condition, struct lttng_condition_buffer_usage,
194 parent);
195 usage->threshold_percent.set = false;
196 usage->threshold_bytes.set = true;
197 usage->threshold_bytes.value = threshold_bytes;
198 end:
199 return status;
200 }
201
202 enum lttng_condition_status
203 lttng_condition_buffer_usage_get_session_name(
204 struct lttng_condition *condition, const char **session_name)
205 {
206 struct lttng_condition_buffer_usage *usage;
207 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
208
209 if (!condition || !is_usage_condition(condition) || !session_name) {
210 status = LTTNG_CONDITION_STATUS_INVALID;
211 goto end;
212 }
213
214 usage = container_of(condition, struct lttng_condition_buffer_usage,
215 parent);
216 if (!usage->session_name) {
217 status = LTTNG_CONDITION_STATUS_UNSET;
218 goto end;
219 }
220 *session_name = usage->session_name;
221 end:
222 return status;
223 }
224
225 extern enum lttng_condition_status
226 lttng_condition_buffer_usage_set_session_name(
227 struct lttng_condition *condition, const char *session_name)
228 {
229 struct lttng_condition_buffer_usage *usage;
230 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
231
232 if (!condition || !is_usage_condition(condition) || !session_name ||
233 strlen(session_name) == 0) {
234 status = LTTNG_CONDITION_STATUS_INVALID;
235 goto end;
236 }
237
238 usage = container_of(condition, struct lttng_condition_buffer_usage,
239 parent);
240 usage->session_name = strdup(session_name);
241 if (!usage->session_name) {
242 status = LTTNG_CONDITION_STATUS_ERROR;
243 goto end;
244 }
245 end:
246 return status;
247 }
248
249 enum lttng_condition_status
250 lttng_condition_buffer_usage_get_channel_name(
251 struct lttng_condition *condition, const char **channel_name)
252 {
253 struct lttng_condition_buffer_usage *usage;
254 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
255
256 if (!condition || !is_usage_condition(condition) || !channel_name) {
257 status = LTTNG_CONDITION_STATUS_INVALID;
258 goto end;
259 }
260
261 usage = container_of(condition, struct lttng_condition_buffer_usage,
262 parent);
263 if (!usage->channel_name) {
264 status = LTTNG_CONDITION_STATUS_UNSET;
265 goto end;
266 }
267 *channel_name = usage->channel_name;
268 end:
269 return status;
270 }
271
272 extern enum lttng_condition_status
273 lttng_condition_buffer_usage_set_channel_name(
274 struct lttng_condition *condition, const char *channel_name)
275 {
276 struct lttng_condition_buffer_usage *usage;
277 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
278
279 if (!condition || !is_usage_condition(condition) || !channel_name ||
280 strlen(channel_name) == 0) {
281 status = LTTNG_CONDITION_STATUS_INVALID;
282 goto end;
283 }
284
285 usage = container_of(condition, struct lttng_condition_buffer_usage,
286 parent);
287 usage->channel_name = strdup(channel_name);
288 if (!usage->channel_name) {
289 status = LTTNG_CONDITION_STATUS_ERROR;
290 goto end;
291 }
292 end:
293 return status;
294 }
295
296 extern enum lttng_condition_status
297 lttng_condition_buffer_usage_get_domain_type(
298 struct lttng_condition *condition, enum lttng_domain_type *type)
299 {
300 struct lttng_condition_buffer_usage *usage;
301 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
302
303 if (!condition || !is_usage_condition(condition) || !type) {
304 status = LTTNG_CONDITION_STATUS_INVALID;
305 goto end;
306 }
307
308 usage = container_of(condition, struct lttng_condition_buffer_usage,
309 parent);
310 if (!usage->domain.set) {
311 status = LTTNG_CONDITION_STATUS_UNSET;
312 goto end;
313 }
314 *type = usage->domain.type;
315 end:
316 return status;
317 }
318
319 extern enum lttng_condition_status
320 lttng_condition_buffer_usage_set_domain_type(
321 struct lttng_condition *condition, enum lttng_domain_type type)
322 {
323 struct lttng_condition_buffer_usage *usage;
324 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
325
326 if (!condition || !is_usage_condition(condition) ||
327 type == LTTNG_DOMAIN_NONE) {
328 status = LTTNG_CONDITION_STATUS_INVALID;
329 goto end;
330 }
331
332 usage = container_of(condition, struct lttng_condition_buffer_usage,
333 parent);
334 usage->domain.set = true;
335 usage->domain.type = type;
336 end:
337 return status;
338 }
339
340 static
341 void lttng_evaluation_buffer_usage_destroy(
342 struct lttng_evaluation *evaluation)
343 {
344 struct lttng_evaluation_buffer_usage *usage;
345
346 usage = container_of(evaluation, struct lttng_evaluation_buffer_usage,
347 parent);
348 free(usage);
349 }
350
351 LTTNG_HIDDEN
352 struct lttng_evaluation *lttng_evaluation_buffer_usage_create(uint64_t use,
353 uint64_t capacity)
354 {
355 struct lttng_evaluation_buffer_usage *usage;
356
357 usage = zmalloc(sizeof(struct lttng_evaluation_buffer_usage));
358 if (!usage) {
359 goto end;
360 }
361
362 usage->buffer_use = use;
363 usage->buffer_capacity = capacity;
364 usage->parent.destroy = lttng_evaluation_buffer_usage_destroy;
365 end:
366 return &usage->parent;
367 }
368
369 /*
370 * Get the sampled buffer usage which caused the associated condition to
371 * evaluate to "true".
372 */
373 enum lttng_evaluation_status
374 lttng_evaluation_buffer_usage_get_usage_percentage(
375 struct lttng_evaluation *evaluation, double *usage_percent)
376 {
377 struct lttng_evaluation_buffer_usage *usage;
378 enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
379
380 if (!evaluation || !is_usage_evaluation(evaluation) || !usage_percent) {
381 status = LTTNG_EVALUATION_STATUS_INVALID;
382 goto end;
383 }
384
385 usage = container_of(evaluation, struct lttng_evaluation_buffer_usage,
386 parent);
387 *usage_percent = (double) usage->buffer_use /
388 (double) usage->buffer_capacity;
389 end:
390 return status;
391 }
392
393 enum lttng_evaluation_status
394 lttng_evaluation_buffer_usage_get_usage(struct lttng_evaluation *evaluation,
395 uint64_t *usage_bytes)
396 {
397 struct lttng_evaluation_buffer_usage *usage;
398 enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
399
400 if (!evaluation || !is_usage_evaluation(evaluation) || !usage_bytes) {
401 status = LTTNG_EVALUATION_STATUS_INVALID;
402 goto end;
403 }
404
405 usage = container_of(evaluation, struct lttng_evaluation_buffer_usage,
406 parent);
407 *usage_bytes = usage->buffer_use;
408 end:
409 return status;
410 }
This page took 0.038544 seconds and 4 git commands to generate.