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