2 * Copyright (C) 2017 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License, version 2.1 only,
6 * as published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 #include <lttng/condition/condition-internal.h>
19 #include <lttng/condition/buffer-usage-internal.h>
20 #include <common/macros.h>
24 bool is_usage_condition(struct lttng_condition
*condition
)
26 enum lttng_condition_type type
= lttng_condition_get_type(condition
);
28 return type
== LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
||
29 type
== LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
;
33 bool is_usage_evaluation(struct lttng_evaluation
*evaluation
)
35 enum lttng_condition_type type
= lttng_evaluation_get_type(evaluation
);
37 return type
== LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
||
38 type
== LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
;
42 void lttng_condition_buffer_usage_destroy(struct lttng_condition
*condition
)
44 struct lttng_condition_buffer_usage
*usage
;
46 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
49 free(usage
->session_name
);
50 free(usage
->channel_name
);
55 bool lttng_condition_buffer_usage_validate(struct lttng_condition
*condition
)
58 struct lttng_condition_buffer_usage
*usage
;
64 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
66 if (!usage
->session_name
) {
69 if (!usage
->channel_name
) {
72 if (!usage
->threshold_percent
.set
&& !usage
->threshold_bytes
.set
) {
82 ssize_t
lttng_condition_buffer_usage_serialize(struct lttng_condition
*condition
,
85 struct lttng_condition_buffer_usage
*usage
;
87 size_t session_name_len
, channel_name_len
;
89 if (!condition
|| !is_usage_condition(condition
)) {
94 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
96 size
= sizeof(struct lttng_condition_buffer_usage_comm
);
97 session_name_len
= strlen(usage
->session_name
) + 1;
98 channel_name_len
= strlen(usage
->channel_name
) + 1;
99 size
+= session_name_len
+ channel_name_len
;
101 struct lttng_condition_buffer_usage_comm usage_comm
= {
102 .threshold_set_in_bytes
= usage
->threshold_bytes
.set
? 1 : 0,
103 .session_name_len
= session_name_len
,
104 .channel_name_len
= channel_name_len
,
105 .domain_type
= (int8_t) usage
->domain
.type
,
108 if (usage
->threshold_bytes
.set
) {
109 usage_comm
.threshold
.bytes
=
110 usage
->threshold_bytes
.value
;
112 usage_comm
.threshold
.percent
=
113 usage
->threshold_percent
.value
;
116 memcpy(buf
, &usage_comm
, sizeof(usage_comm
));
117 buf
+= sizeof(usage_comm
);
118 memcpy(buf
, usage
->session_name
, session_name_len
);
119 buf
+= session_name_len
;
120 memcpy(buf
, usage
->channel_name
, channel_name_len
);
121 buf
+= channel_name_len
;
128 struct lttng_condition
*lttng_condition_buffer_usage_create(
129 enum lttng_condition_type type
)
131 struct lttng_condition_buffer_usage
*condition
;
133 condition
= zmalloc(sizeof(struct lttng_condition_buffer_usage
));
138 condition
->parent
.type
= type
;
139 condition
->parent
.validate
= lttng_condition_buffer_usage_validate
;
140 condition
->parent
.serialize
= lttng_condition_buffer_usage_serialize
;
141 condition
->parent
.destroy
= lttng_condition_buffer_usage_destroy
;
143 return &condition
->parent
;
146 struct lttng_condition
*lttng_condition_buffer_usage_low_create(void)
148 return lttng_condition_buffer_usage_create(
149 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
);
152 struct lttng_condition
*lttng_condition_buffer_usage_high_create(void)
154 return lttng_condition_buffer_usage_create(
155 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
);
158 enum lttng_condition_status
159 lttng_condition_buffer_usage_get_threshold_percentage(
160 struct lttng_condition
*condition
, double *threshold_percent
)
162 struct lttng_condition_buffer_usage
*usage
;
163 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
165 if (!condition
|| !is_usage_condition(condition
) ||
166 !threshold_percent
) {
167 status
= LTTNG_CONDITION_STATUS_INVALID
;
171 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
173 if (!usage
->threshold_percent
.set
) {
174 status
= LTTNG_CONDITION_STATUS_UNSET
;
177 *threshold_percent
= usage
->threshold_percent
.value
;
182 /* threshold_percent expressed as [0.0, 1.0]. */
183 enum lttng_condition_status
184 lttng_condition_buffer_usage_set_threshold_percentage(
185 struct lttng_condition
*condition
, double threshold_percent
)
187 struct lttng_condition_buffer_usage
*usage
;
188 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
190 if (!condition
|| !is_usage_condition(condition
) ||
191 threshold_percent
< 0.0 || threshold_percent
> 1.0) {
192 status
= LTTNG_CONDITION_STATUS_INVALID
;
196 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
198 usage
->threshold_percent
.set
= true;
199 usage
->threshold_bytes
.set
= false;
200 usage
->threshold_percent
.value
= threshold_percent
;
205 enum lttng_condition_status
206 lttng_condition_buffer_usage_get_threshold(
207 struct lttng_condition
*condition
, uint64_t *threshold_bytes
)
209 struct lttng_condition_buffer_usage
*usage
;
210 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
212 if (!condition
|| !is_usage_condition(condition
) || !threshold_bytes
) {
213 status
= LTTNG_CONDITION_STATUS_INVALID
;
217 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
219 if (!usage
->threshold_bytes
.set
) {
220 status
= LTTNG_CONDITION_STATUS_UNSET
;
223 *threshold_bytes
= usage
->threshold_bytes
.value
;
228 enum lttng_condition_status
229 lttng_condition_buffer_usage_set_threshold(
230 struct lttng_condition
*condition
, uint64_t threshold_bytes
)
232 struct lttng_condition_buffer_usage
*usage
;
233 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
235 if (!condition
|| !is_usage_condition(condition
)) {
236 status
= LTTNG_CONDITION_STATUS_INVALID
;
240 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
242 usage
->threshold_percent
.set
= false;
243 usage
->threshold_bytes
.set
= true;
244 usage
->threshold_bytes
.value
= threshold_bytes
;
249 enum lttng_condition_status
250 lttng_condition_buffer_usage_get_session_name(
251 struct lttng_condition
*condition
, const char **session_name
)
253 struct lttng_condition_buffer_usage
*usage
;
254 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
256 if (!condition
|| !is_usage_condition(condition
) || !session_name
) {
257 status
= LTTNG_CONDITION_STATUS_INVALID
;
261 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
263 if (!usage
->session_name
) {
264 status
= LTTNG_CONDITION_STATUS_UNSET
;
267 *session_name
= usage
->session_name
;
272 extern enum lttng_condition_status
273 lttng_condition_buffer_usage_set_session_name(
274 struct lttng_condition
*condition
, const char *session_name
)
276 struct lttng_condition_buffer_usage
*usage
;
277 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
279 if (!condition
|| !is_usage_condition(condition
) || !session_name
||
280 strlen(session_name
) == 0) {
281 status
= LTTNG_CONDITION_STATUS_INVALID
;
285 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
287 usage
->session_name
= strdup(session_name
);
288 if (!usage
->session_name
) {
289 status
= LTTNG_CONDITION_STATUS_ERROR
;
296 enum lttng_condition_status
297 lttng_condition_buffer_usage_get_channel_name(
298 struct lttng_condition
*condition
, const char **channel_name
)
300 struct lttng_condition_buffer_usage
*usage
;
301 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
303 if (!condition
|| !is_usage_condition(condition
) || !channel_name
) {
304 status
= LTTNG_CONDITION_STATUS_INVALID
;
308 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
310 if (!usage
->channel_name
) {
311 status
= LTTNG_CONDITION_STATUS_UNSET
;
314 *channel_name
= usage
->channel_name
;
319 extern enum lttng_condition_status
320 lttng_condition_buffer_usage_set_channel_name(
321 struct lttng_condition
*condition
, const char *channel_name
)
323 struct lttng_condition_buffer_usage
*usage
;
324 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
326 if (!condition
|| !is_usage_condition(condition
) || !channel_name
||
327 strlen(channel_name
) == 0) {
328 status
= LTTNG_CONDITION_STATUS_INVALID
;
332 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
334 usage
->channel_name
= strdup(channel_name
);
335 if (!usage
->channel_name
) {
336 status
= LTTNG_CONDITION_STATUS_ERROR
;
343 extern enum lttng_condition_status
344 lttng_condition_buffer_usage_get_domain_type(
345 struct lttng_condition
*condition
, enum lttng_domain_type
*type
)
347 struct lttng_condition_buffer_usage
*usage
;
348 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
350 if (!condition
|| !is_usage_condition(condition
) || !type
) {
351 status
= LTTNG_CONDITION_STATUS_INVALID
;
355 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
357 if (!usage
->domain
.set
) {
358 status
= LTTNG_CONDITION_STATUS_UNSET
;
361 *type
= usage
->domain
.type
;
366 extern enum lttng_condition_status
367 lttng_condition_buffer_usage_set_domain_type(
368 struct lttng_condition
*condition
, enum lttng_domain_type type
)
370 struct lttng_condition_buffer_usage
*usage
;
371 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
373 if (!condition
|| !is_usage_condition(condition
) ||
374 type
== LTTNG_DOMAIN_NONE
) {
375 status
= LTTNG_CONDITION_STATUS_INVALID
;
379 usage
= container_of(condition
, struct lttng_condition_buffer_usage
,
381 usage
->domain
.set
= true;
382 usage
->domain
.type
= type
;
388 void lttng_evaluation_buffer_usage_destroy(
389 struct lttng_evaluation
*evaluation
)
391 struct lttng_evaluation_buffer_usage
*usage
;
393 usage
= container_of(evaluation
, struct lttng_evaluation_buffer_usage
,
399 struct lttng_evaluation
*lttng_evaluation_buffer_usage_create(uint64_t use
,
402 struct lttng_evaluation_buffer_usage
*usage
;
404 usage
= zmalloc(sizeof(struct lttng_evaluation_buffer_usage
));
409 usage
->buffer_use
= use
;
410 usage
->buffer_capacity
= capacity
;
411 usage
->parent
.destroy
= lttng_evaluation_buffer_usage_destroy
;
413 return &usage
->parent
;
417 * Get the sampled buffer usage which caused the associated condition to
418 * evaluate to "true".
420 enum lttng_evaluation_status
421 lttng_evaluation_buffer_usage_get_usage_percentage(
422 struct lttng_evaluation
*evaluation
, double *usage_percent
)
424 struct lttng_evaluation_buffer_usage
*usage
;
425 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
427 if (!evaluation
|| !is_usage_evaluation(evaluation
) || !usage_percent
) {
428 status
= LTTNG_EVALUATION_STATUS_INVALID
;
432 usage
= container_of(evaluation
, struct lttng_evaluation_buffer_usage
,
434 *usage_percent
= (double) usage
->buffer_use
/
435 (double) usage
->buffer_capacity
;
440 enum lttng_evaluation_status
441 lttng_evaluation_buffer_usage_get_usage(struct lttng_evaluation
*evaluation
,
442 uint64_t *usage_bytes
)
444 struct lttng_evaluation_buffer_usage
*usage
;
445 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
447 if (!evaluation
|| !is_usage_evaluation(evaluation
) || !usage_bytes
) {
448 status
= LTTNG_EVALUATION_STATUS_INVALID
;
452 usage
= container_of(evaluation
, struct lttng_evaluation_buffer_usage
,
454 *usage_bytes
= usage
->buffer_use
;