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