EM-ODP 4.4.0
Event Machine on ODP
Loading...
Searching...
No Matches
event_machine_pool.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018-2026, Nokia Solutions and Networks
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * * Neither the name of the copyright holder nor the names of its
15 * contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/**
32 * @file
33 *
34 * Event Machine event pool functions.
35 *
36 */
37
38#ifndef _GNU_SOURCE
39#define _GNU_SOURCE
40#endif
41
42#ifdef HAVE_CONFIG_H
43#include "config.h"
44#endif
45
46#include <stdbool.h>
47#include <stdint.h>
48#include <string.h>
49
50#include <odp_api.h>
51
52#include <event_machine.h>
53
54#include "em_error.h"
55#include "em_internal_event.h"
56#include "em_mem.h"
57#include "em_pool.h"
58#include "em_pool_inline.h"
59#include "em_pool_types.h"
60
61/* per core (thread) state for em_atomic_group_next() */
62static ENV_LOCAL unsigned int _pool_tbl_iter_idx;
63
64void em_pool_cfg_init(em_pool_cfg_t *const pool_cfg)
65{
66 odp_pool_param_t odp_pool_defaults;
67 uint32_t buf_cache_sz;
68 uint32_t pkt_cache_sz;
69 uint32_t vec_cache_sz;
70 uint32_t cache_sz;
71
72 if (unlikely(!pool_cfg)) {
74 EM_ESCOPE_POOL_CFG_INIT,
75 "pool_cfg pointer NULL!");
76 return;
77 }
78
79 odp_pool_param_init(&odp_pool_defaults);
80 memset(pool_cfg, 0, sizeof(*pool_cfg));
81
83
84 buf_cache_sz = odp_pool_defaults.buf.cache_size;
85 pkt_cache_sz = odp_pool_defaults.pkt.cache_size;
86 vec_cache_sz = MIN(odp_pool_defaults.vector.cache_size,
87 odp_pool_defaults.event_vector.cache_size);
88 cache_sz = MIN(buf_cache_sz, pkt_cache_sz);
89 cache_sz = MIN(cache_sz, vec_cache_sz);
90
91 for (int i = 0; i < EM_MAX_SUBPOOLS; i++)
92 pool_cfg->subpool[i].cache_size = cache_sz;
93
95}
96
97em_pool_t
98em_pool_create(const char *name, em_pool_t pool, const em_pool_cfg_t *pool_cfg)
99{
100 em_pool_t pool_created;
101 const char *err_str = "";
102
103 /* Verify config */
104 int err = invalid_pool_cfg(pool_cfg, &err_str);
105
106 if (unlikely(err)) {
107 INTERNAL_ERROR(EM_ERR_BAD_ARG, EM_ESCOPE_POOL_CREATE,
108 "Pool create: invalid pool-config(%d): %s",
109 err, err_str);
110 return EM_POOL_UNDEF;
111 }
112
113 err = check_pool_uarea_persistence(pool_cfg, &err_str);
114
115 if (unlikely(err)) {
116 INTERNAL_ERROR(EM_ERR_NOT_SUPPORTED, EM_ESCOPE_POOL_CREATE,
117 "Pool create: user area persistence unsupported(%d): %s",
118 err, err_str);
119 return EM_POOL_UNDEF;
120 }
121
122 pool_created = pool_create(name, pool, pool_cfg);
123
124 if (unlikely(pool_created == EM_POOL_UNDEF ||
125 (pool != EM_POOL_UNDEF && pool != pool_created))) {
126 INTERNAL_ERROR(EM_ERR_LIB_FAILED, EM_ESCOPE_POOL_CREATE,
127 "Pool create failed,\n"
128 "requested:%" PRI_POOL " created:%" PRI_POOL "",
129 pool, pool_created);
130 return EM_POOL_UNDEF;
131 }
132
133 return pool_created;
134}
135
137em_pool_delete(em_pool_t pool)
138{
139 em_status_t stat;
140
141 stat = pool_delete(pool);
142 RETURN_ERROR_IF(stat != EM_OK, stat, EM_ESCOPE_POOL_DELETE,
143 "Pool delete failed");
144
145 return EM_OK;
146}
147
148em_pool_t
149em_pool_find(const char *name)
150{
151 if (name && *name)
152 return pool_find(name);
153
154 return EM_POOL_UNDEF;
155}
156
157size_t em_pool_name(em_pool_t pool, char *name /*out*/, size_t maxlen)
158{
159 const mpool_elem_t *mpool_elem = pool_elem_get(pool);
160 size_t len = 0;
161
162 if (unlikely(name == NULL || maxlen == 0)) {
163 INTERNAL_ERROR(EM_ERR_BAD_ARG, EM_ESCOPE_POOL_NAME,
164 "Invalid args: name=0x%" PRIx64 ", maxlen=%zu",
165 name, maxlen);
166 return 0;
167 }
168
169 if (unlikely(mpool_elem == NULL || !pool_allocated(mpool_elem))) {
170 INTERNAL_ERROR(EM_ERR_BAD_ARG, EM_ESCOPE_POOL_NAME,
171 "Invalid Pool:%" PRI_POOL "", pool);
172 name[0] = '\0';
173 return 0;
174 }
175
176 len = strnlen(mpool_elem->name, sizeof(mpool_elem->name) - 1);
177 if (maxlen - 1 < len)
178 len = maxlen - 1;
179
180 memcpy(name, mpool_elem->name, len);
181 name[len] = '\0';
182
183 return len;
184}
185
186em_pool_t em_pool_first(unsigned int *num)
187{
188 const mpool_elem_t *const mpool_elem_tbl = em_shm->mpool_tbl.pool;
189 const mpool_elem_t *mpool_elem = &mpool_elem_tbl[0];
190 const unsigned int pool_cnt = pool_count();
191
192 _pool_tbl_iter_idx = 0; /* reset iteration */
193
194 if (num)
195 *num = pool_cnt;
196
197 if (pool_cnt == 0) {
198 _pool_tbl_iter_idx = EM_CONFIG_POOLS; /* UNDEF = _next() */
199 return EM_POOL_UNDEF;
200 }
201
202 /* find first */
203 while (!pool_allocated(mpool_elem)) {
204 _pool_tbl_iter_idx++;
205 if (_pool_tbl_iter_idx >= EM_CONFIG_POOLS)
206 return EM_POOL_UNDEF;
207 mpool_elem = &mpool_elem_tbl[_pool_tbl_iter_idx];
208 }
209
210 return pool_idx2hdl(_pool_tbl_iter_idx);
211}
212
213em_pool_t em_pool_next(void)
214{
215 if (_pool_tbl_iter_idx >= EM_CONFIG_POOLS - 1)
216 return EM_POOL_UNDEF;
217
218 _pool_tbl_iter_idx++;
219
220 const mpool_elem_t *const mpool_elem_tbl = em_shm->mpool_tbl.pool;
221 const mpool_elem_t *mpool_elem = &mpool_elem_tbl[_pool_tbl_iter_idx];
222
223 /* find next */
224 while (!pool_allocated(mpool_elem)) {
225 _pool_tbl_iter_idx++;
226 if (_pool_tbl_iter_idx >= EM_CONFIG_POOLS)
227 return EM_POOL_UNDEF;
228 mpool_elem = &mpool_elem_tbl[_pool_tbl_iter_idx];
229 }
230
231 return pool_idx2hdl(_pool_tbl_iter_idx);
232}
233
235em_pool_info(em_pool_t pool, em_pool_info_t *pool_info /*out*/)
236{
237 const mpool_elem_t *pool_elem = pool_elem_get(pool);
238
239 if (EM_CHECK_LEVEL > 0)
240 RETURN_ERROR_IF(!pool_elem || !pool_info,
241 EM_ERR_BAD_ARG, EM_ESCOPE_POOL_INFO,
242 "Inv. args: pool:%" PRI_POOL " pool_info:%p",
243 pool, pool_info);
244
245 if (EM_CHECK_LEVEL >= 2)
246 RETURN_ERROR_IF(!pool_allocated(pool_elem),
247 EM_ERR_NOT_CREATED, EM_ESCOPE_POOL_INFO,
248 "EM-pool:%" PRI_POOL " not created", pool);
249
250 memset(pool_info, 0, sizeof(*pool_info));
251 /* copy pool info into the user provided 'pool_info' */
252 strncpy(pool_info->name, pool_elem->name, sizeof(pool_info->name) - 1);
253 pool_info->name[sizeof(pool_info->name) - 1] = '\0';
254 pool_info->em_pool = pool_elem->em_pool;
255 pool_info->event_type = pool_elem->event_type;
256 pool_info->align_offset = pool_elem->align_offset;
257 pool_info->user_area_size = pool_elem->user_area.size;
258 pool_info->num_subpools = pool_elem->num_subpools;
259
260 for (int i = 0; i < pool_elem->num_subpools; i++) {
261 pool_info->subpool[i].size = pool_elem->size[i]; /*sorted sz*/
262 pool_info->subpool[i].num = pool_elem->pool_cfg.subpool[i].num;
263 pool_info->subpool[i].cache_size = pool_elem->pool_cfg.subpool[i].cache_size;
264 }
265
266 pool_stats_opt_odp2em(&pool_info->stats_opt, &pool_elem->stats_opt);
267
268 /*
269 * EM pool usage statistics only collected if the pool was created with
270 * 'available' enabled either through EM config file: 'pool.statistics' or
271 * in 'em_pool_cfg_t::stats_opt' given to function em_pool_create(..., pool_cfg).
272 *
273 * Following code still tries to fetch 'cache_available' which would be 0
274 * if it was not enabled or enabled but ineffective without ODP support. In
275 * this case, 'pool_info->subpool[i].free' and 'pool_info->subpool[i].used'
276 * fields may not be accurate.
277 */
278 if (!pool_elem->stats_opt.bit.available)
279 return EM_OK; /* no statistics, return */
280
281 /* EM pool usage statistics _enabled_ - collect it: */
282 for (int i = 0; i < pool_elem->num_subpools; i++) {
283 const uint64_t num = pool_elem->pool_cfg.subpool[i].num;
284 uint64_t used = 0;
285 uint64_t free = 0;
286 odp_pool_stats_t odp_stats;
287
288 /* avoid LTO-error: 'odp_stats.thread.first/last' may be used uninitialized */
289 odp_stats.thread.first = 0;
290 odp_stats.thread.last = 0;
291
292 int ret = odp_pool_stats(pool_elem->odp_pool[i], &odp_stats);
293
294 RETURN_ERROR_IF(ret, EM_ERR_LIB_FAILED, EM_ESCOPE_POOL_INFO,
295 "EM-pool:%" PRI_POOL " subpool:%d stats failed:%d",
296 pool, i, ret);
297 /* ODP inactive counters are zero, it is safe to add both: */
298 free = odp_stats.available + odp_stats.cache_available;
299 if (free > num)
300 free = num;
301 used = num - free;
302
303 pool_info->subpool[i].used = used;
304 pool_info->subpool[i].free = free;
305 }
306
307 return EM_OK;
308}
309
310void
311em_pool_info_print(em_pool_t pool)
312{
313 pool_info_print_hdr(1);
314 pool_info_print(pool);
315}
316
317int em_pool_num_subpools(em_pool_t pool)
318{
319 const mpool_elem_t *pool_elem = pool_elem_get(pool);
320
321 if (EM_CHECK_LEVEL > 0 && unlikely(!pool_elem)) {
322 INTERNAL_ERROR(EM_ERR_BAD_ARG, EM_ESCOPE_POOL_NUM_SUBPOOLS,
323 "Inv. args: pool:%" PRI_POOL, pool);
324 return -1;
325 }
326
327 if (EM_CHECK_LEVEL >= 2 && unlikely(!pool_allocated(pool_elem))) {
328 INTERNAL_ERROR(EM_ERR_NOT_CREATED, EM_ESCOPE_POOL_NUM_SUBPOOLS,
329 "EM-pool:%" PRI_POOL " not created", pool);
330 return -1;
331 }
332
333 return pool_elem->num_subpools;
334}
335
336void
338{
339 em_pool_t pool;
340 unsigned int num;
341
342 pool = em_pool_first(&num);
343
344 pool_info_print_hdr(num);
345 while (pool != EM_POOL_UNDEF) {
346 pool_info_print(pool);
347 pool = em_pool_next();
348 }
349}
350
352em_pool_stats_opt(em_pool_t pool, em_pool_stats_opt_t *pool_stats_opt /*out*/)
353{
354 const mpool_elem_t *pool_elem = pool_elem_get(pool);
355
356 if (EM_CHECK_LEVEL > 0)
357 RETURN_ERROR_IF(!pool_elem || !pool_stats_opt,
358 EM_ERR_BAD_ARG, EM_ESCOPE_POOL_STATS_OPT,
359 "Inv. args: pool:%" PRI_POOL " pool_stats_opt:%p",
360 pool, pool_stats_opt);
361
362 if (EM_CHECK_LEVEL >= 2)
363 RETURN_ERROR_IF(!pool_allocated(pool_elem),
364 EM_ERR_NOT_CREATED, EM_ESCOPE_POOL_STATS_OPT,
365 "EM-pool:%" PRI_POOL " not created", pool);
366
367 pool_stats_opt_odp2em(pool_stats_opt, &pool_elem->stats_opt);
368
369 return EM_OK;
370}
371
372void em_pool_stats_opt_print(em_pool_t pool)
373{
374 pool_stats_opt_print_hdr();
375 pool_stats_opt_print(pool);
376}
377
379{
380 em_pool_t pool;
381 unsigned int num;
382
383 pool = em_pool_first(&num);
384
385 pool_stats_opt_print_hdr();
386 while (pool != EM_POOL_UNDEF) {
387 pool_stats_opt_print(pool);
388 pool = em_pool_next();
389 }
390}
391
392em_status_t em_pool_stats(em_pool_t pool, em_pool_stats_t *pool_stats/*out*/)
393{
394 int i;
395 int ret;
396 odp_pool_stats_t *odp_stats;
397 const mpool_elem_t *pool_elem = pool_elem_get(pool);
398
399 if (EM_CHECK_LEVEL > 0)
400 RETURN_ERROR_IF(!pool_elem || !pool_stats,
401 EM_ERR_BAD_ARG, EM_ESCOPE_POOL_STATS,
402 "Inv. args: pool:%" PRI_POOL " pool_stats:%p",
403 pool, pool_stats);
404
405 if (EM_CHECK_LEVEL >= 2)
406 RETURN_ERROR_IF(!pool_allocated(pool_elem),
407 EM_ERR_NOT_CREATED, EM_ESCOPE_POOL_STATS,
408 "EM-pool: %" PRI_POOL "not created", pool);
409
410 i = 0;
411 for (; i < pool_elem->num_subpools; i++) {
412 odp_stats = (odp_pool_stats_t *)&pool_stats->subpool_stats[i];
413
414 /* avoid LTO-error: 'odp_stats.thread.first/last' may be used uninitialized */
415 odp_stats->thread.first = 0;
416 odp_stats->thread.last = 0;
417
418 ret = odp_pool_stats(pool_elem->odp_pool[i], odp_stats);
419
420 RETURN_ERROR_IF(ret, EM_ERR_LIB_FAILED, EM_ESCOPE_POOL_STATS,
421 "EM-pool:%" PRI_POOL " subpool:%d stats failed:%d",
422 pool, i, ret);
423 }
424
425 pool_stats->num_subpools = i;
426
427 return EM_OK;
428}
429
431{
432 int ret;
433 const mpool_elem_t *pool_elem = pool_elem_get(pool);
434
435 if (EM_CHECK_LEVEL > 0)
436 RETURN_ERROR_IF(pool_elem == NULL,
437 EM_ERR_BAD_ARG, EM_ESCOPE_POOL_STATS_RESET,
438 "EM-pool:%" PRI_POOL " invalid", pool);
439
440 if (EM_CHECK_LEVEL >= 2)
441 RETURN_ERROR_IF(!pool_allocated(pool_elem),
442 EM_ERR_NOT_CREATED, EM_ESCOPE_POOL_STATS_RESET,
443 "EM-pool:%" PRI_POOL " not created", pool);
444
445 for (int i = 0; i < pool_elem->num_subpools; i++) {
446 ret = odp_pool_stats_reset(pool_elem->odp_pool[i]);
447 RETURN_ERROR_IF(ret, EM_ERR_LIB_FAILED, EM_ESCOPE_POOL_STATS_RESET,
448 "EM-pool:%" PRI_POOL " subpool:%d stats reset failed:%d",
449 pool);
450 }
451
452 return EM_OK;
453}
454
455void em_pool_stats_print(em_pool_t pool)
456{
457 pool_stats_print(pool);
458}
459
460#define SUBPOOL_STATS_INV_ARG_FMT \
461"Inv. args: pool:%" PRI_POOL " subpools:%p num_subpools:%d subpool_stats:%p"
462
463int
464em_pool_subpool_stats(em_pool_t pool, const int subpools[], int num_subpools,
465 em_pool_subpool_stats_t subpool_stats[]/*out*/)
466{
467 int ret;
468 int num_stats = 0;
469 odp_pool_stats_t *odp_stats;
470 const mpool_elem_t *pool_elem = pool_elem_get(pool);
471
472 if (EM_CHECK_LEVEL > 0 &&
473 unlikely(!pool_elem || !subpools || !subpool_stats ||
474 num_subpools <= 0 || num_subpools > pool_elem->num_subpools)) {
475 INTERNAL_ERROR(EM_ERR_BAD_ARG, EM_ESCOPE_POOL_SUBPOOL_STATS,
476 SUBPOOL_STATS_INV_ARG_FMT, pool, subpools,
477 num_subpools, subpool_stats);
478 return 0;
479 }
480
481 if (EM_CHECK_LEVEL >= 2 && unlikely(!pool_allocated(pool_elem))) {
482 INTERNAL_ERROR(EM_ERR_NOT_CREATED, EM_ESCOPE_POOL_SUBPOOL_STATS,
483 "EM-pool: %" PRI_POOL "not allocated", pool);
484 return 0;
485 }
486
487 for (int i = 0; i < num_subpools; i++) {
488 if (EM_CHECK_LEVEL > 0 &&
489 unlikely(subpools[i] < 0 || subpools[i] > pool_elem->num_subpools - 1)) {
490 INTERNAL_ERROR(EM_ERR_BAD_ARG, EM_ESCOPE_POOL_SUBPOOL_STATS,
491 "arg 'subpools[%d]: %d' out of range", i, subpools[i]);
492 return num_stats;
493 }
494
495 odp_stats = (odp_pool_stats_t *)&subpool_stats[i];
496
497 /* avoid LTO-error: 'odp_stats.thread.first/last' may be used uninitialized */
498 odp_stats->thread.first = 0;
499 odp_stats->thread.last = 0;
500
501 ret = odp_pool_stats(pool_elem->odp_pool[subpools[i]], odp_stats);
502 if (unlikely(ret < 0)) {
503 INTERNAL_ERROR(EM_ERR_LIB_FAILED, EM_ESCOPE_POOL_SUBPOOL_STATS,
504 "EM-pool:%" PRI_POOL " subpool:%d stats failed:%d",
505 pool, subpools[i], ret);
506 return num_stats;
507 }
508 num_stats++;
509 }
510
511 return num_stats;
512}
513
515em_pool_subpool_stats_reset(em_pool_t pool, const int subpools[], int num_subpools)
516{
517 int ret;
518 const mpool_elem_t *pool_elem = pool_elem_get(pool);
519
520 if (EM_CHECK_LEVEL > 0)
521 RETURN_ERROR_IF(!pool_elem || !subpools || num_subpools <= 0 ||
522 num_subpools > pool_elem->num_subpools,
523 EM_ERR_BAD_ARG, EM_ESCOPE_POOL_SUBPOOL_STATS_RESET,
524 "Inv. args: pool:%" PRI_POOL " subpools:%p num:%d",
525 pool, subpools, num_subpools);
526
527 if (EM_CHECK_LEVEL >= 2)
528 RETURN_ERROR_IF(!pool_allocated(pool_elem),
529 EM_ERR_NOT_CREATED, EM_ESCOPE_POOL_SUBPOOL_STATS_RESET,
530 "EM-pool:%" PRI_POOL " not created", pool);
531
532 for (int i = 0; i < num_subpools; i++) {
533 RETURN_ERROR_IF(subpools[i] < 0 || subpools[i] > pool_elem->num_subpools - 1,
534 EM_ERR_BAD_ARG, EM_ESCOPE_POOL_SUBPOOL_STATS_RESET,
535 "arg 'subpools[%d]: %d' out of range", i, subpools[i]);
536
537 ret = odp_pool_stats_reset(pool_elem->odp_pool[subpools[i]]);
538 RETURN_ERROR_IF(ret, EM_ERR_LIB_FAILED, EM_ESCOPE_POOL_SUBPOOL_STATS_RESET,
539 "EM-pool:%" PRI_POOL " subpool:%d stats reset failed:%d",
540 pool, subpools[i], ret);
541 }
542
543 return EM_OK;
544}
545
546void em_pool_subpool_stats_print(em_pool_t pool, const int subpools[], int num_subpools)
547{
548 subpools_stats_print(pool, subpools, num_subpools);
549}
550
551static inline void assign_odp_stats_opt(odp_pool_stats_opt_t *opt_odp/*out*/,
552 const em_pool_stats_opt_t *opt_em)
553{
554 opt_odp->all = 0;
555 opt_odp->bit.available = opt_em->available;
556 opt_odp->bit.alloc_ops = opt_em->alloc_ops;
557 opt_odp->bit.alloc_fails = opt_em->alloc_fails;
558 opt_odp->bit.free_ops = opt_em->free_ops;
559 opt_odp->bit.total_ops = opt_em->total_ops;
560 opt_odp->bit.cache_available = opt_em->cache_available;
561 opt_odp->bit.cache_alloc_ops = opt_em->cache_alloc_ops;
562 opt_odp->bit.cache_free_ops = opt_em->cache_free_ops;
563}
564
566em_pool_stats_selected(em_pool_t pool, em_pool_stats_selected_t *pool_stats/*out*/,
567 const em_pool_stats_opt_t *opt)
568{
569 int i;
570 int ret;
571 odp_pool_stats_opt_t opt_odp;
572 odp_pool_stats_selected_t *odp_stats;
573 const mpool_elem_t *pool_elem = pool_elem_get(pool);
574
575 if (EM_CHECK_LEVEL > 0)
576 RETURN_ERROR_IF(!pool_elem || !pool_stats || !opt,
577 EM_ERR_BAD_ARG, EM_ESCOPE_POOL_STATS_SELECTED,
578 "Inv. args: pool:%" PRI_POOL " pool_stats:%p opt: %p",
579 pool, pool_stats, opt);
580
581 if (EM_CHECK_LEVEL >= 2)
582 RETURN_ERROR_IF(!pool_allocated(pool_elem),
583 EM_ERR_NOT_CREATED, EM_ESCOPE_POOL_STATS_SELECTED,
584 "EM-pool: %" PRI_POOL "not created", pool);
585
586 assign_odp_stats_opt(&opt_odp, opt);
587
588 for (i = 0; i < pool_elem->num_subpools; i++) {
589 odp_pool_t odp_pool = pool_elem->odp_pool[i];
590
591 if (EM_CHECK_LEVEL >= 3)
592 RETURN_ERROR_IF(odp_pool == ODP_POOL_INVALID,
593 EM_ERR_BAD_ID, EM_ESCOPE_POOL_STATS_SELECTED,
594 "EM-pool:%" PRI_POOL " invalid subpool:%d",
595 pool, i);
596
597 odp_stats = (odp_pool_stats_selected_t *)&pool_stats->subpool_stats[i];
598
599 ret = odp_pool_stats_selected(odp_pool, odp_stats, &opt_odp);
600
601 RETURN_ERROR_IF(ret, EM_ERR_LIB_FAILED, EM_ESCOPE_POOL_STATS_SELECTED,
602 "EM-pool:%" PRI_POOL " subpool:%d stats selected failed:%d",
603 pool, i, ret);
604 }
605
606 pool_stats->num_subpools = i;
607
608 return EM_OK;
609}
610
611void em_pool_stats_selected_print(em_pool_t pool, const em_pool_stats_opt_t *opt)
612{
613 pool_stats_selected_print(pool, opt);
614}
615
616#define SUBPOOL_STATS_SELECTED_INV_ARG_FMT \
617"Inv. args: pool:%" PRI_POOL " subpools:%p num_subpools:%d subpool_stats:%p opt: %p"
618
619int em_pool_subpool_stats_selected(em_pool_t pool, const int subpools[], int num_subpools,
620 em_pool_subpool_stats_selected_t subpool_stats[]/*out*/,
621 const em_pool_stats_opt_t *opt)
622{
623 int ret;
624 int num_stats = 0;
625 odp_pool_stats_opt_t opt_odp;
626 odp_pool_stats_selected_t *odp_stats;
627 const mpool_elem_t *pool_elem = pool_elem_get(pool);
628
629 if (EM_CHECK_LEVEL > 0 &&
630 unlikely(!pool_elem || !subpools || !subpool_stats || !opt ||
631 num_subpools <= 0 || num_subpools > pool_elem->num_subpools)) {
632 INTERNAL_ERROR(EM_ERR_BAD_ARG, EM_ESCOPE_POOL_SUBPOOL_STATS_SELECTED,
633 SUBPOOL_STATS_SELECTED_INV_ARG_FMT, pool, subpools,
634 num_subpools, subpool_stats, opt);
635 return 0;
636 }
637
638 if (EM_CHECK_LEVEL >= 2 && unlikely(!pool_allocated(pool_elem))) {
639 INTERNAL_ERROR(EM_ERR_NOT_CREATED, EM_ESCOPE_POOL_SUBPOOL_STATS_SELECTED,
640 "EM-pool: %" PRI_POOL "not allocated", pool);
641 return 0;
642 }
643
644 assign_odp_stats_opt(&opt_odp, opt);
645
646 for (int i = 0; i < num_subpools; i++) {
647 if (EM_CHECK_LEVEL > 0 &&
648 unlikely(subpools[i] < 0 || subpools[i] > pool_elem->num_subpools - 1)) {
649 INTERNAL_ERROR(EM_ERR_BAD_ARG, EM_ESCOPE_POOL_SUBPOOL_STATS_SELECTED,
650 "arg 'subpools[%d]: %d' out of range", i, subpools[i]);
651 return num_stats;
652 }
653
654 odp_pool_t odp_pool = pool_elem->odp_pool[subpools[i]];
655
656 if (EM_CHECK_LEVEL >= 3 && unlikely(odp_pool == ODP_POOL_INVALID)) {
657 INTERNAL_ERROR(EM_ERR_BAD_ID, EM_ESCOPE_POOL_SUBPOOL_STATS_SELECTED,
658 "EM-pool:%" PRI_POOL " invalid subpool:%d", pool, i);
659 return num_stats;
660 }
661
662 odp_stats = (odp_pool_stats_selected_t *)&subpool_stats[i];
663
664 ret = odp_pool_stats_selected(odp_pool, odp_stats, &opt_odp);
665 if (unlikely(ret < 0)) {
666 INTERNAL_ERROR(EM_ERR_LIB_FAILED, EM_ESCOPE_POOL_SUBPOOL_STATS_SELECTED,
667 "EM-pool:%" PRI_POOL " subpool:%d stats failed:%d",
668 pool, subpools[i], ret);
669 return num_stats;
670 }
671 num_stats++;
672 }
673
674 return num_stats;
675}
676
677void em_pool_subpool_stats_selected_print(em_pool_t pool, const int subpools[],
678 int num_subpools,
679 const em_pool_stats_opt_t *opt)
680{
681 subpools_stats_selected_print(pool, subpools, num_subpools, opt);
682}
683
684uint64_t em_pool_to_u64(em_pool_t pool)
685{
686 return (uint64_t)pool;
687}
#define INTERNAL_ERROR(error, escope, fmt,...)
Definition em_error.h:58
#define RETURN_ERROR_IF(cond, error, escope, fmt,...)
Definition em_error.h:65
#define EM_CHECK_INIT_CALLED
em_shm_t * em_shm
#define EM_CONFIG_POOLS
#define EM_CHECK_LEVEL
#define EM_MAX_SUBPOOLS
The maximum number of subpools in each EM pool. The subpool is a pool with buffers of only one size.
#define PRI_POOL
#define EM_POOL_UNDEF
#define EM_OK
#define EM_FATAL(error)
uint32_t em_status_t
@ EM_ERR_BAD_ID
@ EM_ERR_NOT_CREATED
@ EM_ERR_BAD_ARG
@ EM_ERR_NOT_SUPPORTED
@ EM_ERR_LIB_FAILED
@ EM_EVENT_TYPE_UNDEF
void em_pool_stats_opt_print(em_pool_t pool)
em_pool_t em_pool_find(const char *name)
em_pool_t em_pool_create(const char *name, em_pool_t pool, const em_pool_cfg_t *pool_cfg)
void em_pool_cfg_init(em_pool_cfg_t *const pool_cfg)
void em_pool_subpool_stats_selected_print(em_pool_t pool, const int subpools[], int num_subpools, const em_pool_stats_opt_t *opt)
Helper function to print selected statistics for subpool(s) of an EM pool.
em_pool_t em_pool_next(void)
uint64_t em_pool_to_u64(em_pool_t pool)
em_status_t em_pool_subpool_stats_reset(em_pool_t pool, const int subpools[], int num_subpools)
void em_pool_stats_opt_print_all(void)
int em_pool_subpool_stats_selected(em_pool_t pool, const int subpools[], int num_subpools, em_pool_subpool_stats_selected_t subpool_stats[], const em_pool_stats_opt_t *opt)
Retrieve selected statistics about subpool(s) of an EM pool.
size_t em_pool_name(em_pool_t pool, char *name, size_t maxlen)
void em_pool_subpool_stats_print(em_pool_t pool, const int subpools[], int num_subpools)
Helper function to print statistics for subpool(s) of an EM pool.
void em_pool_stats_selected_print(em_pool_t pool, const em_pool_stats_opt_t *opt)
Helper function to print selected statistics for an EM pool.
em_status_t em_pool_stats_reset(em_pool_t pool)
void em_pool_stats_print(em_pool_t pool)
Helper function to print statistics for an EM pool.
em_status_t em_pool_stats_selected(em_pool_t pool, em_pool_stats_selected_t *pool_stats, const em_pool_stats_opt_t *opt)
Retrieve selected statistics about an EM pool.
em_status_t em_pool_info(em_pool_t pool, em_pool_info_t *pool_info)
void em_pool_info_print(em_pool_t pool)
em_status_t em_pool_delete(em_pool_t pool)
em_status_t em_pool_stats_opt(em_pool_t pool, em_pool_stats_opt_t *pool_stats_opt)
int em_pool_subpool_stats(em_pool_t pool, const int subpools[], int num_subpools, em_pool_subpool_stats_t subpool_stats[])
Retrieve statistics about subpool(s) of an EM pool.
em_pool_t em_pool_first(unsigned int *num)
em_status_t em_pool_stats(em_pool_t pool, em_pool_stats_t *pool_stats)
Retrieve statistics about an EM pool.
int em_pool_num_subpools(em_pool_t pool)
Return the number of subpools in an EM pool.
void em_pool_info_print_all(void)
struct em_pool_cfg_t::@23 subpool[EM_MAX_SUBPOOLS]
em_event_type_t event_type
em_event_type_t event_type
em_pool_stats_opt_t stats_opt
struct mpool_elem_t::@54 user_area
em_pool_cfg_t pool_cfg
odp_pool_stats_opt_t stats_opt
uint32_t align_offset
em_pool_t em_pool
odp_pool_t odp_pool[EM_MAX_SUBPOOLS]
uint16_t size
em_event_type_t event_type