2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
9 #include <common/error.h>
10 #include <common/macros.h>
11 #include <common/mi-lttng.h>
13 #include <lttng/condition/buffer-usage-internal.h>
14 #include <lttng/condition/condition-internal.h>
18 #define IS_USAGE_CONDITION(condition) ( \
19 lttng_condition_get_type(condition) == LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW || \
20 lttng_condition_get_type(condition) == LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH \
24 bool is_usage_evaluation(const struct lttng_evaluation
*evaluation
)
26 enum lttng_condition_type type
= lttng_evaluation_get_type(evaluation
);
28 return type
== LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
||
29 type
== LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
;
33 void lttng_condition_buffer_usage_destroy(struct lttng_condition
*condition
)
35 struct lttng_condition_buffer_usage
*usage
;
37 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
40 free(usage
->session_name
);
41 free(usage
->channel_name
);
46 bool lttng_condition_buffer_usage_validate(
47 const struct lttng_condition
*condition
)
50 struct lttng_condition_buffer_usage
*usage
;
56 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
58 if (!usage
->session_name
) {
59 ERR("Invalid buffer condition: a target session name must be set.");
62 if (!usage
->channel_name
) {
63 ERR("Invalid buffer condition: a target channel name must be set.");
66 if (usage
->threshold_ratio
.set
== usage
->threshold_bytes
.set
) {
67 ERR("Invalid buffer condition: a threshold must be set or both type cannot be used simultaneously.");
70 if (!usage
->domain
.set
) {
71 ERR("Invalid buffer usage condition: a domain must be set.");
81 int lttng_condition_buffer_usage_serialize(
82 const struct lttng_condition
*condition
,
83 struct lttng_payload
*payload
)
86 struct lttng_condition_buffer_usage
*usage
;
87 size_t session_name_len
, channel_name_len
;
88 struct lttng_condition_buffer_usage_comm usage_comm
= {};
90 if (!condition
|| !IS_USAGE_CONDITION(condition
)) {
95 DBG("Serializing buffer usage condition");
96 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
99 session_name_len
= strlen(usage
->session_name
) + 1;
100 channel_name_len
= strlen(usage
->channel_name
) + 1;
101 if (session_name_len
> LTTNG_NAME_MAX
||
102 channel_name_len
> LTTNG_NAME_MAX
) {
107 usage_comm
.threshold_set_in_bytes
= !!usage
->threshold_bytes
.set
;
108 usage_comm
.session_name_len
= session_name_len
;
109 usage_comm
.channel_name_len
= channel_name_len
;
110 usage_comm
.domain_type
= (int8_t) usage
->domain
.type
;
112 if (usage
->threshold_bytes
.set
) {
113 usage_comm
.threshold_bytes
= usage
->threshold_bytes
.value
;
115 usage_comm
.threshold_ratio
= usage
->threshold_ratio
.value
;
118 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &usage_comm
,
124 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, usage
->session_name
,
130 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, usage
->channel_name
,
140 bool lttng_condition_buffer_usage_is_equal(const struct lttng_condition
*_a
,
141 const struct lttng_condition
*_b
)
143 bool is_equal
= false;
144 struct lttng_condition_buffer_usage
*a
, *b
;
146 a
= container_of(_a
, struct lttng_condition_buffer_usage
, parent
);
147 b
= container_of(_b
, struct lttng_condition_buffer_usage
, parent
);
149 if ((a
->threshold_ratio
.set
&& !b
->threshold_ratio
.set
) ||
150 (a
->threshold_bytes
.set
&& !b
->threshold_bytes
.set
)) {
154 if (a
->threshold_ratio
.set
&& b
->threshold_ratio
.set
) {
155 double a_value
, b_value
, diff
;
157 a_value
= a
->threshold_ratio
.value
;
158 b_value
= b
->threshold_ratio
.value
;
159 diff
= fabs(a_value
- b_value
);
161 if (diff
> DBL_EPSILON
) {
164 } else if (a
->threshold_bytes
.set
&& b
->threshold_bytes
.set
) {
165 uint64_t a_value
, b_value
;
167 a_value
= a
->threshold_bytes
.value
;
168 b_value
= b
->threshold_bytes
.value
;
169 if (a_value
!= b_value
) {
174 /* Condition is not valid if this is not true. */
175 assert(a
->session_name
);
176 assert(b
->session_name
);
177 if (strcmp(a
->session_name
, b
->session_name
)) {
181 assert(a
->channel_name
);
182 assert(b
->channel_name
);
183 if (strcmp(a
->channel_name
, b
->channel_name
)) {
187 assert(a
->domain
.set
);
188 assert(b
->domain
.set
);
189 if (a
->domain
.type
!= b
->domain
.type
) {
197 static enum lttng_error_code
lttng_condition_buffer_usage_mi_serialize(
198 const struct lttng_condition
*condition
,
199 struct mi_writer
*writer
)
202 enum lttng_error_code ret_code
;
203 enum lttng_condition_status status
;
204 const char *session_name
= NULL
, *channel_name
= NULL
;
205 enum lttng_domain_type domain_type
;
206 bool is_threshold_bytes
= false;
207 double threshold_ratio
;
208 uint64_t threshold_bytes
;
209 const char *condition_type_str
= NULL
;
212 assert(IS_USAGE_CONDITION(condition
));
214 status
= lttng_condition_buffer_usage_get_session_name(
215 condition
, &session_name
);
216 assert(status
== LTTNG_CONDITION_STATUS_OK
);
217 assert(session_name
);
219 status
= lttng_condition_buffer_usage_get_channel_name(
220 condition
, &channel_name
);
221 assert(status
== LTTNG_CONDITION_STATUS_OK
);
222 assert(session_name
);
224 status
= lttng_condition_buffer_usage_get_domain_type(
225 condition
, &domain_type
);
226 assert(status
== LTTNG_CONDITION_STATUS_OK
);
228 status
= lttng_condition_buffer_usage_get_threshold(
229 condition
, &threshold_bytes
);
230 if (status
== LTTNG_CONDITION_STATUS_OK
) {
231 is_threshold_bytes
= true;
232 } else if (status
!= LTTNG_CONDITION_STATUS_UNSET
) {
233 /* Unexpected at this stage. */
234 ret_code
= LTTNG_ERR_INVALID
;
238 if (!is_threshold_bytes
) {
239 status
= lttng_condition_buffer_usage_get_threshold_ratio(
240 condition
, &threshold_ratio
);
241 assert(status
== LTTNG_CONDITION_STATUS_OK
);
244 switch (lttng_condition_get_type(condition
)) {
245 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
:
247 mi_lttng_element_condition_buffer_usage_high
;
249 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
:
251 mi_lttng_element_condition_buffer_usage_low
;
258 /* Open the sub type condition element. */
259 ret
= mi_lttng_writer_open_element(writer
, condition_type_str
);
265 ret
= mi_lttng_writer_write_element_string(
266 writer
, mi_lttng_element_session_name
, session_name
);
272 ret
= mi_lttng_writer_write_element_string(writer
,
273 mi_lttng_element_condition_channel_name
, channel_name
);
279 ret
= mi_lttng_writer_write_element_string(writer
,
280 config_element_domain
,
281 mi_lttng_domaintype_string(domain_type
));
286 if (is_threshold_bytes
) {
287 /* Usage in bytes. */
288 ret
= mi_lttng_writer_write_element_unsigned_int(writer
,
289 mi_lttng_element_condition_threshold_bytes
,
296 ret
= mi_lttng_writer_write_element_double(writer
,
297 mi_lttng_element_condition_threshold_ratio
,
304 /* Closing sub type condition element. */
305 ret
= mi_lttng_writer_close_element(writer
);
314 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
320 struct lttng_condition
*lttng_condition_buffer_usage_create(
321 enum lttng_condition_type type
)
323 struct lttng_condition_buffer_usage
*condition
;
325 condition
= zmalloc(sizeof(struct lttng_condition_buffer_usage
));
330 lttng_condition_init(&condition
->parent
, type
);
331 condition
->parent
.validate
= lttng_condition_buffer_usage_validate
;
332 condition
->parent
.serialize
= lttng_condition_buffer_usage_serialize
;
333 condition
->parent
.equal
= lttng_condition_buffer_usage_is_equal
;
334 condition
->parent
.destroy
= lttng_condition_buffer_usage_destroy
;
335 condition
->parent
.mi_serialize
= lttng_condition_buffer_usage_mi_serialize
;
336 return &condition
->parent
;
339 struct lttng_condition
*lttng_condition_buffer_usage_low_create(void)
341 return lttng_condition_buffer_usage_create(
342 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
);
345 struct lttng_condition
*lttng_condition_buffer_usage_high_create(void)
347 return lttng_condition_buffer_usage_create(
348 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
);
352 ssize_t
init_condition_from_payload(struct lttng_condition
*condition
,
353 struct lttng_payload_view
*src_view
)
355 ssize_t ret
, condition_size
;
356 enum lttng_condition_status status
;
357 enum lttng_domain_type domain_type
;
358 const char *session_name
, *channel_name
;
359 struct lttng_buffer_view names_view
;
360 const struct lttng_condition_buffer_usage_comm
*condition_comm
;
361 const struct lttng_payload_view condition_comm_view
=
362 lttng_payload_view_from_view(
363 src_view
, 0, sizeof(*condition_comm
));
365 if (!lttng_payload_view_is_valid(&condition_comm_view
)) {
366 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain header");
371 condition_comm
= (typeof(condition_comm
)) condition_comm_view
.buffer
.data
;
372 names_view
= lttng_buffer_view_from_view(&src_view
->buffer
,
373 sizeof(*condition_comm
), -1);
375 if (condition_comm
->session_name_len
> LTTNG_NAME_MAX
||
376 condition_comm
->channel_name_len
> LTTNG_NAME_MAX
) {
377 ERR("Failed to initialize from malformed condition buffer: name exceeds LTTNG_MAX_NAME");
382 if (names_view
.size
<
383 (condition_comm
->session_name_len
+
384 condition_comm
->channel_name_len
)) {
385 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain element names");
390 if (condition_comm
->threshold_set_in_bytes
) {
391 status
= lttng_condition_buffer_usage_set_threshold(condition
,
392 condition_comm
->threshold_bytes
);
394 status
= lttng_condition_buffer_usage_set_threshold_ratio(
395 condition
, condition_comm
->threshold_ratio
);
398 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
399 ERR("Failed to initialize buffer usage condition threshold");
404 if (condition_comm
->domain_type
<= LTTNG_DOMAIN_NONE
||
405 condition_comm
->domain_type
> LTTNG_DOMAIN_PYTHON
) {
406 /* Invalid domain value. */
407 ERR("Invalid domain type value (%i) found in condition buffer",
408 (int) condition_comm
->domain_type
);
413 domain_type
= (enum lttng_domain_type
) condition_comm
->domain_type
;
414 status
= lttng_condition_buffer_usage_set_domain_type(condition
,
416 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
417 ERR("Failed to set buffer usage condition domain");
422 session_name
= names_view
.data
;
423 if (*(session_name
+ condition_comm
->session_name_len
- 1) != '\0') {
424 ERR("Malformed session name encountered in condition buffer");
429 channel_name
= session_name
+ condition_comm
->session_name_len
;
430 if (*(channel_name
+ condition_comm
->channel_name_len
- 1) != '\0') {
431 ERR("Malformed channel name encountered in condition buffer");
436 status
= lttng_condition_buffer_usage_set_session_name(condition
,
438 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
439 ERR("Failed to set buffer usage session name");
444 status
= lttng_condition_buffer_usage_set_channel_name(condition
,
446 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
447 ERR("Failed to set buffer usage channel name");
452 if (!lttng_condition_validate(condition
)) {
457 condition_size
= sizeof(*condition_comm
) +
458 (ssize_t
) condition_comm
->session_name_len
+
459 (ssize_t
) condition_comm
->channel_name_len
;
460 ret
= condition_size
;
466 ssize_t
lttng_condition_buffer_usage_low_create_from_payload(
467 struct lttng_payload_view
*view
,
468 struct lttng_condition
**_condition
)
471 struct lttng_condition
*condition
=
472 lttng_condition_buffer_usage_low_create();
474 if (!_condition
|| !condition
) {
479 ret
= init_condition_from_payload(condition
, view
);
484 *_condition
= condition
;
487 lttng_condition_destroy(condition
);
492 ssize_t
lttng_condition_buffer_usage_high_create_from_payload(
493 struct lttng_payload_view
*view
,
494 struct lttng_condition
**_condition
)
497 struct lttng_condition
*condition
=
498 lttng_condition_buffer_usage_high_create();
500 if (!_condition
|| !condition
) {
505 ret
= init_condition_from_payload(condition
, view
);
510 *_condition
= condition
;
513 lttng_condition_destroy(condition
);
518 struct lttng_evaluation
*create_evaluation_from_payload(
519 enum lttng_condition_type type
,
520 struct lttng_payload_view
*view
)
522 const struct lttng_evaluation_buffer_usage_comm
*comm
=
523 (typeof(comm
)) view
->buffer
.data
;
524 struct lttng_evaluation
*evaluation
= NULL
;
526 if (view
->buffer
.size
< sizeof(*comm
)) {
530 evaluation
= lttng_evaluation_buffer_usage_create(type
,
531 comm
->buffer_use
, comm
->buffer_capacity
);
537 ssize_t
lttng_evaluation_buffer_usage_low_create_from_payload(
538 struct lttng_payload_view
*view
,
539 struct lttng_evaluation
**_evaluation
)
542 struct lttng_evaluation
*evaluation
= NULL
;
549 evaluation
= create_evaluation_from_payload(
550 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
, view
);
556 *_evaluation
= evaluation
;
557 ret
= sizeof(struct lttng_evaluation_buffer_usage_comm
);
560 lttng_evaluation_destroy(evaluation
);
565 ssize_t
lttng_evaluation_buffer_usage_high_create_from_payload(
566 struct lttng_payload_view
*view
,
567 struct lttng_evaluation
**_evaluation
)
570 struct lttng_evaluation
*evaluation
= NULL
;
577 evaluation
= create_evaluation_from_payload(
578 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
, view
);
584 *_evaluation
= evaluation
;
585 ret
= sizeof(struct lttng_evaluation_buffer_usage_comm
);
588 lttng_evaluation_destroy(evaluation
);
592 enum lttng_condition_status
593 lttng_condition_buffer_usage_get_threshold_ratio(
594 const struct lttng_condition
*condition
,
595 double *threshold_ratio
)
597 struct lttng_condition_buffer_usage
*usage
;
598 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
600 if (!condition
|| !IS_USAGE_CONDITION(condition
) ||
602 status
= LTTNG_CONDITION_STATUS_INVALID
;
606 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
608 if (!usage
->threshold_ratio
.set
) {
609 status
= LTTNG_CONDITION_STATUS_UNSET
;
612 *threshold_ratio
= usage
->threshold_ratio
.value
;
617 /* threshold_ratio expressed as [0.0, 1.0]. */
618 enum lttng_condition_status
619 lttng_condition_buffer_usage_set_threshold_ratio(
620 struct lttng_condition
*condition
, double threshold_ratio
)
622 struct lttng_condition_buffer_usage
*usage
;
623 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
625 if (!condition
|| !IS_USAGE_CONDITION(condition
) ||
626 threshold_ratio
< 0.0 ||
627 threshold_ratio
> 1.0) {
628 status
= LTTNG_CONDITION_STATUS_INVALID
;
632 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
634 usage
->threshold_ratio
.set
= true;
635 usage
->threshold_bytes
.set
= false;
636 usage
->threshold_ratio
.value
= threshold_ratio
;
641 enum lttng_condition_status
642 lttng_condition_buffer_usage_get_threshold(
643 const struct lttng_condition
*condition
,
644 uint64_t *threshold_bytes
)
646 struct lttng_condition_buffer_usage
*usage
;
647 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
649 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !threshold_bytes
) {
650 status
= LTTNG_CONDITION_STATUS_INVALID
;
654 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
656 if (!usage
->threshold_bytes
.set
) {
657 status
= LTTNG_CONDITION_STATUS_UNSET
;
660 *threshold_bytes
= usage
->threshold_bytes
.value
;
665 enum lttng_condition_status
666 lttng_condition_buffer_usage_set_threshold(
667 struct lttng_condition
*condition
, uint64_t threshold_bytes
)
669 struct lttng_condition_buffer_usage
*usage
;
670 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
672 if (!condition
|| !IS_USAGE_CONDITION(condition
)) {
673 status
= LTTNG_CONDITION_STATUS_INVALID
;
677 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
679 usage
->threshold_ratio
.set
= false;
680 usage
->threshold_bytes
.set
= true;
681 usage
->threshold_bytes
.value
= threshold_bytes
;
686 enum lttng_condition_status
687 lttng_condition_buffer_usage_get_session_name(
688 const struct lttng_condition
*condition
,
689 const char **session_name
)
691 struct lttng_condition_buffer_usage
*usage
;
692 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
694 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !session_name
) {
695 status
= LTTNG_CONDITION_STATUS_INVALID
;
699 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
701 if (!usage
->session_name
) {
702 status
= LTTNG_CONDITION_STATUS_UNSET
;
705 *session_name
= usage
->session_name
;
710 enum lttng_condition_status
711 lttng_condition_buffer_usage_set_session_name(
712 struct lttng_condition
*condition
, const char *session_name
)
714 char *session_name_copy
;
715 struct lttng_condition_buffer_usage
*usage
;
716 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
718 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !session_name
||
719 strlen(session_name
) == 0) {
720 status
= LTTNG_CONDITION_STATUS_INVALID
;
724 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
726 session_name_copy
= strdup(session_name
);
727 if (!session_name_copy
) {
728 status
= LTTNG_CONDITION_STATUS_ERROR
;
732 if (usage
->session_name
) {
733 free(usage
->session_name
);
735 usage
->session_name
= session_name_copy
;
740 enum lttng_condition_status
741 lttng_condition_buffer_usage_get_channel_name(
742 const struct lttng_condition
*condition
,
743 const char **channel_name
)
745 struct lttng_condition_buffer_usage
*usage
;
746 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
748 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !channel_name
) {
749 status
= LTTNG_CONDITION_STATUS_INVALID
;
753 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
755 if (!usage
->channel_name
) {
756 status
= LTTNG_CONDITION_STATUS_UNSET
;
759 *channel_name
= usage
->channel_name
;
764 enum lttng_condition_status
765 lttng_condition_buffer_usage_set_channel_name(
766 struct lttng_condition
*condition
, const char *channel_name
)
768 char *channel_name_copy
;
769 struct lttng_condition_buffer_usage
*usage
;
770 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
772 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !channel_name
||
773 strlen(channel_name
) == 0) {
774 status
= LTTNG_CONDITION_STATUS_INVALID
;
778 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
780 channel_name_copy
= strdup(channel_name
);
781 if (!channel_name_copy
) {
782 status
= LTTNG_CONDITION_STATUS_ERROR
;
786 if (usage
->channel_name
) {
787 free(usage
->channel_name
);
789 usage
->channel_name
= channel_name_copy
;
794 enum lttng_condition_status
795 lttng_condition_buffer_usage_get_domain_type(
796 const struct lttng_condition
*condition
,
797 enum lttng_domain_type
*type
)
799 struct lttng_condition_buffer_usage
*usage
;
800 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
802 if (!condition
|| !IS_USAGE_CONDITION(condition
) || !type
) {
803 status
= LTTNG_CONDITION_STATUS_INVALID
;
807 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
809 if (!usage
->domain
.set
) {
810 status
= LTTNG_CONDITION_STATUS_UNSET
;
813 *type
= usage
->domain
.type
;
818 enum lttng_condition_status
819 lttng_condition_buffer_usage_set_domain_type(
820 struct lttng_condition
*condition
, enum lttng_domain_type type
)
822 struct lttng_condition_buffer_usage
*usage
;
823 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
825 if (!condition
|| !IS_USAGE_CONDITION(condition
) ||
826 type
== LTTNG_DOMAIN_NONE
) {
827 status
= LTTNG_CONDITION_STATUS_INVALID
;
831 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
833 usage
->domain
.set
= true;
834 usage
->domain
.type
= type
;
840 int lttng_evaluation_buffer_usage_serialize(
841 const struct lttng_evaluation
*evaluation
,
842 struct lttng_payload
*payload
)
844 struct lttng_evaluation_buffer_usage
*usage
;
845 struct lttng_evaluation_buffer_usage_comm comm
;
847 usage
= container_of(evaluation
, struct lttng_evaluation_buffer_usage
,
849 comm
.buffer_use
= usage
->buffer_use
;
850 comm
.buffer_capacity
= usage
->buffer_capacity
;
852 return lttng_dynamic_buffer_append(
853 &payload
->buffer
, &comm
, sizeof(comm
));
857 void lttng_evaluation_buffer_usage_destroy(
858 struct lttng_evaluation
*evaluation
)
860 struct lttng_evaluation_buffer_usage
*usage
;
862 usage
= container_of(evaluation
, struct lttng_evaluation_buffer_usage
,
868 struct lttng_evaluation
*lttng_evaluation_buffer_usage_create(
869 enum lttng_condition_type type
, uint64_t use
, uint64_t capacity
)
871 struct lttng_evaluation_buffer_usage
*usage
;
873 usage
= zmalloc(sizeof(struct lttng_evaluation_buffer_usage
));
878 usage
->parent
.type
= type
;
879 usage
->buffer_use
= use
;
880 usage
->buffer_capacity
= capacity
;
881 usage
->parent
.serialize
= lttng_evaluation_buffer_usage_serialize
;
882 usage
->parent
.destroy
= lttng_evaluation_buffer_usage_destroy
;
884 return &usage
->parent
;
888 * Get the sampled buffer usage which caused the associated condition to
889 * evaluate to "true".
891 enum lttng_evaluation_status
892 lttng_evaluation_buffer_usage_get_usage_ratio(
893 const struct lttng_evaluation
*evaluation
, double *usage_ratio
)
895 struct lttng_evaluation_buffer_usage
*usage
;
896 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
898 if (!evaluation
|| !is_usage_evaluation(evaluation
) || !usage_ratio
) {
899 status
= LTTNG_EVALUATION_STATUS_INVALID
;
903 usage
= container_of(evaluation
, struct lttng_evaluation_buffer_usage
,
905 *usage_ratio
= (double) usage
->buffer_use
/
906 (double) usage
->buffer_capacity
;
911 enum lttng_evaluation_status
912 lttng_evaluation_buffer_usage_get_usage(
913 const struct lttng_evaluation
*evaluation
,
914 uint64_t *usage_bytes
)
916 struct lttng_evaluation_buffer_usage
*usage
;
917 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
919 if (!evaluation
|| !is_usage_evaluation(evaluation
) || !usage_bytes
) {
920 status
= LTTNG_EVALUATION_STATUS_INVALID
;
924 usage
= container_of(evaluation
, struct lttng_evaluation_buffer_usage
,
926 *usage_bytes
= usage
->buffer_use
;