Force usage of assert() condition when NDEBUG is defined
[lttng-tools.git] / src / common / conditions / buffer-usage.c
CommitLineData
a58c490f 1/*
ab5be9fa 2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
a58c490f 3 *
ab5be9fa 4 * SPDX-License-Identifier: LGPL-2.1-only
a58c490f 5 *
a58c490f
JG
6 */
7
6a751b95
JR
8#include <common/error.h>
9#include <common/macros.h>
10#include <common/mi-lttng.h>
a58c490f 11#include <float.h>
6a751b95
JR
12#include <lttng/condition/buffer-usage-internal.h>
13#include <lttng/condition/condition-internal.h>
14#include <math.h>
a58c490f
JG
15#include <time.h>
16
17#define IS_USAGE_CONDITION(condition) ( \
18 lttng_condition_get_type(condition) == LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW || \
19 lttng_condition_get_type(condition) == LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH \
20 )
21
a58c490f
JG
22static
23bool is_usage_evaluation(const struct lttng_evaluation *evaluation)
24{
25 enum lttng_condition_type type = lttng_evaluation_get_type(evaluation);
26
27 return type == LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW ||
28 type == LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH;
29}
30
31static
32void lttng_condition_buffer_usage_destroy(struct lttng_condition *condition)
33{
34 struct lttng_condition_buffer_usage *usage;
35
36 usage = container_of(condition, struct lttng_condition_buffer_usage,
37 parent);
38
39 free(usage->session_name);
40 free(usage->channel_name);
41 free(usage);
42}
43
44static
45bool lttng_condition_buffer_usage_validate(
46 const struct lttng_condition *condition)
47{
48 bool valid = false;
49 struct lttng_condition_buffer_usage *usage;
50
51 if (!condition) {
52 goto end;
53 }
54
55 usage = container_of(condition, struct lttng_condition_buffer_usage,
56 parent);
57 if (!usage->session_name) {
58 ERR("Invalid buffer condition: a target session name must be set.");
59 goto end;
60 }
61 if (!usage->channel_name) {
62 ERR("Invalid buffer condition: a target channel name must be set.");
63 goto end;
64 }
70ee6d20
JR
65 if (usage->threshold_ratio.set == usage->threshold_bytes.set) {
66 ERR("Invalid buffer condition: a threshold must be set or both type cannot be used simultaneously.");
a58c490f
JG
67 goto end;
68 }
821d5e92
JG
69 if (!usage->domain.set) {
70 ERR("Invalid buffer usage condition: a domain must be set.");
71 goto end;
72 }
a58c490f
JG
73
74 valid = true;
75end:
76 return valid;
77}
78
79static
3647288f
JG
80int lttng_condition_buffer_usage_serialize(
81 const struct lttng_condition *condition,
c0a66c84 82 struct lttng_payload *payload)
a58c490f 83{
3647288f 84 int ret;
a58c490f 85 struct lttng_condition_buffer_usage *usage;
a58c490f 86 size_t session_name_len, channel_name_len;
d33bfbbf 87 struct lttng_condition_buffer_usage_comm usage_comm = {};
a58c490f
JG
88
89 if (!condition || !IS_USAGE_CONDITION(condition)) {
90 ret = -1;
91 goto end;
92 }
93
94 DBG("Serializing buffer usage condition");
95 usage = container_of(condition, struct lttng_condition_buffer_usage,
96 parent);
3647288f 97
a58c490f
JG
98 session_name_len = strlen(usage->session_name) + 1;
99 channel_name_len = strlen(usage->channel_name) + 1;
100 if (session_name_len > LTTNG_NAME_MAX ||
101 channel_name_len > LTTNG_NAME_MAX) {
102 ret = -1;
103 goto end;
104 }
3647288f
JG
105
106 usage_comm.threshold_set_in_bytes = !!usage->threshold_bytes.set;
107 usage_comm.session_name_len = session_name_len;
108 usage_comm.channel_name_len = channel_name_len;
109 usage_comm.domain_type = (int8_t) usage->domain.type;
110
111 if (usage->threshold_bytes.set) {
f66473ac 112 usage_comm.threshold_bytes = usage->threshold_bytes.value;
3647288f 113 } else {
f66473ac 114 usage_comm.threshold_ratio = usage->threshold_ratio.value;
3647288f 115 }
a58c490f 116
c0a66c84 117 ret = lttng_dynamic_buffer_append(&payload->buffer, &usage_comm,
3647288f
JG
118 sizeof(usage_comm));
119 if (ret) {
120 goto end;
121 }
c0a66c84
JG
122
123 ret = lttng_dynamic_buffer_append(&payload->buffer, usage->session_name,
3647288f
JG
124 session_name_len);
125 if (ret) {
126 goto end;
127 }
c0a66c84
JG
128
129 ret = lttng_dynamic_buffer_append(&payload->buffer, usage->channel_name,
3647288f
JG
130 channel_name_len);
131 if (ret) {
132 goto end;
a58c490f 133 }
a58c490f
JG
134end:
135 return ret;
136}
137
138static
139bool lttng_condition_buffer_usage_is_equal(const struct lttng_condition *_a,
140 const struct lttng_condition *_b)
141{
142 bool is_equal = false;
143 struct lttng_condition_buffer_usage *a, *b;
144
145 a = container_of(_a, struct lttng_condition_buffer_usage, parent);
146 b = container_of(_b, struct lttng_condition_buffer_usage, parent);
147
148 if ((a->threshold_ratio.set && !b->threshold_ratio.set) ||
149 (a->threshold_bytes.set && !b->threshold_bytes.set)) {
150 goto end;
151 }
152
153 if (a->threshold_ratio.set && b->threshold_ratio.set) {
154 double a_value, b_value, diff;
155
156 a_value = a->threshold_ratio.value;
157 b_value = b->threshold_ratio.value;
158 diff = fabs(a_value - b_value);
159
160 if (diff > DBL_EPSILON) {
161 goto end;
162 }
163 } else if (a->threshold_bytes.set && b->threshold_bytes.set) {
164 uint64_t a_value, b_value;
165
166 a_value = a->threshold_bytes.value;
167 b_value = b->threshold_bytes.value;
168 if (a_value != b_value) {
169 goto end;
170 }
171 }
172
821d5e92 173 /* Condition is not valid if this is not true. */
a0377dfe
FD
174 LTTNG_ASSERT(a->session_name);
175 LTTNG_ASSERT(b->session_name);
821d5e92 176 if (strcmp(a->session_name, b->session_name)) {
a58c490f
JG
177 goto end;
178 }
179
a0377dfe
FD
180 LTTNG_ASSERT(a->channel_name);
181 LTTNG_ASSERT(b->channel_name);
821d5e92 182 if (strcmp(a->channel_name, b->channel_name)) {
a58c490f
JG
183 goto end;
184 }
185
a0377dfe
FD
186 LTTNG_ASSERT(a->domain.set);
187 LTTNG_ASSERT(b->domain.set);
821d5e92 188 if (a->domain.type != b->domain.type) {
a58c490f
JG
189 goto end;
190 }
a58c490f
JG
191 is_equal = true;
192end:
193 return is_equal;
194}
195
6a751b95
JR
196static enum lttng_error_code lttng_condition_buffer_usage_mi_serialize(
197 const struct lttng_condition *condition,
198 struct mi_writer *writer)
199{
200 int ret;
201 enum lttng_error_code ret_code;
202 enum lttng_condition_status status;
203 const char *session_name = NULL, *channel_name = NULL;
204 enum lttng_domain_type domain_type;
205 bool is_threshold_bytes = false;
206 double threshold_ratio;
207 uint64_t threshold_bytes;
208 const char *condition_type_str = NULL;
209
a0377dfe
FD
210 LTTNG_ASSERT(condition);
211 LTTNG_ASSERT(IS_USAGE_CONDITION(condition));
6a751b95
JR
212
213 status = lttng_condition_buffer_usage_get_session_name(
214 condition, &session_name);
a0377dfe
FD
215 LTTNG_ASSERT(status == LTTNG_CONDITION_STATUS_OK);
216 LTTNG_ASSERT(session_name);
6a751b95
JR
217
218 status = lttng_condition_buffer_usage_get_channel_name(
219 condition, &channel_name);
a0377dfe
FD
220 LTTNG_ASSERT(status == LTTNG_CONDITION_STATUS_OK);
221 LTTNG_ASSERT(session_name);
6a751b95
JR
222
223 status = lttng_condition_buffer_usage_get_domain_type(
224 condition, &domain_type);
a0377dfe 225 LTTNG_ASSERT(status == LTTNG_CONDITION_STATUS_OK);
6a751b95
JR
226
227 status = lttng_condition_buffer_usage_get_threshold(
228 condition, &threshold_bytes);
229 if (status == LTTNG_CONDITION_STATUS_OK) {
230 is_threshold_bytes = true;
231 } else if (status != LTTNG_CONDITION_STATUS_UNSET) {
232 /* Unexpected at this stage. */
233 ret_code = LTTNG_ERR_INVALID;
234 goto end;
235 }
236
237 if (!is_threshold_bytes) {
238 status = lttng_condition_buffer_usage_get_threshold_ratio(
239 condition, &threshold_ratio);
a0377dfe 240 LTTNG_ASSERT(status == LTTNG_CONDITION_STATUS_OK);
6a751b95
JR
241 }
242
243 switch (lttng_condition_get_type(condition)) {
244 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH:
245 condition_type_str =
246 mi_lttng_element_condition_buffer_usage_high;
247 break;
248 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW:
249 condition_type_str =
250 mi_lttng_element_condition_buffer_usage_low;
251 break;
252 default:
253 abort();
254 break;
255 }
256
257 /* Open the sub type condition element. */
258 ret = mi_lttng_writer_open_element(writer, condition_type_str);
259 if (ret) {
260 goto mi_error;
261 }
262
263 /* Session name. */
264 ret = mi_lttng_writer_write_element_string(
265 writer, mi_lttng_element_session_name, session_name);
266 if (ret) {
267 goto mi_error;
268 }
269
270 /* Channel name. */
271 ret = mi_lttng_writer_write_element_string(writer,
272 mi_lttng_element_condition_channel_name, channel_name);
273 if (ret) {
274 goto mi_error;
275 }
276
277 /* Domain. */
278 ret = mi_lttng_writer_write_element_string(writer,
279 config_element_domain,
280 mi_lttng_domaintype_string(domain_type));
281 if (ret) {
282 goto mi_error;
283 }
284
285 if (is_threshold_bytes) {
286 /* Usage in bytes. */
287 ret = mi_lttng_writer_write_element_unsigned_int(writer,
288 mi_lttng_element_condition_threshold_bytes,
289 threshold_bytes);
290 if (ret) {
291 goto mi_error;
292 }
293 } else {
294 /* Ratio. */
295 ret = mi_lttng_writer_write_element_double(writer,
296 mi_lttng_element_condition_threshold_ratio,
297 threshold_ratio);
298 if (ret) {
299 goto mi_error;
300 }
301 }
302
303 /* Closing sub type condition element. */
304 ret = mi_lttng_writer_close_element(writer);
305 if (ret) {
306 goto mi_error;
307 }
308
309 ret_code = LTTNG_OK;
310 goto end;
311
312mi_error:
313 ret_code = LTTNG_ERR_MI_IO_FAIL;
314end:
315 return ret_code;
316}
317
a58c490f
JG
318static
319struct lttng_condition *lttng_condition_buffer_usage_create(
320 enum lttng_condition_type type)
321{
322 struct lttng_condition_buffer_usage *condition;
323
324 condition = zmalloc(sizeof(struct lttng_condition_buffer_usage));
325 if (!condition) {
9a09eef5 326 return NULL;
a58c490f
JG
327 }
328
329 lttng_condition_init(&condition->parent, type);
330 condition->parent.validate = lttng_condition_buffer_usage_validate;
331 condition->parent.serialize = lttng_condition_buffer_usage_serialize;
332 condition->parent.equal = lttng_condition_buffer_usage_is_equal;
333 condition->parent.destroy = lttng_condition_buffer_usage_destroy;
6a751b95 334 condition->parent.mi_serialize = lttng_condition_buffer_usage_mi_serialize;
a58c490f
JG
335 return &condition->parent;
336}
337
338struct lttng_condition *lttng_condition_buffer_usage_low_create(void)
339{
340 return lttng_condition_buffer_usage_create(
341 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW);
342}
343
344struct lttng_condition *lttng_condition_buffer_usage_high_create(void)
345{
346 return lttng_condition_buffer_usage_create(
347 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH);
348}
349
350static
c0a66c84
JG
351ssize_t init_condition_from_payload(struct lttng_condition *condition,
352 struct lttng_payload_view *src_view)
a58c490f
JG
353{
354 ssize_t ret, condition_size;
355 enum lttng_condition_status status;
356 enum lttng_domain_type domain_type;
a58c490f
JG
357 const char *session_name, *channel_name;
358 struct lttng_buffer_view names_view;
3e6e0df2
JG
359 const struct lttng_condition_buffer_usage_comm *condition_comm;
360 const struct lttng_payload_view condition_comm_view =
361 lttng_payload_view_from_view(
362 src_view, 0, sizeof(*condition_comm));
a58c490f 363
3e6e0df2 364 if (!lttng_payload_view_is_valid(&condition_comm_view)) {
a58c490f
JG
365 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain header");
366 ret = -1;
367 goto end;
368 }
369
3e6e0df2 370 condition_comm = (typeof(condition_comm)) condition_comm_view.buffer.data;
c0a66c84 371 names_view = lttng_buffer_view_from_view(&src_view->buffer,
a58c490f
JG
372 sizeof(*condition_comm), -1);
373
374 if (condition_comm->session_name_len > LTTNG_NAME_MAX ||
375 condition_comm->channel_name_len > LTTNG_NAME_MAX) {
376 ERR("Failed to initialize from malformed condition buffer: name exceeds LTTNG_MAX_NAME");
377 ret = -1;
378 goto end;
379 }
380
381 if (names_view.size <
382 (condition_comm->session_name_len +
383 condition_comm->channel_name_len)) {
384 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain element names");
385 ret = -1;
386 goto end;
387 }
388
389 if (condition_comm->threshold_set_in_bytes) {
390 status = lttng_condition_buffer_usage_set_threshold(condition,
f66473ac 391 condition_comm->threshold_bytes);
a58c490f
JG
392 } else {
393 status = lttng_condition_buffer_usage_set_threshold_ratio(
f66473ac 394 condition, condition_comm->threshold_ratio);
a58c490f 395 }
c0a66c84 396
a58c490f
JG
397 if (status != LTTNG_CONDITION_STATUS_OK) {
398 ERR("Failed to initialize buffer usage condition threshold");
399 ret = -1;
400 goto end;
401 }
402
403 if (condition_comm->domain_type <= LTTNG_DOMAIN_NONE ||
404 condition_comm->domain_type > LTTNG_DOMAIN_PYTHON) {
405 /* Invalid domain value. */
406 ERR("Invalid domain type value (%i) found in condition buffer",
407 (int) condition_comm->domain_type);
408 ret = -1;
409 goto end;
410 }
411
412 domain_type = (enum lttng_domain_type) condition_comm->domain_type;
413 status = lttng_condition_buffer_usage_set_domain_type(condition,
414 domain_type);
415 if (status != LTTNG_CONDITION_STATUS_OK) {
416 ERR("Failed to set buffer usage condition domain");
417 ret = -1;
418 goto end;
419 }
420
421 session_name = names_view.data;
422 if (*(session_name + condition_comm->session_name_len - 1) != '\0') {
423 ERR("Malformed session name encountered in condition buffer");
424 ret = -1;
425 goto end;
426 }
427
428 channel_name = session_name + condition_comm->session_name_len;
429 if (*(channel_name + condition_comm->channel_name_len - 1) != '\0') {
430 ERR("Malformed channel name encountered in condition buffer");
431 ret = -1;
432 goto end;
433 }
434
435 status = lttng_condition_buffer_usage_set_session_name(condition,
436 session_name);
437 if (status != LTTNG_CONDITION_STATUS_OK) {
438 ERR("Failed to set buffer usage session name");
439 ret = -1;
440 goto end;
441 }
442
443 status = lttng_condition_buffer_usage_set_channel_name(condition,
444 channel_name);
445 if (status != LTTNG_CONDITION_STATUS_OK) {
446 ERR("Failed to set buffer usage channel name");
447 ret = -1;
448 goto end;
449 }
450
451 if (!lttng_condition_validate(condition)) {
452 ret = -1;
453 goto end;
454 }
455
456 condition_size = sizeof(*condition_comm) +
457 (ssize_t) condition_comm->session_name_len +
458 (ssize_t) condition_comm->channel_name_len;
459 ret = condition_size;
460end:
461 return ret;
462}
463
464LTTNG_HIDDEN
c0a66c84
JG
465ssize_t lttng_condition_buffer_usage_low_create_from_payload(
466 struct lttng_payload_view *view,
a58c490f
JG
467 struct lttng_condition **_condition)
468{
469 ssize_t ret;
470 struct lttng_condition *condition =
471 lttng_condition_buffer_usage_low_create();
472
473 if (!_condition || !condition) {
474 ret = -1;
475 goto error;
476 }
477
c0a66c84 478 ret = init_condition_from_payload(condition, view);
a58c490f
JG
479 if (ret < 0) {
480 goto error;
481 }
482
483 *_condition = condition;
484 return ret;
485error:
486 lttng_condition_destroy(condition);
487 return ret;
488}
489
490LTTNG_HIDDEN
c0a66c84
JG
491ssize_t lttng_condition_buffer_usage_high_create_from_payload(
492 struct lttng_payload_view *view,
a58c490f
JG
493 struct lttng_condition **_condition)
494{
495 ssize_t ret;
496 struct lttng_condition *condition =
497 lttng_condition_buffer_usage_high_create();
498
499 if (!_condition || !condition) {
500 ret = -1;
501 goto error;
502 }
503
c0a66c84 504 ret = init_condition_from_payload(condition, view);
a58c490f
JG
505 if (ret < 0) {
506 goto error;
507 }
508
509 *_condition = condition;
510 return ret;
511error:
512 lttng_condition_destroy(condition);
513 return ret;
514}
515
516static
c0a66c84 517struct lttng_evaluation *create_evaluation_from_payload(
a58c490f 518 enum lttng_condition_type type,
c0a66c84 519 struct lttng_payload_view *view)
a58c490f
JG
520{
521 const struct lttng_evaluation_buffer_usage_comm *comm =
c0a66c84 522 (typeof(comm)) view->buffer.data;
a58c490f
JG
523 struct lttng_evaluation *evaluation = NULL;
524
c0a66c84 525 if (view->buffer.size < sizeof(*comm)) {
a58c490f
JG
526 goto end;
527 }
528
529 evaluation = lttng_evaluation_buffer_usage_create(type,
530 comm->buffer_use, comm->buffer_capacity);
531end:
532 return evaluation;
533}
534
535LTTNG_HIDDEN
c0a66c84
JG
536ssize_t lttng_evaluation_buffer_usage_low_create_from_payload(
537 struct lttng_payload_view *view,
a58c490f
JG
538 struct lttng_evaluation **_evaluation)
539{
540 ssize_t ret;
541 struct lttng_evaluation *evaluation = NULL;
542
543 if (!_evaluation) {
544 ret = -1;
545 goto error;
546 }
547
c0a66c84 548 evaluation = create_evaluation_from_payload(
a58c490f
JG
549 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW, view);
550 if (!evaluation) {
551 ret = -1;
552 goto error;
553 }
554
555 *_evaluation = evaluation;
556 ret = sizeof(struct lttng_evaluation_buffer_usage_comm);
557 return ret;
558error:
559 lttng_evaluation_destroy(evaluation);
560 return ret;
561}
562
563LTTNG_HIDDEN
c0a66c84
JG
564ssize_t lttng_evaluation_buffer_usage_high_create_from_payload(
565 struct lttng_payload_view *view,
a58c490f
JG
566 struct lttng_evaluation **_evaluation)
567{
568 ssize_t ret;
569 struct lttng_evaluation *evaluation = NULL;
570
571 if (!_evaluation) {
572 ret = -1;
573 goto error;
574 }
575
c0a66c84 576 evaluation = create_evaluation_from_payload(
a58c490f
JG
577 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH, view);
578 if (!evaluation) {
579 ret = -1;
580 goto error;
581 }
582
583 *_evaluation = evaluation;
584 ret = sizeof(struct lttng_evaluation_buffer_usage_comm);
585 return ret;
586error:
587 lttng_evaluation_destroy(evaluation);
588 return ret;
589}
590
591enum lttng_condition_status
592lttng_condition_buffer_usage_get_threshold_ratio(
593 const struct lttng_condition *condition,
594 double *threshold_ratio)
595{
596 struct lttng_condition_buffer_usage *usage;
597 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
598
599 if (!condition || !IS_USAGE_CONDITION(condition) ||
600 !threshold_ratio) {
601 status = LTTNG_CONDITION_STATUS_INVALID;
602 goto end;
603 }
604
605 usage = container_of(condition, struct lttng_condition_buffer_usage,
606 parent);
607 if (!usage->threshold_ratio.set) {
608 status = LTTNG_CONDITION_STATUS_UNSET;
609 goto end;
610 }
611 *threshold_ratio = usage->threshold_ratio.value;
612end:
613 return status;
614}
615
616/* threshold_ratio expressed as [0.0, 1.0]. */
617enum lttng_condition_status
618lttng_condition_buffer_usage_set_threshold_ratio(
619 struct lttng_condition *condition, double threshold_ratio)
620{
621 struct lttng_condition_buffer_usage *usage;
622 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
623
624 if (!condition || !IS_USAGE_CONDITION(condition) ||
625 threshold_ratio < 0.0 ||
626 threshold_ratio > 1.0) {
627 status = LTTNG_CONDITION_STATUS_INVALID;
628 goto end;
629 }
630
631 usage = container_of(condition, struct lttng_condition_buffer_usage,
632 parent);
633 usage->threshold_ratio.set = true;
634 usage->threshold_bytes.set = false;
635 usage->threshold_ratio.value = threshold_ratio;
636end:
637 return status;
638}
639
640enum lttng_condition_status
641lttng_condition_buffer_usage_get_threshold(
642 const struct lttng_condition *condition,
643 uint64_t *threshold_bytes)
644{
645 struct lttng_condition_buffer_usage *usage;
646 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
647
648 if (!condition || !IS_USAGE_CONDITION(condition) || !threshold_bytes) {
649 status = LTTNG_CONDITION_STATUS_INVALID;
650 goto end;
651 }
652
653 usage = container_of(condition, struct lttng_condition_buffer_usage,
654 parent);
655 if (!usage->threshold_bytes.set) {
656 status = LTTNG_CONDITION_STATUS_UNSET;
657 goto end;
658 }
659 *threshold_bytes = usage->threshold_bytes.value;
660end:
661 return status;
662}
663
664enum lttng_condition_status
665lttng_condition_buffer_usage_set_threshold(
666 struct lttng_condition *condition, uint64_t threshold_bytes)
667{
668 struct lttng_condition_buffer_usage *usage;
669 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
670
671 if (!condition || !IS_USAGE_CONDITION(condition)) {
672 status = LTTNG_CONDITION_STATUS_INVALID;
673 goto end;
674 }
675
676 usage = container_of(condition, struct lttng_condition_buffer_usage,
677 parent);
678 usage->threshold_ratio.set = false;
679 usage->threshold_bytes.set = true;
680 usage->threshold_bytes.value = threshold_bytes;
681end:
682 return status;
683}
684
685enum lttng_condition_status
686lttng_condition_buffer_usage_get_session_name(
687 const struct lttng_condition *condition,
688 const char **session_name)
689{
690 struct lttng_condition_buffer_usage *usage;
691 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
692
693 if (!condition || !IS_USAGE_CONDITION(condition) || !session_name) {
694 status = LTTNG_CONDITION_STATUS_INVALID;
695 goto end;
696 }
697
698 usage = container_of(condition, struct lttng_condition_buffer_usage,
699 parent);
700 if (!usage->session_name) {
701 status = LTTNG_CONDITION_STATUS_UNSET;
702 goto end;
703 }
704 *session_name = usage->session_name;
705end:
706 return status;
707}
708
709enum lttng_condition_status
710lttng_condition_buffer_usage_set_session_name(
711 struct lttng_condition *condition, const char *session_name)
712{
713 char *session_name_copy;
714 struct lttng_condition_buffer_usage *usage;
715 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
716
717 if (!condition || !IS_USAGE_CONDITION(condition) || !session_name ||
718 strlen(session_name) == 0) {
719 status = LTTNG_CONDITION_STATUS_INVALID;
720 goto end;
721 }
722
723 usage = container_of(condition, struct lttng_condition_buffer_usage,
724 parent);
725 session_name_copy = strdup(session_name);
726 if (!session_name_copy) {
727 status = LTTNG_CONDITION_STATUS_ERROR;
728 goto end;
729 }
730
731 if (usage->session_name) {
732 free(usage->session_name);
733 }
734 usage->session_name = session_name_copy;
735end:
736 return status;
737}
738
739enum lttng_condition_status
740lttng_condition_buffer_usage_get_channel_name(
741 const struct lttng_condition *condition,
742 const char **channel_name)
743{
744 struct lttng_condition_buffer_usage *usage;
745 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
746
747 if (!condition || !IS_USAGE_CONDITION(condition) || !channel_name) {
748 status = LTTNG_CONDITION_STATUS_INVALID;
749 goto end;
750 }
751
752 usage = container_of(condition, struct lttng_condition_buffer_usage,
753 parent);
754 if (!usage->channel_name) {
755 status = LTTNG_CONDITION_STATUS_UNSET;
756 goto end;
757 }
758 *channel_name = usage->channel_name;
759end:
760 return status;
761}
762
763enum lttng_condition_status
764lttng_condition_buffer_usage_set_channel_name(
765 struct lttng_condition *condition, const char *channel_name)
766{
767 char *channel_name_copy;
768 struct lttng_condition_buffer_usage *usage;
769 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
770
771 if (!condition || !IS_USAGE_CONDITION(condition) || !channel_name ||
772 strlen(channel_name) == 0) {
773 status = LTTNG_CONDITION_STATUS_INVALID;
774 goto end;
775 }
776
777 usage = container_of(condition, struct lttng_condition_buffer_usage,
778 parent);
779 channel_name_copy = strdup(channel_name);
780 if (!channel_name_copy) {
781 status = LTTNG_CONDITION_STATUS_ERROR;
782 goto end;
783 }
784
785 if (usage->channel_name) {
786 free(usage->channel_name);
787 }
788 usage->channel_name = channel_name_copy;
789end:
790 return status;
791}
792
793enum lttng_condition_status
794lttng_condition_buffer_usage_get_domain_type(
795 const struct lttng_condition *condition,
796 enum lttng_domain_type *type)
797{
798 struct lttng_condition_buffer_usage *usage;
799 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
800
801 if (!condition || !IS_USAGE_CONDITION(condition) || !type) {
802 status = LTTNG_CONDITION_STATUS_INVALID;
803 goto end;
804 }
805
806 usage = container_of(condition, struct lttng_condition_buffer_usage,
807 parent);
808 if (!usage->domain.set) {
809 status = LTTNG_CONDITION_STATUS_UNSET;
810 goto end;
811 }
812 *type = usage->domain.type;
813end:
814 return status;
815}
816
817enum lttng_condition_status
818lttng_condition_buffer_usage_set_domain_type(
819 struct lttng_condition *condition, enum lttng_domain_type type)
820{
821 struct lttng_condition_buffer_usage *usage;
822 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
823
824 if (!condition || !IS_USAGE_CONDITION(condition) ||
825 type == LTTNG_DOMAIN_NONE) {
826 status = LTTNG_CONDITION_STATUS_INVALID;
827 goto end;
828 }
829
830 usage = container_of(condition, struct lttng_condition_buffer_usage,
831 parent);
832 usage->domain.set = true;
833 usage->domain.type = type;
834end:
835 return status;
836}
837
838static
3647288f 839int lttng_evaluation_buffer_usage_serialize(
9b63a4aa 840 const struct lttng_evaluation *evaluation,
c0a66c84 841 struct lttng_payload *payload)
a58c490f 842{
a58c490f 843 struct lttng_evaluation_buffer_usage *usage;
3647288f 844 struct lttng_evaluation_buffer_usage_comm comm;
a58c490f
JG
845
846 usage = container_of(evaluation, struct lttng_evaluation_buffer_usage,
847 parent);
3647288f
JG
848 comm.buffer_use = usage->buffer_use;
849 comm.buffer_capacity = usage->buffer_capacity;
a58c490f 850
c0a66c84
JG
851 return lttng_dynamic_buffer_append(
852 &payload->buffer, &comm, sizeof(comm));
a58c490f
JG
853}
854
855static
856void lttng_evaluation_buffer_usage_destroy(
857 struct lttng_evaluation *evaluation)
858{
859 struct lttng_evaluation_buffer_usage *usage;
860
861 usage = container_of(evaluation, struct lttng_evaluation_buffer_usage,
862 parent);
863 free(usage);
864}
865
866LTTNG_HIDDEN
867struct lttng_evaluation *lttng_evaluation_buffer_usage_create(
868 enum lttng_condition_type type, uint64_t use, uint64_t capacity)
869{
870 struct lttng_evaluation_buffer_usage *usage;
871
872 usage = zmalloc(sizeof(struct lttng_evaluation_buffer_usage));
873 if (!usage) {
874 goto end;
875 }
876
877 usage->parent.type = type;
878 usage->buffer_use = use;
879 usage->buffer_capacity = capacity;
880 usage->parent.serialize = lttng_evaluation_buffer_usage_serialize;
881 usage->parent.destroy = lttng_evaluation_buffer_usage_destroy;
882end:
883 return &usage->parent;
884}
885
886/*
887 * Get the sampled buffer usage which caused the associated condition to
888 * evaluate to "true".
889 */
890enum lttng_evaluation_status
891lttng_evaluation_buffer_usage_get_usage_ratio(
892 const struct lttng_evaluation *evaluation, double *usage_ratio)
893{
894 struct lttng_evaluation_buffer_usage *usage;
895 enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
896
897 if (!evaluation || !is_usage_evaluation(evaluation) || !usage_ratio) {
898 status = LTTNG_EVALUATION_STATUS_INVALID;
899 goto end;
900 }
901
902 usage = container_of(evaluation, struct lttng_evaluation_buffer_usage,
903 parent);
904 *usage_ratio = (double) usage->buffer_use /
905 (double) usage->buffer_capacity;
906end:
907 return status;
908}
909
910enum lttng_evaluation_status
911lttng_evaluation_buffer_usage_get_usage(
912 const struct lttng_evaluation *evaluation,
913 uint64_t *usage_bytes)
914{
915 struct lttng_evaluation_buffer_usage *usage;
916 enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
917
918 if (!evaluation || !is_usage_evaluation(evaluation) || !usage_bytes) {
919 status = LTTNG_EVALUATION_STATUS_INVALID;
920 goto end;
921 }
922
923 usage = container_of(evaluation, struct lttng_evaluation_buffer_usage,
924 parent);
925 *usage_bytes = usage->buffer_use;
926end:
927 return status;
928}
This page took 0.071782 seconds and 4 git commands to generate.