2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #include <common/error.hpp>
9 #include <common/macros.hpp>
10 #include <common/mi-lttng.hpp>
12 #include <lttng/condition/buffer-usage-internal.hpp>
13 #include <lttng/condition/condition-internal.hpp>
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 \
23 bool is_usage_evaluation(const struct lttng_evaluation
*evaluation
)
25 enum lttng_condition_type type
= lttng_evaluation_get_type(evaluation
);
27 return type
== LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
||
28 type
== LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
;
32 void lttng_condition_buffer_usage_destroy(struct lttng_condition
*condition
)
34 struct lttng_condition_buffer_usage
*usage
;
36 usage
= lttng::utils::container_of(condition
,
37 <tng_condition_buffer_usage::parent
);
39 free(usage
->session_name
);
40 free(usage
->channel_name
);
45 bool lttng_condition_buffer_usage_validate(
46 const struct lttng_condition
*condition
)
49 struct lttng_condition_buffer_usage
*usage
;
55 usage
= lttng::utils::container_of(condition
,
56 <tng_condition_buffer_usage::parent
);
57 if (!usage
->session_name
) {
58 ERR("Invalid buffer condition: a target session name must be set.");
61 if (!usage
->channel_name
) {
62 ERR("Invalid buffer condition: a target channel name must be set.");
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.");
69 if (!usage
->domain
.set
) {
70 ERR("Invalid buffer usage condition: a domain must be set.");
80 int lttng_condition_buffer_usage_serialize(
81 const struct lttng_condition
*condition
,
82 struct lttng_payload
*payload
)
85 struct lttng_condition_buffer_usage
*usage
;
86 size_t session_name_len
, channel_name_len
;
87 struct lttng_condition_buffer_usage_comm usage_comm
= {};
89 if (!condition
|| !IS_USAGE_CONDITION(condition
)) {
94 DBG("Serializing buffer usage condition");
95 usage
= lttng::utils::container_of(condition
,
96 <tng_condition_buffer_usage::parent
);
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
) {
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
;
111 if (usage
->threshold_bytes
.set
) {
112 usage_comm
.threshold_bytes
= usage
->threshold_bytes
.value
;
114 usage_comm
.threshold_ratio
= usage
->threshold_ratio
.value
;
117 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &usage_comm
,
123 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, usage
->session_name
,
129 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, usage
->channel_name
,
139 bool lttng_condition_buffer_usage_is_equal(const struct lttng_condition
*_a
,
140 const struct lttng_condition
*_b
)
142 bool is_equal
= false;
143 struct lttng_condition_buffer_usage
*a
, *b
;
145 a
= lttng::utils::container_of(_a
, <tng_condition_buffer_usage::parent
);
146 b
= lttng::utils::container_of(_b
, <tng_condition_buffer_usage::parent
);
148 if ((a
->threshold_ratio
.set
&& !b
->threshold_ratio
.set
) ||
149 (a
->threshold_bytes
.set
&& !b
->threshold_bytes
.set
)) {
153 if (a
->threshold_ratio
.set
&& b
->threshold_ratio
.set
) {
154 double a_value
, b_value
, diff
;
156 a_value
= a
->threshold_ratio
.value
;
157 b_value
= b
->threshold_ratio
.value
;
158 diff
= fabs(a_value
- b_value
);
160 if (diff
> DBL_EPSILON
) {
163 } else if (a
->threshold_bytes
.set
&& b
->threshold_bytes
.set
) {
164 uint64_t a_value
, b_value
;
166 a_value
= a
->threshold_bytes
.value
;
167 b_value
= b
->threshold_bytes
.value
;
168 if (a_value
!= b_value
) {
173 /* Condition is not valid if this is not true. */
174 LTTNG_ASSERT(a
->session_name
);
175 LTTNG_ASSERT(b
->session_name
);
176 if (strcmp(a
->session_name
, b
->session_name
)) {
180 LTTNG_ASSERT(a
->channel_name
);
181 LTTNG_ASSERT(b
->channel_name
);
182 if (strcmp(a
->channel_name
, b
->channel_name
)) {
186 LTTNG_ASSERT(a
->domain
.set
);
187 LTTNG_ASSERT(b
->domain
.set
);
188 if (a
->domain
.type
!= b
->domain
.type
) {
196 static enum lttng_error_code
lttng_condition_buffer_usage_mi_serialize(
197 const struct lttng_condition
*condition
,
198 struct mi_writer
*writer
)
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
;
210 LTTNG_ASSERT(condition
);
211 LTTNG_ASSERT(IS_USAGE_CONDITION(condition
));
213 status
= lttng_condition_buffer_usage_get_session_name(
214 condition
, &session_name
);
215 LTTNG_ASSERT(status
== LTTNG_CONDITION_STATUS_OK
);
216 LTTNG_ASSERT(session_name
);
218 status
= lttng_condition_buffer_usage_get_channel_name(
219 condition
, &channel_name
);
220 LTTNG_ASSERT(status
== LTTNG_CONDITION_STATUS_OK
);
221 LTTNG_ASSERT(session_name
);
223 status
= lttng_condition_buffer_usage_get_domain_type(
224 condition
, &domain_type
);
225 LTTNG_ASSERT(status
== LTTNG_CONDITION_STATUS_OK
);
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
;
237 if (!is_threshold_bytes
) {
238 status
= lttng_condition_buffer_usage_get_threshold_ratio(
239 condition
, &threshold_ratio
);
240 LTTNG_ASSERT(status
== LTTNG_CONDITION_STATUS_OK
);
243 switch (lttng_condition_get_type(condition
)) {
244 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
:
246 mi_lttng_element_condition_buffer_usage_high
;
248 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
:
250 mi_lttng_element_condition_buffer_usage_low
;
257 /* Open the sub type condition element. */
258 ret
= mi_lttng_writer_open_element(writer
, condition_type_str
);
264 ret
= mi_lttng_writer_write_element_string(
265 writer
, mi_lttng_element_session_name
, session_name
);
271 ret
= mi_lttng_writer_write_element_string(writer
,
272 mi_lttng_element_condition_channel_name
, channel_name
);
278 ret
= mi_lttng_writer_write_element_string(writer
,
279 config_element_domain
,
280 mi_lttng_domaintype_string(domain_type
));
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
,
295 ret
= mi_lttng_writer_write_element_double(writer
,
296 mi_lttng_element_condition_threshold_ratio
,
303 /* Closing sub type condition element. */
304 ret
= mi_lttng_writer_close_element(writer
);
313 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
319 struct lttng_condition
*lttng_condition_buffer_usage_create(
320 enum lttng_condition_type type
)
322 struct lttng_condition_buffer_usage
*condition
;
324 condition
= zmalloc
<lttng_condition_buffer_usage
>();
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
;
334 condition
->parent
.mi_serialize
= lttng_condition_buffer_usage_mi_serialize
;
335 return &condition
->parent
;
338 struct lttng_condition
*lttng_condition_buffer_usage_low_create(void)
340 return lttng_condition_buffer_usage_create(
341 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
);
344 struct lttng_condition
*lttng_condition_buffer_usage_high_create(void)
346 return lttng_condition_buffer_usage_create(
347 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
);
351 ssize_t
init_condition_from_payload(struct lttng_condition
*condition
,
352 struct lttng_payload_view
*src_view
)
354 ssize_t ret
, condition_size
;
355 enum lttng_condition_status status
;
356 enum lttng_domain_type domain_type
;
357 const char *session_name
, *channel_name
;
358 struct lttng_buffer_view names_view
;
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
));
364 if (!lttng_payload_view_is_valid(&condition_comm_view
)) {
365 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain header");
370 condition_comm
= (typeof(condition_comm
)) condition_comm_view
.buffer
.data
;
371 names_view
= lttng_buffer_view_from_view(&src_view
->buffer
,
372 sizeof(*condition_comm
), -1);
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");
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");
389 if (condition_comm
->threshold_set_in_bytes
) {
390 status
= lttng_condition_buffer_usage_set_threshold(condition
,
391 condition_comm
->threshold_bytes
);
393 status
= lttng_condition_buffer_usage_set_threshold_ratio(
394 condition
, condition_comm
->threshold_ratio
);
397 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
398 ERR("Failed to initialize buffer usage condition threshold");
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
);
412 domain_type
= (enum lttng_domain_type
) condition_comm
->domain_type
;
413 status
= lttng_condition_buffer_usage_set_domain_type(condition
,
415 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
416 ERR("Failed to set buffer usage condition domain");
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");
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");
435 status
= lttng_condition_buffer_usage_set_session_name(condition
,
437 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
438 ERR("Failed to set buffer usage session name");
443 status
= lttng_condition_buffer_usage_set_channel_name(condition
,
445 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
446 ERR("Failed to set buffer usage channel name");
451 if (!lttng_condition_validate(condition
)) {
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
;
464 ssize_t
lttng_condition_buffer_usage_low_create_from_payload(
465 struct lttng_payload_view
*view
,
466 struct lttng_condition
**_condition
)
469 struct lttng_condition
*condition
=
470 lttng_condition_buffer_usage_low_create();
472 if (!_condition
|| !condition
) {
477 ret
= init_condition_from_payload(condition
, view
);
482 *_condition
= condition
;
485 lttng_condition_destroy(condition
);
489 ssize_t
lttng_condition_buffer_usage_high_create_from_payload(
490 struct lttng_payload_view
*view
,
491 struct lttng_condition
**_condition
)
494 struct lttng_condition
*condition
=
495 lttng_condition_buffer_usage_high_create();
497 if (!_condition
|| !condition
) {
502 ret
= init_condition_from_payload(condition
, view
);
507 *_condition
= condition
;
510 lttng_condition_destroy(condition
);
515 struct lttng_evaluation
*create_evaluation_from_payload(
516 enum lttng_condition_type type
,
517 struct lttng_payload_view
*view
)
519 const struct lttng_evaluation_buffer_usage_comm
*comm
=
520 (typeof(comm
)) view
->buffer
.data
;
521 struct lttng_evaluation
*evaluation
= NULL
;
523 if (view
->buffer
.size
< sizeof(*comm
)) {
527 evaluation
= lttng_evaluation_buffer_usage_create(type
,
528 comm
->buffer_use
, comm
->buffer_capacity
);
533 ssize_t
lttng_evaluation_buffer_usage_low_create_from_payload(
534 struct lttng_payload_view
*view
,
535 struct lttng_evaluation
**_evaluation
)
538 struct lttng_evaluation
*evaluation
= NULL
;
545 evaluation
= create_evaluation_from_payload(
546 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
, view
);
552 *_evaluation
= evaluation
;
553 ret
= sizeof(struct lttng_evaluation_buffer_usage_comm
);
556 lttng_evaluation_destroy(evaluation
);
560 ssize_t
lttng_evaluation_buffer_usage_high_create_from_payload(
561 struct lttng_payload_view
*view
,
562 struct lttng_evaluation
**_evaluation
)
565 struct lttng_evaluation
*evaluation
= NULL
;
572 evaluation
= create_evaluation_from_payload(
573 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
, view
);
579 *_evaluation
= evaluation
;
580 ret
= sizeof(struct lttng_evaluation_buffer_usage_comm
);
583 lttng_evaluation_destroy(evaluation
);
587 enum lttng_condition_status
588 lttng_condition_buffer_usage_get_threshold_ratio(
589 const struct lttng_condition
*condition
,
590 double *threshold_ratio
)
592 struct lttng_condition_buffer_usage
*usage
;
593 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
595 if (!condition
|| !IS_USAGE_CONDITION(condition
) ||
597 status
= LTTNG_CONDITION_STATUS_INVALID
;
601 usage
= lttng::utils::container_of(condition
,
602 <tng_condition_buffer_usage::parent
);
603 if (!usage
->threshold_ratio
.set
) {
604 status
= LTTNG_CONDITION_STATUS_UNSET
;
607 *threshold_ratio
= usage
->threshold_ratio
.value
;
612 /* threshold_ratio expressed as [0.0, 1.0]. */
613 enum lttng_condition_status
614 lttng_condition_buffer_usage_set_threshold_ratio(
615 struct lttng_condition
*condition
, double threshold_ratio
)
617 struct lttng_condition_buffer_usage
*usage
;
618 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
620 if (!condition
|| !IS_USAGE_CONDITION(condition
) ||
621 threshold_ratio
< 0.0 ||
622 threshold_ratio
> 1.0) {
623 status
= LTTNG_CONDITION_STATUS_INVALID
;
627 usage
= lttng::utils::container_of(condition
,
628 <tng_condition_buffer_usage::parent
);
629 usage
->threshold_ratio
.set
= true;
630 usage
->threshold_bytes
.set
= false;
631 usage
->threshold_ratio
.value
= threshold_ratio
;
636 enum lttng_condition_status
637 lttng_condition_buffer_usage_get_threshold(
638 const struct lttng_condition
*condition
,
639 uint64_t *threshold_bytes
)
641 struct lttng_condition_buffer_usage
*usage
;
642 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
644 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !threshold_bytes
) {
645 status
= LTTNG_CONDITION_STATUS_INVALID
;
649 usage
= lttng::utils::container_of(condition
,
650 <tng_condition_buffer_usage::parent
);
651 if (!usage
->threshold_bytes
.set
) {
652 status
= LTTNG_CONDITION_STATUS_UNSET
;
655 *threshold_bytes
= usage
->threshold_bytes
.value
;
660 enum lttng_condition_status
661 lttng_condition_buffer_usage_set_threshold(
662 struct lttng_condition
*condition
, uint64_t threshold_bytes
)
664 struct lttng_condition_buffer_usage
*usage
;
665 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
667 if (!condition
|| !IS_USAGE_CONDITION(condition
)) {
668 status
= LTTNG_CONDITION_STATUS_INVALID
;
672 usage
= lttng::utils::container_of(condition
,
673 <tng_condition_buffer_usage::parent
);
674 usage
->threshold_ratio
.set
= false;
675 usage
->threshold_bytes
.set
= true;
676 usage
->threshold_bytes
.value
= threshold_bytes
;
681 enum lttng_condition_status
682 lttng_condition_buffer_usage_get_session_name(
683 const struct lttng_condition
*condition
,
684 const char **session_name
)
686 struct lttng_condition_buffer_usage
*usage
;
687 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
689 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !session_name
) {
690 status
= LTTNG_CONDITION_STATUS_INVALID
;
694 usage
= lttng::utils::container_of(condition
,
695 <tng_condition_buffer_usage::parent
);
696 if (!usage
->session_name
) {
697 status
= LTTNG_CONDITION_STATUS_UNSET
;
700 *session_name
= usage
->session_name
;
705 enum lttng_condition_status
706 lttng_condition_buffer_usage_set_session_name(
707 struct lttng_condition
*condition
, const char *session_name
)
709 char *session_name_copy
;
710 struct lttng_condition_buffer_usage
*usage
;
711 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
713 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !session_name
||
714 strlen(session_name
) == 0) {
715 status
= LTTNG_CONDITION_STATUS_INVALID
;
719 usage
= lttng::utils::container_of(condition
,
720 <tng_condition_buffer_usage::parent
);
721 session_name_copy
= strdup(session_name
);
722 if (!session_name_copy
) {
723 status
= LTTNG_CONDITION_STATUS_ERROR
;
727 if (usage
->session_name
) {
728 free(usage
->session_name
);
730 usage
->session_name
= session_name_copy
;
735 enum lttng_condition_status
736 lttng_condition_buffer_usage_get_channel_name(
737 const struct lttng_condition
*condition
,
738 const char **channel_name
)
740 struct lttng_condition_buffer_usage
*usage
;
741 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
743 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !channel_name
) {
744 status
= LTTNG_CONDITION_STATUS_INVALID
;
748 usage
= lttng::utils::container_of(condition
,
749 <tng_condition_buffer_usage::parent
);
750 if (!usage
->channel_name
) {
751 status
= LTTNG_CONDITION_STATUS_UNSET
;
754 *channel_name
= usage
->channel_name
;
759 enum lttng_condition_status
760 lttng_condition_buffer_usage_set_channel_name(
761 struct lttng_condition
*condition
, const char *channel_name
)
763 char *channel_name_copy
;
764 struct lttng_condition_buffer_usage
*usage
;
765 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
767 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !channel_name
||
768 strlen(channel_name
) == 0) {
769 status
= LTTNG_CONDITION_STATUS_INVALID
;
773 usage
= lttng::utils::container_of(condition
,
774 <tng_condition_buffer_usage::parent
);
775 channel_name_copy
= strdup(channel_name
);
776 if (!channel_name_copy
) {
777 status
= LTTNG_CONDITION_STATUS_ERROR
;
781 if (usage
->channel_name
) {
782 free(usage
->channel_name
);
784 usage
->channel_name
= channel_name_copy
;
789 enum lttng_condition_status
790 lttng_condition_buffer_usage_get_domain_type(
791 const struct lttng_condition
*condition
,
792 enum lttng_domain_type
*type
)
794 struct lttng_condition_buffer_usage
*usage
;
795 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
797 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !type
) {
798 status
= LTTNG_CONDITION_STATUS_INVALID
;
802 usage
= lttng::utils::container_of(condition
,
803 <tng_condition_buffer_usage::parent
);
804 if (!usage
->domain
.set
) {
805 status
= LTTNG_CONDITION_STATUS_UNSET
;
808 *type
= usage
->domain
.type
;
813 enum lttng_condition_status
814 lttng_condition_buffer_usage_set_domain_type(
815 struct lttng_condition
*condition
, enum lttng_domain_type type
)
817 struct lttng_condition_buffer_usage
*usage
;
818 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
820 if (!condition
|| !IS_USAGE_CONDITION(condition
) ||
821 type
== LTTNG_DOMAIN_NONE
) {
822 status
= LTTNG_CONDITION_STATUS_INVALID
;
826 usage
= lttng::utils::container_of(condition
,
827 <tng_condition_buffer_usage::parent
);
828 usage
->domain
.set
= true;
829 usage
->domain
.type
= type
;
835 int lttng_evaluation_buffer_usage_serialize(
836 const struct lttng_evaluation
*evaluation
,
837 struct lttng_payload
*payload
)
839 struct lttng_evaluation_buffer_usage
*usage
;
840 struct lttng_evaluation_buffer_usage_comm comm
;
842 usage
= lttng::utils::container_of(evaluation
,
843 <tng_evaluation_buffer_usage::parent
);
844 comm
.buffer_use
= usage
->buffer_use
;
845 comm
.buffer_capacity
= usage
->buffer_capacity
;
847 return lttng_dynamic_buffer_append(
848 &payload
->buffer
, &comm
, sizeof(comm
));
852 void lttng_evaluation_buffer_usage_destroy(
853 struct lttng_evaluation
*evaluation
)
855 struct lttng_evaluation_buffer_usage
*usage
;
857 usage
= lttng::utils::container_of(evaluation
,
858 <tng_evaluation_buffer_usage::parent
);
862 struct lttng_evaluation
*lttng_evaluation_buffer_usage_create(
863 enum lttng_condition_type type
, uint64_t use
, uint64_t capacity
)
865 struct lttng_evaluation_buffer_usage
*usage
;
867 usage
= zmalloc
<lttng_evaluation_buffer_usage
>();
872 usage
->parent
.type
= type
;
873 usage
->buffer_use
= use
;
874 usage
->buffer_capacity
= capacity
;
875 usage
->parent
.serialize
= lttng_evaluation_buffer_usage_serialize
;
876 usage
->parent
.destroy
= lttng_evaluation_buffer_usage_destroy
;
878 return &usage
->parent
;
882 * Get the sampled buffer usage which caused the associated condition to
883 * evaluate to "true".
885 enum lttng_evaluation_status
886 lttng_evaluation_buffer_usage_get_usage_ratio(
887 const struct lttng_evaluation
*evaluation
, double *usage_ratio
)
889 struct lttng_evaluation_buffer_usage
*usage
;
890 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
892 if (!evaluation
|| !is_usage_evaluation(evaluation
) || !usage_ratio
) {
893 status
= LTTNG_EVALUATION_STATUS_INVALID
;
897 usage
= lttng::utils::container_of(evaluation
,
898 <tng_evaluation_buffer_usage::parent
);
899 *usage_ratio
= (double) usage
->buffer_use
/
900 (double) usage
->buffer_capacity
;
905 enum lttng_evaluation_status
906 lttng_evaluation_buffer_usage_get_usage(
907 const struct lttng_evaluation
*evaluation
,
908 uint64_t *usage_bytes
)
910 struct lttng_evaluation_buffer_usage
*usage
;
911 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
913 if (!evaluation
|| !is_usage_evaluation(evaluation
) || !usage_bytes
) {
914 status
= LTTNG_EVALUATION_STATUS_INVALID
;
918 usage
= lttng::utils::container_of(evaluation
,
919 <tng_evaluation_buffer_usage::parent
);
920 *usage_bytes
= usage
->buffer_use
;