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>
19 #define IS_USAGE_CONDITION(condition) \
20 (lttng_condition_get_type(condition) == LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW || \
21 lttng_condition_get_type(condition) == LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH)
23 static 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
;
31 static void lttng_condition_buffer_usage_destroy(struct lttng_condition
*condition
)
33 struct lttng_condition_buffer_usage
*usage
;
35 usage
= lttng::utils::container_of(condition
, <tng_condition_buffer_usage::parent
);
37 free(usage
->session_name
);
38 free(usage
->channel_name
);
42 static bool lttng_condition_buffer_usage_validate(const struct lttng_condition
*condition
)
45 struct lttng_condition_buffer_usage
*usage
;
51 usage
= lttng::utils::container_of(condition
, <tng_condition_buffer_usage::parent
);
52 if (!usage
->session_name
) {
53 ERR("Invalid buffer condition: a target session name must be set.");
56 if (!usage
->channel_name
) {
57 ERR("Invalid buffer condition: a target channel name must be set.");
60 if (usage
->threshold_ratio
.set
== usage
->threshold_bytes
.set
) {
61 ERR("Invalid buffer condition: a threshold must be set or both type cannot be used simultaneously.");
64 if (!usage
->domain
.set
) {
65 ERR("Invalid buffer usage condition: a domain must be set.");
74 static int lttng_condition_buffer_usage_serialize(const struct lttng_condition
*condition
,
75 struct lttng_payload
*payload
)
78 struct lttng_condition_buffer_usage
*usage
;
79 size_t session_name_len
, channel_name_len
;
80 struct lttng_condition_buffer_usage_comm usage_comm
= {};
82 if (!condition
|| !IS_USAGE_CONDITION(condition
)) {
87 DBG("Serializing buffer usage condition");
88 usage
= lttng::utils::container_of(condition
, <tng_condition_buffer_usage::parent
);
90 session_name_len
= strlen(usage
->session_name
) + 1;
91 channel_name_len
= strlen(usage
->channel_name
) + 1;
92 if (session_name_len
> LTTNG_NAME_MAX
|| channel_name_len
> LTTNG_NAME_MAX
) {
97 usage_comm
.threshold_set_in_bytes
= !!usage
->threshold_bytes
.set
;
98 usage_comm
.session_name_len
= session_name_len
;
99 usage_comm
.channel_name_len
= channel_name_len
;
100 usage_comm
.domain_type
= (int8_t) usage
->domain
.type
;
102 if (usage
->threshold_bytes
.set
) {
103 usage_comm
.threshold_bytes
= usage
->threshold_bytes
.value
;
105 usage_comm
.threshold_ratio
= usage
->threshold_ratio
.value
;
108 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &usage_comm
, sizeof(usage_comm
));
113 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, usage
->session_name
, session_name_len
);
118 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, usage
->channel_name
, channel_name_len
);
126 static bool lttng_condition_buffer_usage_is_equal(const struct lttng_condition
*_a
,
127 const struct lttng_condition
*_b
)
129 bool is_equal
= false;
130 struct lttng_condition_buffer_usage
*a
, *b
;
132 a
= lttng::utils::container_of(_a
, <tng_condition_buffer_usage::parent
);
133 b
= lttng::utils::container_of(_b
, <tng_condition_buffer_usage::parent
);
135 if ((a
->threshold_ratio
.set
&& !b
->threshold_ratio
.set
) ||
136 (a
->threshold_bytes
.set
&& !b
->threshold_bytes
.set
)) {
140 if (a
->threshold_ratio
.set
&& b
->threshold_ratio
.set
) {
141 double a_value
, b_value
, diff
;
143 a_value
= a
->threshold_ratio
.value
;
144 b_value
= b
->threshold_ratio
.value
;
145 diff
= fabs(a_value
- b_value
);
147 if (diff
> DBL_EPSILON
) {
150 } else if (a
->threshold_bytes
.set
&& b
->threshold_bytes
.set
) {
151 uint64_t a_value
, b_value
;
153 a_value
= a
->threshold_bytes
.value
;
154 b_value
= b
->threshold_bytes
.value
;
155 if (a_value
!= b_value
) {
160 /* Condition is not valid if this is not true. */
161 LTTNG_ASSERT(a
->session_name
);
162 LTTNG_ASSERT(b
->session_name
);
163 if (strcmp(a
->session_name
, b
->session_name
) != 0) {
167 LTTNG_ASSERT(a
->channel_name
);
168 LTTNG_ASSERT(b
->channel_name
);
169 if (strcmp(a
->channel_name
, b
->channel_name
) != 0) {
173 LTTNG_ASSERT(a
->domain
.set
);
174 LTTNG_ASSERT(b
->domain
.set
);
175 if (a
->domain
.type
!= b
->domain
.type
) {
183 static enum lttng_error_code
184 lttng_condition_buffer_usage_mi_serialize(const struct lttng_condition
*condition
,
185 struct mi_writer
*writer
)
188 enum lttng_error_code ret_code
;
189 enum lttng_condition_status status
;
190 const char *session_name
= nullptr, *channel_name
= nullptr;
191 enum lttng_domain_type domain_type
;
192 bool is_threshold_bytes
= false;
193 double threshold_ratio
;
194 uint64_t threshold_bytes
;
195 const char *condition_type_str
= nullptr;
197 LTTNG_ASSERT(condition
);
198 LTTNG_ASSERT(IS_USAGE_CONDITION(condition
));
200 status
= lttng_condition_buffer_usage_get_session_name(condition
, &session_name
);
201 LTTNG_ASSERT(status
== LTTNG_CONDITION_STATUS_OK
);
202 LTTNG_ASSERT(session_name
);
204 status
= lttng_condition_buffer_usage_get_channel_name(condition
, &channel_name
);
205 LTTNG_ASSERT(status
== LTTNG_CONDITION_STATUS_OK
);
206 LTTNG_ASSERT(session_name
);
208 status
= lttng_condition_buffer_usage_get_domain_type(condition
, &domain_type
);
209 LTTNG_ASSERT(status
== LTTNG_CONDITION_STATUS_OK
);
211 status
= lttng_condition_buffer_usage_get_threshold(condition
, &threshold_bytes
);
212 if (status
== LTTNG_CONDITION_STATUS_OK
) {
213 is_threshold_bytes
= true;
214 } else if (status
!= LTTNG_CONDITION_STATUS_UNSET
) {
215 /* Unexpected at this stage. */
216 ret_code
= LTTNG_ERR_INVALID
;
220 if (!is_threshold_bytes
) {
221 status
= lttng_condition_buffer_usage_get_threshold_ratio(condition
,
223 LTTNG_ASSERT(status
== LTTNG_CONDITION_STATUS_OK
);
226 switch (lttng_condition_get_type(condition
)) {
227 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
:
228 condition_type_str
= mi_lttng_element_condition_buffer_usage_high
;
230 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
:
231 condition_type_str
= mi_lttng_element_condition_buffer_usage_low
;
238 /* Open the sub type condition element. */
239 ret
= mi_lttng_writer_open_element(writer
, condition_type_str
);
245 ret
= mi_lttng_writer_write_element_string(
246 writer
, mi_lttng_element_session_name
, session_name
);
252 ret
= mi_lttng_writer_write_element_string(
253 writer
, mi_lttng_element_condition_channel_name
, channel_name
);
259 ret
= mi_lttng_writer_write_element_string(
260 writer
, config_element_domain
, mi_lttng_domaintype_string(domain_type
));
265 if (is_threshold_bytes
) {
266 /* Usage in bytes. */
267 ret
= mi_lttng_writer_write_element_unsigned_int(
268 writer
, mi_lttng_element_condition_threshold_bytes
, threshold_bytes
);
274 ret
= mi_lttng_writer_write_element_double(
275 writer
, mi_lttng_element_condition_threshold_ratio
, threshold_ratio
);
281 /* Closing sub type condition element. */
282 ret
= mi_lttng_writer_close_element(writer
);
291 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
296 static struct lttng_condition
*lttng_condition_buffer_usage_create(enum lttng_condition_type type
)
298 struct lttng_condition_buffer_usage
*condition
;
300 condition
= zmalloc
<lttng_condition_buffer_usage
>();
305 lttng_condition_init(&condition
->parent
, type
);
306 condition
->parent
.validate
= lttng_condition_buffer_usage_validate
;
307 condition
->parent
.serialize
= lttng_condition_buffer_usage_serialize
;
308 condition
->parent
.equal
= lttng_condition_buffer_usage_is_equal
;
309 condition
->parent
.destroy
= lttng_condition_buffer_usage_destroy
;
310 condition
->parent
.mi_serialize
= lttng_condition_buffer_usage_mi_serialize
;
311 return &condition
->parent
;
314 struct lttng_condition
*lttng_condition_buffer_usage_low_create(void)
316 return lttng_condition_buffer_usage_create(LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
);
319 struct lttng_condition
*lttng_condition_buffer_usage_high_create(void)
321 return lttng_condition_buffer_usage_create(LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
);
324 static ssize_t
init_condition_from_payload(struct lttng_condition
*condition
,
325 struct lttng_payload_view
*src_view
)
327 ssize_t ret
, condition_size
;
328 enum lttng_condition_status status
;
329 enum lttng_domain_type domain_type
;
330 const char *session_name
, *channel_name
;
331 struct lttng_buffer_view names_view
;
332 const struct lttng_condition_buffer_usage_comm
*condition_comm
;
333 const struct lttng_payload_view condition_comm_view
=
334 lttng_payload_view_from_view(src_view
, 0, sizeof(*condition_comm
));
336 if (!lttng_payload_view_is_valid(&condition_comm_view
)) {
337 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain header");
342 condition_comm
= (typeof(condition_comm
)) condition_comm_view
.buffer
.data
;
343 names_view
= lttng_buffer_view_from_view(&src_view
->buffer
, sizeof(*condition_comm
), -1);
345 if (condition_comm
->session_name_len
> LTTNG_NAME_MAX
||
346 condition_comm
->channel_name_len
> LTTNG_NAME_MAX
) {
347 ERR("Failed to initialize from malformed condition buffer: name exceeds LTTNG_MAX_NAME");
352 if (names_view
.size
<
353 (condition_comm
->session_name_len
+ condition_comm
->channel_name_len
)) {
354 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain element names");
359 if (condition_comm
->threshold_set_in_bytes
) {
360 status
= lttng_condition_buffer_usage_set_threshold(
361 condition
, condition_comm
->threshold_bytes
);
363 status
= lttng_condition_buffer_usage_set_threshold_ratio(
364 condition
, condition_comm
->threshold_ratio
);
367 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
368 ERR("Failed to initialize buffer usage condition threshold");
373 if (condition_comm
->domain_type
<= LTTNG_DOMAIN_NONE
||
374 condition_comm
->domain_type
> LTTNG_DOMAIN_PYTHON
) {
375 /* Invalid domain value. */
376 ERR("Invalid domain type value (%i) found in condition buffer",
377 (int) condition_comm
->domain_type
);
382 domain_type
= (enum lttng_domain_type
) condition_comm
->domain_type
;
383 status
= lttng_condition_buffer_usage_set_domain_type(condition
, domain_type
);
384 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
385 ERR("Failed to set buffer usage condition domain");
390 session_name
= names_view
.data
;
391 if (*(session_name
+ condition_comm
->session_name_len
- 1) != '\0') {
392 ERR("Malformed session name encountered in condition buffer");
397 channel_name
= session_name
+ condition_comm
->session_name_len
;
398 if (*(channel_name
+ condition_comm
->channel_name_len
- 1) != '\0') {
399 ERR("Malformed channel name encountered in condition buffer");
404 status
= lttng_condition_buffer_usage_set_session_name(condition
, session_name
);
405 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
406 ERR("Failed to set buffer usage session name");
411 status
= lttng_condition_buffer_usage_set_channel_name(condition
, channel_name
);
412 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
413 ERR("Failed to set buffer usage channel name");
418 if (!lttng_condition_validate(condition
)) {
423 condition_size
= sizeof(*condition_comm
) + (ssize_t
) condition_comm
->session_name_len
+
424 (ssize_t
) condition_comm
->channel_name_len
;
425 ret
= condition_size
;
430 ssize_t
lttng_condition_buffer_usage_low_create_from_payload(struct lttng_payload_view
*view
,
431 struct lttng_condition
**_condition
)
434 struct lttng_condition
*condition
= lttng_condition_buffer_usage_low_create();
436 if (!_condition
|| !condition
) {
441 ret
= init_condition_from_payload(condition
, view
);
446 *_condition
= condition
;
449 lttng_condition_destroy(condition
);
453 ssize_t
lttng_condition_buffer_usage_high_create_from_payload(struct lttng_payload_view
*view
,
454 struct lttng_condition
**_condition
)
457 struct lttng_condition
*condition
= lttng_condition_buffer_usage_high_create();
459 if (!_condition
|| !condition
) {
464 ret
= init_condition_from_payload(condition
, view
);
469 *_condition
= condition
;
472 lttng_condition_destroy(condition
);
476 static struct lttng_evaluation
*create_evaluation_from_payload(enum lttng_condition_type type
,
477 struct lttng_payload_view
*view
)
479 const struct lttng_evaluation_buffer_usage_comm
*comm
= (typeof(comm
)) view
->buffer
.data
;
480 struct lttng_evaluation
*evaluation
= nullptr;
482 if (view
->buffer
.size
< sizeof(*comm
)) {
487 lttng_evaluation_buffer_usage_create(type
, comm
->buffer_use
, comm
->buffer_capacity
);
492 ssize_t
lttng_evaluation_buffer_usage_low_create_from_payload(struct lttng_payload_view
*view
,
493 struct lttng_evaluation
**_evaluation
)
496 struct lttng_evaluation
*evaluation
= nullptr;
503 evaluation
= create_evaluation_from_payload(LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
, view
);
509 *_evaluation
= evaluation
;
510 ret
= sizeof(struct lttng_evaluation_buffer_usage_comm
);
513 lttng_evaluation_destroy(evaluation
);
518 lttng_evaluation_buffer_usage_high_create_from_payload(struct lttng_payload_view
*view
,
519 struct lttng_evaluation
**_evaluation
)
522 struct lttng_evaluation
*evaluation
= nullptr;
529 evaluation
= create_evaluation_from_payload(LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
, view
);
535 *_evaluation
= evaluation
;
536 ret
= sizeof(struct lttng_evaluation_buffer_usage_comm
);
539 lttng_evaluation_destroy(evaluation
);
543 enum lttng_condition_status
544 lttng_condition_buffer_usage_get_threshold_ratio(const struct lttng_condition
*condition
,
545 double *threshold_ratio
)
547 struct lttng_condition_buffer_usage
*usage
;
548 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
550 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !threshold_ratio
) {
551 status
= LTTNG_CONDITION_STATUS_INVALID
;
555 usage
= lttng::utils::container_of(condition
, <tng_condition_buffer_usage::parent
);
556 if (!usage
->threshold_ratio
.set
) {
557 status
= LTTNG_CONDITION_STATUS_UNSET
;
560 *threshold_ratio
= usage
->threshold_ratio
.value
;
565 /* threshold_ratio expressed as [0.0, 1.0]. */
566 enum lttng_condition_status
567 lttng_condition_buffer_usage_set_threshold_ratio(struct lttng_condition
*condition
,
568 double threshold_ratio
)
570 struct lttng_condition_buffer_usage
*usage
;
571 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
573 if (!condition
|| !IS_USAGE_CONDITION(condition
) || threshold_ratio
< 0.0 ||
574 threshold_ratio
> 1.0) {
575 status
= LTTNG_CONDITION_STATUS_INVALID
;
579 usage
= lttng::utils::container_of(condition
, <tng_condition_buffer_usage::parent
);
580 usage
->threshold_ratio
.set
= true;
581 usage
->threshold_bytes
.set
= false;
582 usage
->threshold_ratio
.value
= threshold_ratio
;
587 enum lttng_condition_status
588 lttng_condition_buffer_usage_get_threshold(const struct lttng_condition
*condition
,
589 uint64_t *threshold_bytes
)
591 struct lttng_condition_buffer_usage
*usage
;
592 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
594 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !threshold_bytes
) {
595 status
= LTTNG_CONDITION_STATUS_INVALID
;
599 usage
= lttng::utils::container_of(condition
, <tng_condition_buffer_usage::parent
);
600 if (!usage
->threshold_bytes
.set
) {
601 status
= LTTNG_CONDITION_STATUS_UNSET
;
604 *threshold_bytes
= usage
->threshold_bytes
.value
;
609 enum lttng_condition_status
610 lttng_condition_buffer_usage_set_threshold(struct lttng_condition
*condition
,
611 uint64_t threshold_bytes
)
613 struct lttng_condition_buffer_usage
*usage
;
614 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
616 if (!condition
|| !IS_USAGE_CONDITION(condition
)) {
617 status
= LTTNG_CONDITION_STATUS_INVALID
;
621 usage
= lttng::utils::container_of(condition
, <tng_condition_buffer_usage::parent
);
622 usage
->threshold_ratio
.set
= false;
623 usage
->threshold_bytes
.set
= true;
624 usage
->threshold_bytes
.value
= threshold_bytes
;
629 enum lttng_condition_status
630 lttng_condition_buffer_usage_get_session_name(const struct lttng_condition
*condition
,
631 const char **session_name
)
633 struct lttng_condition_buffer_usage
*usage
;
634 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
636 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !session_name
) {
637 status
= LTTNG_CONDITION_STATUS_INVALID
;
641 usage
= lttng::utils::container_of(condition
, <tng_condition_buffer_usage::parent
);
642 if (!usage
->session_name
) {
643 status
= LTTNG_CONDITION_STATUS_UNSET
;
646 *session_name
= usage
->session_name
;
651 enum lttng_condition_status
652 lttng_condition_buffer_usage_set_session_name(struct lttng_condition
*condition
,
653 const char *session_name
)
655 char *session_name_copy
;
656 struct lttng_condition_buffer_usage
*usage
;
657 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
659 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !session_name
||
660 strlen(session_name
) == 0) {
661 status
= LTTNG_CONDITION_STATUS_INVALID
;
665 usage
= lttng::utils::container_of(condition
, <tng_condition_buffer_usage::parent
);
666 session_name_copy
= strdup(session_name
);
667 if (!session_name_copy
) {
668 status
= LTTNG_CONDITION_STATUS_ERROR
;
672 if (usage
->session_name
) {
673 free(usage
->session_name
);
675 usage
->session_name
= session_name_copy
;
680 enum lttng_condition_status
681 lttng_condition_buffer_usage_get_channel_name(const struct lttng_condition
*condition
,
682 const char **channel_name
)
684 struct lttng_condition_buffer_usage
*usage
;
685 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
687 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !channel_name
) {
688 status
= LTTNG_CONDITION_STATUS_INVALID
;
692 usage
= lttng::utils::container_of(condition
, <tng_condition_buffer_usage::parent
);
693 if (!usage
->channel_name
) {
694 status
= LTTNG_CONDITION_STATUS_UNSET
;
697 *channel_name
= usage
->channel_name
;
702 enum lttng_condition_status
703 lttng_condition_buffer_usage_set_channel_name(struct lttng_condition
*condition
,
704 const char *channel_name
)
706 char *channel_name_copy
;
707 struct lttng_condition_buffer_usage
*usage
;
708 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
710 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !channel_name
||
711 strlen(channel_name
) == 0) {
712 status
= LTTNG_CONDITION_STATUS_INVALID
;
716 usage
= lttng::utils::container_of(condition
, <tng_condition_buffer_usage::parent
);
717 channel_name_copy
= strdup(channel_name
);
718 if (!channel_name_copy
) {
719 status
= LTTNG_CONDITION_STATUS_ERROR
;
723 if (usage
->channel_name
) {
724 free(usage
->channel_name
);
726 usage
->channel_name
= channel_name_copy
;
731 enum lttng_condition_status
732 lttng_condition_buffer_usage_get_domain_type(const struct lttng_condition
*condition
,
733 enum lttng_domain_type
*type
)
735 struct lttng_condition_buffer_usage
*usage
;
736 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
738 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !type
) {
739 status
= LTTNG_CONDITION_STATUS_INVALID
;
743 usage
= lttng::utils::container_of(condition
, <tng_condition_buffer_usage::parent
);
744 if (!usage
->domain
.set
) {
745 status
= LTTNG_CONDITION_STATUS_UNSET
;
748 *type
= usage
->domain
.type
;
753 enum lttng_condition_status
754 lttng_condition_buffer_usage_set_domain_type(struct lttng_condition
*condition
,
755 enum lttng_domain_type type
)
757 struct lttng_condition_buffer_usage
*usage
;
758 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
760 if (!condition
|| !IS_USAGE_CONDITION(condition
) || type
== LTTNG_DOMAIN_NONE
) {
761 status
= LTTNG_CONDITION_STATUS_INVALID
;
765 usage
= lttng::utils::container_of(condition
, <tng_condition_buffer_usage::parent
);
766 usage
->domain
.set
= true;
767 usage
->domain
.type
= type
;
772 static int lttng_evaluation_buffer_usage_serialize(const struct lttng_evaluation
*evaluation
,
773 struct lttng_payload
*payload
)
775 struct lttng_evaluation_buffer_usage
*usage
;
776 struct lttng_evaluation_buffer_usage_comm comm
;
778 usage
= lttng::utils::container_of(evaluation
, <tng_evaluation_buffer_usage::parent
);
779 comm
.buffer_use
= usage
->buffer_use
;
780 comm
.buffer_capacity
= usage
->buffer_capacity
;
782 return lttng_dynamic_buffer_append(&payload
->buffer
, &comm
, sizeof(comm
));
785 static void lttng_evaluation_buffer_usage_destroy(struct lttng_evaluation
*evaluation
)
787 struct lttng_evaluation_buffer_usage
*usage
;
789 usage
= lttng::utils::container_of(evaluation
, <tng_evaluation_buffer_usage::parent
);
793 struct lttng_evaluation
*lttng_evaluation_buffer_usage_create(enum lttng_condition_type type
,
797 struct lttng_evaluation_buffer_usage
*usage
;
799 usage
= zmalloc
<lttng_evaluation_buffer_usage
>();
804 usage
->parent
.type
= type
;
805 usage
->buffer_use
= use
;
806 usage
->buffer_capacity
= capacity
;
807 usage
->parent
.serialize
= lttng_evaluation_buffer_usage_serialize
;
808 usage
->parent
.destroy
= lttng_evaluation_buffer_usage_destroy
;
810 return &usage
->parent
;
814 * Get the sampled buffer usage which caused the associated condition to
815 * evaluate to "true".
817 enum lttng_evaluation_status
818 lttng_evaluation_buffer_usage_get_usage_ratio(const struct lttng_evaluation
*evaluation
,
821 struct lttng_evaluation_buffer_usage
*usage
;
822 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
824 if (!evaluation
|| !is_usage_evaluation(evaluation
) || !usage_ratio
) {
825 status
= LTTNG_EVALUATION_STATUS_INVALID
;
829 usage
= lttng::utils::container_of(evaluation
, <tng_evaluation_buffer_usage::parent
);
830 *usage_ratio
= (double) usage
->buffer_use
/ (double) usage
->buffer_capacity
;
835 enum lttng_evaluation_status
836 lttng_evaluation_buffer_usage_get_usage(const struct lttng_evaluation
*evaluation
,
837 uint64_t *usage_bytes
)
839 struct lttng_evaluation_buffer_usage
*usage
;
840 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
842 if (!evaluation
|| !is_usage_evaluation(evaluation
) || !usage_bytes
) {
843 status
= LTTNG_EVALUATION_STATUS_INVALID
;
847 usage
= lttng::utils::container_of(evaluation
, <tng_evaluation_buffer_usage::parent
);
848 *usage_bytes
= usage
->buffer_use
;