2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #include <common/error.h>
9 #include <common/macros.h>
10 #include <common/mi-lttng.h>
12 #include <lttng/condition/buffer-usage-internal.h>
13 #include <lttng/condition/condition-internal.h>
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
= container_of(condition
, struct lttng_condition_buffer_usage
,
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
= container_of(condition
, struct lttng_condition_buffer_usage
,
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
= container_of(condition
, struct lttng_condition_buffer_usage
,
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
= container_of(_a
, struct lttng_condition_buffer_usage
, parent
);
146 b
= container_of(_b
, struct lttng_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(sizeof(struct 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
;
465 ssize_t
lttng_condition_buffer_usage_low_create_from_payload(
466 struct lttng_payload_view
*view
,
467 struct lttng_condition
**_condition
)
470 struct lttng_condition
*condition
=
471 lttng_condition_buffer_usage_low_create();
473 if (!_condition
|| !condition
) {
478 ret
= init_condition_from_payload(condition
, view
);
483 *_condition
= condition
;
486 lttng_condition_destroy(condition
);
491 ssize_t
lttng_condition_buffer_usage_high_create_from_payload(
492 struct lttng_payload_view
*view
,
493 struct lttng_condition
**_condition
)
496 struct lttng_condition
*condition
=
497 lttng_condition_buffer_usage_high_create();
499 if (!_condition
|| !condition
) {
504 ret
= init_condition_from_payload(condition
, view
);
509 *_condition
= condition
;
512 lttng_condition_destroy(condition
);
517 struct lttng_evaluation
*create_evaluation_from_payload(
518 enum lttng_condition_type type
,
519 struct lttng_payload_view
*view
)
521 const struct lttng_evaluation_buffer_usage_comm
*comm
=
522 (typeof(comm
)) view
->buffer
.data
;
523 struct lttng_evaluation
*evaluation
= NULL
;
525 if (view
->buffer
.size
< sizeof(*comm
)) {
529 evaluation
= lttng_evaluation_buffer_usage_create(type
,
530 comm
->buffer_use
, comm
->buffer_capacity
);
536 ssize_t
lttng_evaluation_buffer_usage_low_create_from_payload(
537 struct lttng_payload_view
*view
,
538 struct lttng_evaluation
**_evaluation
)
541 struct lttng_evaluation
*evaluation
= NULL
;
548 evaluation
= create_evaluation_from_payload(
549 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
, view
);
555 *_evaluation
= evaluation
;
556 ret
= sizeof(struct lttng_evaluation_buffer_usage_comm
);
559 lttng_evaluation_destroy(evaluation
);
564 ssize_t
lttng_evaluation_buffer_usage_high_create_from_payload(
565 struct lttng_payload_view
*view
,
566 struct lttng_evaluation
**_evaluation
)
569 struct lttng_evaluation
*evaluation
= NULL
;
576 evaluation
= create_evaluation_from_payload(
577 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
, view
);
583 *_evaluation
= evaluation
;
584 ret
= sizeof(struct lttng_evaluation_buffer_usage_comm
);
587 lttng_evaluation_destroy(evaluation
);
591 enum lttng_condition_status
592 lttng_condition_buffer_usage_get_threshold_ratio(
593 const struct lttng_condition
*condition
,
594 double *threshold_ratio
)
596 struct lttng_condition_buffer_usage
*usage
;
597 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
599 if (!condition
|| !IS_USAGE_CONDITION(condition
) ||
601 status
= LTTNG_CONDITION_STATUS_INVALID
;
605 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
607 if (!usage
->threshold_ratio
.set
) {
608 status
= LTTNG_CONDITION_STATUS_UNSET
;
611 *threshold_ratio
= usage
->threshold_ratio
.value
;
616 /* threshold_ratio expressed as [0.0, 1.0]. */
617 enum lttng_condition_status
618 lttng_condition_buffer_usage_set_threshold_ratio(
619 struct lttng_condition
*condition
, double threshold_ratio
)
621 struct lttng_condition_buffer_usage
*usage
;
622 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
624 if (!condition
|| !IS_USAGE_CONDITION(condition
) ||
625 threshold_ratio
< 0.0 ||
626 threshold_ratio
> 1.0) {
627 status
= LTTNG_CONDITION_STATUS_INVALID
;
631 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
633 usage
->threshold_ratio
.set
= true;
634 usage
->threshold_bytes
.set
= false;
635 usage
->threshold_ratio
.value
= threshold_ratio
;
640 enum lttng_condition_status
641 lttng_condition_buffer_usage_get_threshold(
642 const struct lttng_condition
*condition
,
643 uint64_t *threshold_bytes
)
645 struct lttng_condition_buffer_usage
*usage
;
646 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
648 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !threshold_bytes
) {
649 status
= LTTNG_CONDITION_STATUS_INVALID
;
653 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
655 if (!usage
->threshold_bytes
.set
) {
656 status
= LTTNG_CONDITION_STATUS_UNSET
;
659 *threshold_bytes
= usage
->threshold_bytes
.value
;
664 enum lttng_condition_status
665 lttng_condition_buffer_usage_set_threshold(
666 struct lttng_condition
*condition
, uint64_t threshold_bytes
)
668 struct lttng_condition_buffer_usage
*usage
;
669 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
671 if (!condition
|| !IS_USAGE_CONDITION(condition
)) {
672 status
= LTTNG_CONDITION_STATUS_INVALID
;
676 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
678 usage
->threshold_ratio
.set
= false;
679 usage
->threshold_bytes
.set
= true;
680 usage
->threshold_bytes
.value
= threshold_bytes
;
685 enum lttng_condition_status
686 lttng_condition_buffer_usage_get_session_name(
687 const struct lttng_condition
*condition
,
688 const char **session_name
)
690 struct lttng_condition_buffer_usage
*usage
;
691 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
693 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !session_name
) {
694 status
= LTTNG_CONDITION_STATUS_INVALID
;
698 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
700 if (!usage
->session_name
) {
701 status
= LTTNG_CONDITION_STATUS_UNSET
;
704 *session_name
= usage
->session_name
;
709 enum lttng_condition_status
710 lttng_condition_buffer_usage_set_session_name(
711 struct lttng_condition
*condition
, const char *session_name
)
713 char *session_name_copy
;
714 struct lttng_condition_buffer_usage
*usage
;
715 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
717 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !session_name
||
718 strlen(session_name
) == 0) {
719 status
= LTTNG_CONDITION_STATUS_INVALID
;
723 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
725 session_name_copy
= strdup(session_name
);
726 if (!session_name_copy
) {
727 status
= LTTNG_CONDITION_STATUS_ERROR
;
731 if (usage
->session_name
) {
732 free(usage
->session_name
);
734 usage
->session_name
= session_name_copy
;
739 enum lttng_condition_status
740 lttng_condition_buffer_usage_get_channel_name(
741 const struct lttng_condition
*condition
,
742 const char **channel_name
)
744 struct lttng_condition_buffer_usage
*usage
;
745 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
747 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !channel_name
) {
748 status
= LTTNG_CONDITION_STATUS_INVALID
;
752 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
754 if (!usage
->channel_name
) {
755 status
= LTTNG_CONDITION_STATUS_UNSET
;
758 *channel_name
= usage
->channel_name
;
763 enum lttng_condition_status
764 lttng_condition_buffer_usage_set_channel_name(
765 struct lttng_condition
*condition
, const char *channel_name
)
767 char *channel_name_copy
;
768 struct lttng_condition_buffer_usage
*usage
;
769 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
771 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !channel_name
||
772 strlen(channel_name
) == 0) {
773 status
= LTTNG_CONDITION_STATUS_INVALID
;
777 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
779 channel_name_copy
= strdup(channel_name
);
780 if (!channel_name_copy
) {
781 status
= LTTNG_CONDITION_STATUS_ERROR
;
785 if (usage
->channel_name
) {
786 free(usage
->channel_name
);
788 usage
->channel_name
= channel_name_copy
;
793 enum lttng_condition_status
794 lttng_condition_buffer_usage_get_domain_type(
795 const struct lttng_condition
*condition
,
796 enum lttng_domain_type
*type
)
798 struct lttng_condition_buffer_usage
*usage
;
799 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
801 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !type
) {
802 status
= LTTNG_CONDITION_STATUS_INVALID
;
806 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
808 if (!usage
->domain
.set
) {
809 status
= LTTNG_CONDITION_STATUS_UNSET
;
812 *type
= usage
->domain
.type
;
817 enum lttng_condition_status
818 lttng_condition_buffer_usage_set_domain_type(
819 struct lttng_condition
*condition
, enum lttng_domain_type type
)
821 struct lttng_condition_buffer_usage
*usage
;
822 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
824 if (!condition
|| !IS_USAGE_CONDITION(condition
) ||
825 type
== LTTNG_DOMAIN_NONE
) {
826 status
= LTTNG_CONDITION_STATUS_INVALID
;
830 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
832 usage
->domain
.set
= true;
833 usage
->domain
.type
= type
;
839 int lttng_evaluation_buffer_usage_serialize(
840 const struct lttng_evaluation
*evaluation
,
841 struct lttng_payload
*payload
)
843 struct lttng_evaluation_buffer_usage
*usage
;
844 struct lttng_evaluation_buffer_usage_comm comm
;
846 usage
= container_of(evaluation
, struct lttng_evaluation_buffer_usage
,
848 comm
.buffer_use
= usage
->buffer_use
;
849 comm
.buffer_capacity
= usage
->buffer_capacity
;
851 return lttng_dynamic_buffer_append(
852 &payload
->buffer
, &comm
, sizeof(comm
));
856 void lttng_evaluation_buffer_usage_destroy(
857 struct lttng_evaluation
*evaluation
)
859 struct lttng_evaluation_buffer_usage
*usage
;
861 usage
= container_of(evaluation
, struct lttng_evaluation_buffer_usage
,
867 struct lttng_evaluation
*lttng_evaluation_buffer_usage_create(
868 enum lttng_condition_type type
, uint64_t use
, uint64_t capacity
)
870 struct lttng_evaluation_buffer_usage
*usage
;
872 usage
= zmalloc(sizeof(struct lttng_evaluation_buffer_usage
));
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
;
883 return &usage
->parent
;
887 * Get the sampled buffer usage which caused the associated condition to
888 * evaluate to "true".
890 enum lttng_evaluation_status
891 lttng_evaluation_buffer_usage_get_usage_ratio(
892 const struct lttng_evaluation
*evaluation
, double *usage_ratio
)
894 struct lttng_evaluation_buffer_usage
*usage
;
895 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
897 if (!evaluation
|| !is_usage_evaluation(evaluation
) || !usage_ratio
) {
898 status
= LTTNG_EVALUATION_STATUS_INVALID
;
902 usage
= container_of(evaluation
, struct lttng_evaluation_buffer_usage
,
904 *usage_ratio
= (double) usage
->buffer_use
/
905 (double) usage
->buffer_capacity
;
910 enum lttng_evaluation_status
911 lttng_evaluation_buffer_usage_get_usage(
912 const struct lttng_evaluation
*evaluation
,
913 uint64_t *usage_bytes
)
915 struct lttng_evaluation_buffer_usage
*usage
;
916 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
918 if (!evaluation
|| !is_usage_evaluation(evaluation
) || !usage_bytes
) {
919 status
= LTTNG_EVALUATION_STATUS_INVALID
;
923 usage
= container_of(evaluation
, struct lttng_evaluation_buffer_usage
,
925 *usage_bytes
= usage
->buffer_use
;