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