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