1 /* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
3 * lttng-counter-client-percpu-32-modular.c
5 * LTTng lib counter client. Per-cpu 32-bit counters in modular
8 * Copyright (C) 2020 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
11 #include "common/counter-clients/clients.h"
12 #include "common/counter/counter-api.h"
13 #include "common/counter/counter.h"
14 #include "common/events.h"
15 #include "common/tracer.h"
17 static const struct lib_counter_config client_config
= {
18 .alloc
= COUNTER_ALLOC_PER_CPU
,
19 .sync
= COUNTER_SYNC_PER_CPU
,
20 .arithmetic
= COUNTER_ARITHMETIC_MODULAR
,
21 .counter_size
= COUNTER_SIZE_32_BIT
,
24 static struct lttng_ust_channel_counter
*counter_create(size_t nr_dimensions
,
25 const struct lttng_counter_dimension
*dimensions
,
26 int64_t global_sum_step
,
27 int global_counter_fd
,
28 int nr_counter_cpu_fds
,
29 const int *counter_cpu_fds
,
32 size_t max_nr_elem
[LTTNG_COUNTER_DIMENSION_MAX
], i
;
33 struct lttng_ust_channel_counter
*lttng_chan_counter
;
34 struct lib_counter
*counter
;
36 if (nr_dimensions
> LTTNG_COUNTER_DIMENSION_MAX
)
38 for (i
= 0; i
< nr_dimensions
; i
++) {
39 if (dimensions
[i
].has_underflow
|| dimensions
[i
].has_overflow
)
41 max_nr_elem
[i
] = dimensions
[i
].size
;
43 lttng_chan_counter
= lttng_ust_alloc_channel_counter();
44 if (!lttng_chan_counter
)
46 counter
= lttng_counter_create(&client_config
, nr_dimensions
, max_nr_elem
,
47 global_sum_step
, global_counter_fd
, nr_counter_cpu_fds
,
48 counter_cpu_fds
, is_daemon
);
51 lttng_chan_counter
->priv
->counter
= counter
;
52 for (i
= 0; i
< nr_dimensions
; i
++)
53 lttng_chan_counter
->priv
->dimension_key_types
[i
] = dimensions
[i
].key_type
;
54 return lttng_chan_counter
;
57 lttng_ust_free_channel_common(lttng_chan_counter
->parent
);
61 static void counter_destroy(struct lttng_ust_channel_counter
*counter
)
63 lttng_counter_destroy(counter
->priv
->counter
);
64 lttng_ust_free_channel_common(counter
->parent
);
67 static int counter_add(struct lttng_ust_channel_counter
*counter
,
68 const size_t *dimension_indexes
, int64_t v
)
70 return lttng_counter_add(&client_config
, counter
->priv
->counter
, dimension_indexes
, v
);
73 static int counter_hit(struct lttng_ust_event_counter
*event_counter
,
74 const char *stack_data
__attribute__((unused
)),
75 struct lttng_ust_probe_ctx
*probe_ctx
__attribute__((unused
)),
76 struct lttng_ust_event_counter_ctx
*event_counter_ctx
__attribute__((unused
)))
78 struct lttng_ust_channel_counter
*counter
= event_counter
->chan
;
80 switch (event_counter
->priv
->action
) {
81 case LTTNG_EVENT_COUNTER_ACTION_INCREMENT
:
83 size_t index
= event_counter
->priv
->parent
.id
;
84 return counter_add(counter
, &index
, 1);
91 static int counter_read(struct lttng_ust_channel_counter
*counter
, const size_t *dimension_indexes
, int cpu
,
92 int64_t *value
, bool *overflow
, bool *underflow
)
94 return lttng_counter_read(&client_config
, counter
->priv
->counter
, dimension_indexes
, cpu
, value
,
98 static int counter_aggregate(struct lttng_ust_channel_counter
*counter
, const size_t *dimension_indexes
,
99 int64_t *value
, bool *overflow
, bool *underflow
)
101 return lttng_counter_aggregate(&client_config
, counter
->priv
->counter
, dimension_indexes
, value
,
102 overflow
, underflow
);
105 static int counter_clear(struct lttng_ust_channel_counter
*counter
, const size_t *dimension_indexes
)
107 return lttng_counter_clear(&client_config
, counter
->priv
->counter
, dimension_indexes
);
110 static struct lttng_counter_transport lttng_counter_transport
= {
111 .name
= "counter-per-cpu-32-modular",
113 .struct_size
= sizeof(struct lttng_ust_channel_counter_ops
),
114 .priv
= LTTNG_UST_COMPOUND_LITERAL(struct lttng_ust_channel_counter_ops_private
, {
115 .pub
= <tng_counter_transport
.ops
,
116 .counter_create
= counter_create
,
117 .counter_destroy
= counter_destroy
,
118 .counter_add
= counter_add
,
119 .counter_read
= counter_read
,
120 .counter_aggregate
= counter_aggregate
,
121 .counter_clear
= counter_clear
,
123 .counter_hit
= counter_hit
,
125 .client_config
= &client_config
,
128 void lttng_counter_client_percpu_32_modular_init(void)
130 lttng_counter_transport_register(<tng_counter_transport
);
133 void lttng_counter_client_percpu_32_modular_exit(void)
135 lttng_counter_transport_unregister(<tng_counter_transport
);