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