Fix: statements with side-effects in assert statements
[lttng-tools.git] / src / common / actions / rate-policy.c
CommitLineData
7f4d5b07
JR
1/*
2 * Copyright (C) 2021 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8#include <assert.h>
9#include <common/buffer-view.h>
10#include <common/dynamic-buffer.h>
11#include <common/error.h>
12#include <common/macros.h>
6a751b95 13#include <common/mi-lttng.h>
7f4d5b07
JR
14#include <common/payload-view.h>
15#include <common/payload.h>
16#include <limits.h>
17#include <lttng/action/rate-policy-internal.h>
18#include <lttng/action/rate-policy.h>
19#include <stdbool.h>
20#include <sys/types.h>
21
22#define IS_EVERY_N_RATE_POLICY(policy) \
23 (lttng_rate_policy_get_type(policy) == LTTNG_RATE_POLICY_TYPE_EVERY_N)
24
25#define IS_ONCE_AFTER_N_RATE_POLICY(policy) \
26 (lttng_rate_policy_get_type(policy) == \
27 LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N)
28
29typedef void (*rate_policy_destroy_cb)(struct lttng_rate_policy *rate_policy);
30typedef int (*rate_policy_serialize_cb)(struct lttng_rate_policy *rate_policy,
31 struct lttng_payload *payload);
32typedef bool (*rate_policy_equal_cb)(const struct lttng_rate_policy *a,
33 const struct lttng_rate_policy *b);
34typedef ssize_t (*rate_policy_create_from_payload_cb)(
35 struct lttng_payload_view *view,
36 struct lttng_rate_policy **rate_policy);
37typedef struct lttng_rate_policy *(*rate_policy_copy_cb)(
38 const struct lttng_rate_policy *source);
6a751b95
JR
39typedef enum lttng_error_code (*rate_policy_mi_serialize_cb)(
40 const struct lttng_rate_policy *rate_policy,
41 struct mi_writer *writer);
7f4d5b07
JR
42
43struct lttng_rate_policy {
44 enum lttng_rate_policy_type type;
45 rate_policy_serialize_cb serialize;
46 rate_policy_equal_cb equal;
47 rate_policy_destroy_cb destroy;
48 rate_policy_copy_cb copy;
6a751b95 49 rate_policy_mi_serialize_cb mi_serialize;
7f4d5b07
JR
50};
51
52struct lttng_rate_policy_every_n {
53 struct lttng_rate_policy parent;
54 uint64_t interval;
55};
56
57struct lttng_rate_policy_once_after_n {
58 struct lttng_rate_policy parent;
59 uint64_t threshold;
60};
61
62struct lttng_rate_policy_comm {
63 /* enum lttng_rate_policy_type */
64 int8_t rate_policy_type;
65} LTTNG_PACKED;
66
67struct lttng_rate_policy_once_after_n_comm {
68 uint64_t threshold;
69} LTTNG_PACKED;
70
71struct lttng_rate_policy_every_n_comm {
72 uint64_t interval;
73} LTTNG_PACKED;
74
75/* Forward declaration. */
76static void lttng_rate_policy_init(struct lttng_rate_policy *rate_policy,
77 enum lttng_rate_policy_type type,
78 rate_policy_serialize_cb serialize,
79 rate_policy_equal_cb equal,
80 rate_policy_destroy_cb destroy,
6a751b95
JR
81 rate_policy_copy_cb copy,
82 rate_policy_mi_serialize_cb mi);
7f4d5b07
JR
83
84/* Forward declaration. Every n */
85static bool lttng_rate_policy_every_n_should_execute(
86 const struct lttng_rate_policy *policy, uint64_t counter);
87
88/* Forward declaration. Once after N */
89static bool lttng_rate_policy_once_after_n_should_execute(
90 const struct lttng_rate_policy *policy, uint64_t counter);
91
92LTTNG_HIDDEN
93const char *lttng_rate_policy_type_string(
94 enum lttng_rate_policy_type rate_policy_type)
95{
96 switch (rate_policy_type) {
97 case LTTNG_RATE_POLICY_TYPE_EVERY_N:
98 return "EVERY-N";
99 case LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N:
100 return "ONCE-AFTER-N";
101 default:
102 return "???";
103 }
104}
105
106enum lttng_rate_policy_type lttng_rate_policy_get_type(
107 const struct lttng_rate_policy *policy)
108{
109 return policy ? policy->type : LTTNG_RATE_POLICY_TYPE_UNKNOWN;
110}
111
112LTTNG_HIDDEN
113void lttng_rate_policy_init(struct lttng_rate_policy *rate_policy,
114 enum lttng_rate_policy_type type,
115 rate_policy_serialize_cb serialize,
116 rate_policy_equal_cb equal,
117 rate_policy_destroy_cb destroy,
6a751b95
JR
118 rate_policy_copy_cb copy,
119 rate_policy_mi_serialize_cb mi)
7f4d5b07
JR
120{
121 rate_policy->type = type;
122 rate_policy->serialize = serialize;
123 rate_policy->equal = equal;
124 rate_policy->destroy = destroy;
125 rate_policy->copy = copy;
6a751b95 126 rate_policy->mi_serialize = mi;
7f4d5b07
JR
127}
128
129void lttng_rate_policy_destroy(struct lttng_rate_policy *rate_policy)
130{
131 if (!rate_policy) {
132 return;
133 }
134
135 rate_policy->destroy(rate_policy);
136}
137
138LTTNG_HIDDEN
139int lttng_rate_policy_serialize(struct lttng_rate_policy *rate_policy,
140 struct lttng_payload *payload)
141{
142 int ret;
143 struct lttng_rate_policy_comm rate_policy_comm = {
144 .rate_policy_type = (int8_t) rate_policy->type,
145 };
146
147 ret = lttng_dynamic_buffer_append(&payload->buffer, &rate_policy_comm,
148 sizeof(rate_policy_comm));
149 if (ret) {
150 goto end;
151 }
152
153 ret = rate_policy->serialize(rate_policy, payload);
154 if (ret) {
155 goto end;
156 }
157end:
158 return ret;
159}
160
161static ssize_t lttng_rate_policy_once_after_n_create_from_payload(
162 struct lttng_payload_view *view,
163 struct lttng_rate_policy **rate_policy)
164{
165 ssize_t consumed_len = -1;
166 struct lttng_rate_policy *policy = NULL;
167 const struct lttng_rate_policy_once_after_n_comm *comm;
168 const struct lttng_payload_view comm_view =
169 lttng_payload_view_from_view(view, 0, sizeof(*comm));
170
171 if (!view || !rate_policy) {
172 consumed_len = -1;
173 goto end;
174 }
175
176 if (!lttng_payload_view_is_valid(&comm_view)) {
177 /* Payload not large enough to contain the header. */
178 consumed_len = -1;
179 goto end;
180 }
181
182 comm = (const struct lttng_rate_policy_once_after_n_comm *)
183 comm_view.buffer.data;
184
185 policy = lttng_rate_policy_once_after_n_create(comm->threshold);
186 if (policy == NULL) {
187 consumed_len = -1;
188 goto end;
189 }
190
191 *rate_policy = policy;
192 consumed_len = sizeof(*comm);
193
194end:
195 return consumed_len;
196}
197
198static ssize_t lttng_rate_policy_every_n_create_from_payload(
199 struct lttng_payload_view *view,
200 struct lttng_rate_policy **rate_policy)
201{
202 ssize_t consumed_len = -1;
203 struct lttng_rate_policy *policy = NULL;
204 const struct lttng_rate_policy_every_n_comm *comm;
205 const struct lttng_payload_view comm_view =
206 lttng_payload_view_from_view(view, 0, sizeof(*comm));
207
208 if (!view || !rate_policy) {
209 consumed_len = -1;
210 goto end;
211 }
212
213 if (!lttng_payload_view_is_valid(&comm_view)) {
214 /* Payload not large enough to contain the header. */
215 consumed_len = -1;
216 goto end;
217 }
218
219 comm = (const struct lttng_rate_policy_every_n_comm *)
220 comm_view.buffer.data;
221
222 policy = lttng_rate_policy_every_n_create(comm->interval);
223 if (policy == NULL) {
224 consumed_len = -1;
225 goto end;
226 }
227
228 *rate_policy = policy;
229 consumed_len = sizeof(*comm);
230
231end:
232 return consumed_len;
233}
234
235LTTNG_HIDDEN
236ssize_t lttng_rate_policy_create_from_payload(struct lttng_payload_view *view,
237 struct lttng_rate_policy **rate_policy)
238{
239 ssize_t consumed_len, specific_rate_policy_consumed_len;
240 rate_policy_create_from_payload_cb create_from_payload_cb;
241 const struct lttng_rate_policy_comm *rate_policy_comm;
242 const struct lttng_payload_view rate_policy_comm_view =
243 lttng_payload_view_from_view(
244 view, 0, sizeof(*rate_policy_comm));
245
246 if (!view || !rate_policy) {
247 consumed_len = -1;
248 goto end;
249 }
250
251 if (!lttng_payload_view_is_valid(&rate_policy_comm_view)) {
252 /* Payload not large enough to contain the header. */
253 consumed_len = -1;
254 goto end;
255 }
256
257 rate_policy_comm = (const struct lttng_rate_policy_comm *)
258 rate_policy_comm_view.buffer.data;
259
260 DBG("Create rate_policy from payload: rate-policy-type=%s",
261 lttng_rate_policy_type_string(
262 rate_policy_comm->rate_policy_type));
263
264 switch (rate_policy_comm->rate_policy_type) {
265 case LTTNG_RATE_POLICY_TYPE_EVERY_N:
266 create_from_payload_cb =
267 lttng_rate_policy_every_n_create_from_payload;
268 break;
269 case LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N:
270 create_from_payload_cb =
271 lttng_rate_policy_once_after_n_create_from_payload;
272 break;
273 default:
274 ERR("Failed to create rate-policy from payload, unhandled rate-policy type: rate-policy-type=%u (%s)",
275 rate_policy_comm->rate_policy_type,
276 lttng_rate_policy_type_string(
277 rate_policy_comm->rate_policy_type));
278 consumed_len = -1;
279 goto end;
280 }
281
282 {
283 /* Create buffer view for the rate_policy-type-specific data.
284 */
285 struct lttng_payload_view specific_rate_policy_view =
286 lttng_payload_view_from_view(view,
287 sizeof(struct lttng_rate_policy_comm),
288 -1);
289
290 specific_rate_policy_consumed_len = create_from_payload_cb(
291 &specific_rate_policy_view, rate_policy);
292 }
293 if (specific_rate_policy_consumed_len < 0) {
294 ERR("Failed to create specific rate_policy from buffer.");
295 consumed_len = -1;
296 goto end;
297 }
298
299 assert(*rate_policy);
300
301 consumed_len = sizeof(struct lttng_rate_policy_comm) +
302 specific_rate_policy_consumed_len;
303
304end:
305 return consumed_len;
306}
307
308LTTNG_HIDDEN
309bool lttng_rate_policy_is_equal(const struct lttng_rate_policy *a,
310 const struct lttng_rate_policy *b)
311{
312 bool is_equal = false;
313
314 if (!a || !b) {
315 goto end;
316 }
317
318 if (a->type != b->type) {
319 goto end;
320 }
321
322 if (a == b) {
323 is_equal = true;
324 goto end;
325 }
326
327 assert(a->equal);
328 is_equal = a->equal(a, b);
329end:
330 return is_equal;
331}
332
333LTTNG_HIDDEN
334bool lttng_rate_policy_should_execute(
335 const struct lttng_rate_policy *policy, uint64_t counter)
336{
337 switch (policy->type) {
338 case LTTNG_RATE_POLICY_TYPE_EVERY_N:
339 return lttng_rate_policy_every_n_should_execute(
340 policy, counter);
341 case LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N:
342 return lttng_rate_policy_once_after_n_should_execute(
343 policy, counter);
344 default:
345 abort();
346 break;
347 }
348}
349
350/* Every N */
351static struct lttng_rate_policy_every_n *rate_policy_every_n_from_rate_policy(
352 struct lttng_rate_policy *policy)
353{
354 assert(policy);
355
356 return container_of(policy, struct lttng_rate_policy_every_n, parent);
357}
358
359static const struct lttng_rate_policy_every_n *
360rate_policy_every_n_from_rate_policy_const(
361 const struct lttng_rate_policy *policy)
362{
363 assert(policy);
364
365 return container_of(policy, struct lttng_rate_policy_every_n, parent);
366}
367
368static int lttng_rate_policy_every_n_serialize(
369 struct lttng_rate_policy *policy, struct lttng_payload *payload)
370{
371 int ret;
372
373 struct lttng_rate_policy_every_n *every_n_policy;
374 struct lttng_rate_policy_every_n_comm comm = {};
375
376 assert(policy);
377 assert(payload);
378
379 every_n_policy = rate_policy_every_n_from_rate_policy(policy);
380 comm.interval = every_n_policy->interval;
381
382 ret = lttng_dynamic_buffer_append(
383 &payload->buffer, &comm, sizeof(comm));
384 return ret;
385}
386
387static bool lttng_rate_policy_every_n_is_equal(
388 const struct lttng_rate_policy *_a,
389 const struct lttng_rate_policy *_b)
390{
391 bool is_equal = false;
392 const struct lttng_rate_policy_every_n *a, *b;
393
394 a = rate_policy_every_n_from_rate_policy_const(_a);
395 b = rate_policy_every_n_from_rate_policy_const(_b);
396
397 if (a->interval != b->interval) {
398 goto end;
399 }
400
401 is_equal = true;
402
403end:
404 return is_equal;
405}
406
407static void lttng_rate_policy_every_n_destroy(struct lttng_rate_policy *policy)
408{
409 struct lttng_rate_policy_every_n *every_n_policy;
410
411 if (!policy) {
412 goto end;
413 }
414
415 every_n_policy = rate_policy_every_n_from_rate_policy(policy);
416
417 free(every_n_policy);
418
419end:
420 return;
421}
422
423static struct lttng_rate_policy *lttng_rate_policy_every_n_copy(
424 const struct lttng_rate_policy *source)
425{
426 struct lttng_rate_policy *copy = NULL;
427 const struct lttng_rate_policy_every_n *every_n_policy;
428
429 if (!source) {
430 goto end;
431 }
432
433 every_n_policy = rate_policy_every_n_from_rate_policy_const(source);
434 copy = lttng_rate_policy_every_n_create(every_n_policy->interval);
435
436end:
437 return copy;
438}
439
6a751b95
JR
440static enum lttng_error_code lttng_rate_policy_every_n_mi_serialize(
441 const struct lttng_rate_policy *rate_policy,
442 struct mi_writer *writer)
443{
444 int ret;
445 enum lttng_error_code ret_code;
446 const struct lttng_rate_policy_every_n *every_n_policy = NULL;
447
448 assert(rate_policy);
449 assert(IS_EVERY_N_RATE_POLICY(rate_policy));
450 assert(writer);
451
452 every_n_policy = rate_policy_every_n_from_rate_policy_const(
453 rate_policy);
454
455 /* Open rate_policy_every_n element. */
456 ret = mi_lttng_writer_open_element(
457 writer, mi_lttng_element_rate_policy_every_n);
458 if (ret) {
459 goto mi_error;
460 }
461
462 /* Interval. */
463 ret = mi_lttng_writer_write_element_unsigned_int(writer,
464 mi_lttng_element_rate_policy_every_n_interval,
465 every_n_policy->interval);
466 if (ret) {
467 goto mi_error;
468 }
469
470 /* Close rate_policy_every_n element. */
471 ret = mi_lttng_writer_close_element(writer);
472 if (ret) {
473 goto mi_error;
474 }
475
476 ret_code = LTTNG_OK;
477 goto end;
478
479mi_error:
480 ret_code = LTTNG_ERR_MI_IO_FAIL;
481end:
482 return ret_code;
483}
484
7f4d5b07
JR
485struct lttng_rate_policy *lttng_rate_policy_every_n_create(uint64_t interval)
486{
487 struct lttng_rate_policy_every_n *policy = NULL;
488 struct lttng_rate_policy *_policy = NULL;
489
490 if (interval == 0) {
491 /*
492 * An interval of 0 is invalid since it would never be fired.
493 */
494 goto end;
495 }
496
497 policy = zmalloc(sizeof(struct lttng_rate_policy_every_n));
498 if (!policy) {
499 goto end;
500 }
501
502 lttng_rate_policy_init(&policy->parent, LTTNG_RATE_POLICY_TYPE_EVERY_N,
503 lttng_rate_policy_every_n_serialize,
504 lttng_rate_policy_every_n_is_equal,
505 lttng_rate_policy_every_n_destroy,
6a751b95
JR
506 lttng_rate_policy_every_n_copy,
507 lttng_rate_policy_every_n_mi_serialize);
7f4d5b07
JR
508
509 policy->interval = interval;
510
511 _policy = &policy->parent;
512 policy = NULL;
513
514end:
515 free(policy);
516 return _policy;
517}
518
7f4d5b07
JR
519enum lttng_rate_policy_status lttng_rate_policy_every_n_get_interval(
520 const struct lttng_rate_policy *policy, uint64_t *interval)
521{
522 const struct lttng_rate_policy_every_n *every_n_policy;
523 enum lttng_rate_policy_status status;
524
525 if (!policy || !IS_EVERY_N_RATE_POLICY(policy) || !interval) {
526 status = LTTNG_RATE_POLICY_STATUS_INVALID;
527 goto end;
528 }
529
530 every_n_policy = rate_policy_every_n_from_rate_policy_const(policy);
531 *interval = every_n_policy->interval;
532 status = LTTNG_RATE_POLICY_STATUS_OK;
533end:
534
535 return status;
536}
537
538static bool lttng_rate_policy_every_n_should_execute(
539 const struct lttng_rate_policy *policy, uint64_t counter)
540{
541 const struct lttng_rate_policy_every_n *every_n_policy;
542 assert(policy);
543 bool execute = false;
544
545 every_n_policy = rate_policy_every_n_from_rate_policy_const(policy);
546
547 if (every_n_policy->interval == 0) {
548 abort();
549 }
550
551 execute = (counter % every_n_policy->interval) == 0;
552
553 DBG("Policy every N = %" PRIu64
554 ": execution %s. Execution count: %" PRIu64,
555 every_n_policy->interval,
556 execute ? "accepted" : "denied", counter);
557
558 return execute;
559}
560
561/* Once after N */
562
563static struct lttng_rate_policy_once_after_n *
564rate_policy_once_after_n_from_rate_policy(struct lttng_rate_policy *policy)
565{
566 assert(policy);
567
568 return container_of(
569 policy, struct lttng_rate_policy_once_after_n, parent);
570}
571
572static const struct lttng_rate_policy_once_after_n *
573rate_policy_once_after_n_from_rate_policy_const(
574 const struct lttng_rate_policy *policy)
575{
576 assert(policy);
577
578 return container_of(
579 policy, struct lttng_rate_policy_once_after_n, parent);
580}
581static int lttng_rate_policy_once_after_n_serialize(
582 struct lttng_rate_policy *policy, struct lttng_payload *payload)
583{
584 int ret;
585
586 struct lttng_rate_policy_once_after_n *once_after_n_policy;
587 struct lttng_rate_policy_once_after_n_comm comm = {};
588
589 assert(policy);
590 assert(payload);
591
592 once_after_n_policy = rate_policy_once_after_n_from_rate_policy(policy);
593 comm.threshold = once_after_n_policy->threshold;
594
595 ret = lttng_dynamic_buffer_append(
596 &payload->buffer, &comm, sizeof(comm));
597 return ret;
598}
599
600static bool lttng_rate_policy_once_after_n_is_equal(
601 const struct lttng_rate_policy *_a,
602 const struct lttng_rate_policy *_b)
603{
604 bool is_equal = false;
605 const struct lttng_rate_policy_once_after_n *a, *b;
606
607 a = rate_policy_once_after_n_from_rate_policy_const(_a);
608 b = rate_policy_once_after_n_from_rate_policy_const(_b);
609
610 if (a->threshold != b->threshold) {
611 goto end;
612 }
613
614 is_equal = true;
615
616end:
617 return is_equal;
618}
619
620static void lttng_rate_policy_once_after_n_destroy(
621 struct lttng_rate_policy *policy)
622{
623 struct lttng_rate_policy_once_after_n *once_after_n_policy;
624
625 if (!policy) {
626 goto end;
627 }
628
629 once_after_n_policy = rate_policy_once_after_n_from_rate_policy(policy);
630
631 free(once_after_n_policy);
632
633end:
634 return;
635}
636
637static struct lttng_rate_policy *lttng_rate_policy_once_after_n_copy(
638 const struct lttng_rate_policy *source)
639{
640 struct lttng_rate_policy *copy = NULL;
641 const struct lttng_rate_policy_once_after_n *once_after_n_policy;
642
643 if (!source) {
644 goto end;
645 }
646
647 once_after_n_policy =
648 rate_policy_once_after_n_from_rate_policy_const(source);
649 copy = lttng_rate_policy_once_after_n_create(
650 once_after_n_policy->threshold);
651
652end:
653 return copy;
654}
655
6a751b95
JR
656static enum lttng_error_code lttng_rate_policy_once_after_n_mi_serialize(
657 const struct lttng_rate_policy *rate_policy,
658 struct mi_writer *writer)
659{
660 int ret;
661 enum lttng_error_code ret_code;
662 const struct lttng_rate_policy_once_after_n *once_after_n_policy = NULL;
663
664 assert(rate_policy);
665 assert(IS_ONCE_AFTER_N_RATE_POLICY(rate_policy));
666 assert(writer);
667
668 once_after_n_policy = rate_policy_once_after_n_from_rate_policy_const(
669 rate_policy);
670
671 /* Open rate_policy_once_after_n. */
672 ret = mi_lttng_writer_open_element(
673 writer, mi_lttng_element_rate_policy_once_after_n);
674 if (ret) {
675 goto mi_error;
676 }
677
678 /* Threshold. */
679 ret = mi_lttng_writer_write_element_unsigned_int(writer,
680 mi_lttng_element_rate_policy_once_after_n_threshold,
681 once_after_n_policy->threshold);
682 if (ret) {
683 goto mi_error;
684 }
685
686 /* Close rate_policy_once_after_n element. */
687 ret = mi_lttng_writer_close_element(writer);
688 if (ret) {
689 goto mi_error;
690 }
691
692 ret_code = LTTNG_OK;
693 goto end;
694
695mi_error:
696 ret_code = LTTNG_ERR_MI_IO_FAIL;
697end:
698 return ret_code;
699}
700
7f4d5b07
JR
701struct lttng_rate_policy *lttng_rate_policy_once_after_n_create(
702 uint64_t threshold)
703{
704 struct lttng_rate_policy_once_after_n *policy = NULL;
705 struct lttng_rate_policy *_policy = NULL;
706
707 if (threshold == 0) {
708 /* threshold is expected to be > 0 */
709 goto end;
710 }
711
712 policy = zmalloc(sizeof(struct lttng_rate_policy_once_after_n));
713 if (!policy) {
714 goto end;
715 }
716
717 lttng_rate_policy_init(&policy->parent,
718 LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N,
719 lttng_rate_policy_once_after_n_serialize,
720 lttng_rate_policy_once_after_n_is_equal,
721 lttng_rate_policy_once_after_n_destroy,
6a751b95
JR
722 lttng_rate_policy_once_after_n_copy,
723 lttng_rate_policy_once_after_n_mi_serialize);
7f4d5b07
JR
724
725 policy->threshold = threshold;
726
727 _policy = &policy->parent;
728 policy = NULL;
729
730end:
731 free(policy);
732 return _policy;
733}
734
7f4d5b07
JR
735enum lttng_rate_policy_status lttng_rate_policy_once_after_n_get_threshold(
736 const struct lttng_rate_policy *policy, uint64_t *threshold)
737{
738 const struct lttng_rate_policy_once_after_n *once_after_n_policy;
739 enum lttng_rate_policy_status status;
740
741 if (!policy || !IS_ONCE_AFTER_N_RATE_POLICY(policy) || !threshold) {
742 status = LTTNG_RATE_POLICY_STATUS_INVALID;
743 goto end;
744 }
745
746 once_after_n_policy =
747 rate_policy_once_after_n_from_rate_policy_const(policy);
748 *threshold = once_after_n_policy->threshold;
749 status = LTTNG_RATE_POLICY_STATUS_OK;
750end:
751
752 return status;
753}
754
755LTTNG_HIDDEN
756struct lttng_rate_policy *lttng_rate_policy_copy(
757 const struct lttng_rate_policy *source)
758{
759 assert(source->copy);
760 return source->copy(source);
761}
762
763static bool lttng_rate_policy_once_after_n_should_execute(
764 const struct lttng_rate_policy *policy, uint64_t counter)
765{
766 const struct lttng_rate_policy_once_after_n *once_after_n_policy;
767 bool execute = false;
768 assert(policy);
769
770 once_after_n_policy =
771 rate_policy_once_after_n_from_rate_policy_const(policy);
772
773 execute = counter == once_after_n_policy->threshold;
774
775 DBG("Policy once after N = %" PRIu64
776 ": execution %s. Execution count: %" PRIu64,
777 once_after_n_policy->threshold,
778 execute ? "accepted" : "denied", counter);
779
780 return counter == once_after_n_policy->threshold;
781}
6a751b95
JR
782
783LTTNG_HIDDEN
784enum lttng_error_code lttng_rate_policy_mi_serialize(
785 const struct lttng_rate_policy *rate_policy,
786 struct mi_writer *writer)
787{
788 int ret;
789 enum lttng_error_code ret_code;
790
791 assert(rate_policy);
792 assert(writer);
793 assert(rate_policy->mi_serialize);
794
795 /* Open rate policy element. */
796 ret = mi_lttng_writer_open_element(
797 writer, mi_lttng_element_rate_policy);
798 if (ret) {
799 goto mi_error;
800 }
801
802 /* Serialize underlying rate policy. */
803 ret_code = rate_policy->mi_serialize(rate_policy, writer);
804 if (ret_code != LTTNG_OK) {
805 goto end;
806 }
807
808 /* Close rate policy element. */
809 ret = mi_lttng_writer_close_element(writer);
810 if (ret) {
811 goto mi_error;
812 }
813
814 ret_code = LTTNG_OK;
815 goto end;
816
817mi_error:
818 ret_code = LTTNG_ERR_MI_IO_FAIL;
819end:
820 return ret_code;
821}
This page took 0.053476 seconds and 4 git commands to generate.