EM-ODP 4.4.0
Event Machine on ODP
Loading...
Searching...
No Matches
event_machine_init.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018-2023, 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 initialization and termination.
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 <stdio.h>
49#include <string.h>
50
51#include <odp_api.h>
52#include <odp/helper/odph_api.h>
53
54#include <event_machine.h>
56
57#include "em_atomic_group.h"
58#include "em_chaining.h"
59#include "em_chaining_types.h"
60#include "em_cli.h"
61#include "em_core.h"
62#include "em_core_types.h"
63#include "em_dispatcher.h"
64#include "em_eo.h"
65#include "em_error.h"
66#include "em_event.h"
67#include "em_event_group.h"
68#include "em_event_state.h"
69#include "em_hooks.h"
70#include "em_info.h"
71#include "em_init.h"
72#include "em_internal_event.h"
73#include "em_libconfig.h"
74#include "em_mem.h"
75#include "em_pool.h"
76#include "em_queue.h"
77#include "em_queue_group.h"
78#include "em_timer.h"
79
80/**
81 * Check that the runtime ODP API version is supported.
82 *
83 * Compare the EM required ODP API version (EM_REQ_ODP_API_{GENERATION,MAJOR,MINOR})
84 * against both the ODP API header version (ODP_VERSION_API_{GENERATION,MAJOR,MINOR})
85 * and the runtime libodp version from odp_version_api_str().
86 */
87static em_status_t check_odp_version(void)
88{
89 const char *ver_str = odp_version_api_str();
90 unsigned int odp_api_ver = ODP_VERSION_API_NUM(ODP_VERSION_API_GENERATION,
91 ODP_VERSION_API_MAJOR,
92 ODP_VERSION_API_MINOR);
93 unsigned int gen = 0;
94 unsigned int major = 0;
95 unsigned int minor = 0;
96
97 if (ver_str == NULL || sscanf(ver_str, "%u.%u.%u", &gen, &major, &minor) != 3) {
98 EM_LOG(EM_LOG_ERR,
99 "Error: Unable to parse ODP runtime API version: \"%s\"\n",
100 ver_str ? ver_str : "NULL");
102 }
103
104 unsigned int odp_ver = ODP_VERSION_API_NUM(gen, major, minor);
105 unsigned int min_ver = ODP_VERSION_API_NUM(EM_REQ_ODP_API_GENERATION,
106 EM_REQ_ODP_API_MAJOR,
107 EM_REQ_ODP_API_MINOR);
108
109 if (odp_ver < min_ver || odp_api_ver < min_ver) {
110 EM_LOG(EM_LOG_ERR,
111 "Error: Unsupported ODP API version:%s%s\n"
112 " EM required ODP API version (min): %u.%u.%u\n"
113 " ODP API version from headers: %u.%u.%u\n"
114 " ODP API version from libodp: %u.%u.%u\n",
115 odp_api_ver < min_ver ? " headers too old" : "",
116 odp_ver < min_ver ? " libodp too old" : "",
117 EM_REQ_ODP_API_GENERATION,
118 EM_REQ_ODP_API_MAJOR,
119 EM_REQ_ODP_API_MINOR,
120 ODP_VERSION_API_GENERATION,
121 ODP_VERSION_API_MAJOR,
122 ODP_VERSION_API_MINOR,
123 gen, major, minor);
125 }
126
127 return EM_OK;
128}
129
130/** EM shared memory */
132
134
136{
137 if (unlikely(!conf)) {
139 EM_ESCOPE_CONF_INIT, "Conf pointer NULL!");
140 return;
141 }
142 memset(conf, 0, sizeof(em_conf_t));
145}
146
148{
149 em_status_t stat;
150 int ret;
151
152 RETURN_ERROR_IF(!conf, EM_FATAL(EM_ERR_BAD_ARG), EM_ESCOPE_INIT,
153 "Conf pointer NULL!");
154
156 EM_ERR_NOT_INITIALIZED, EM_ESCOPE_INIT,
157 "Not initialized: em_conf_init(conf) not called");
158
159 stat = early_log_init(conf->log.log_fn, conf->log.vlog_fn);
160 RETURN_ERROR_IF(stat != EM_OK, EM_FATAL(stat),
161 EM_ESCOPE_INIT, "User provided log funcs invalid!");
162
163 /* Sanity check: em_shm should not be set yet */
164 RETURN_ERROR_IF(em_shm != NULL,
165 EM_FATAL(EM_ERR_BAD_STATE), EM_ESCOPE_INIT,
166 "EM shared memory ptr set - already initialized?");
167 /* Sanity check: either process- or thread-per-core, but not both */
169 EM_FATAL(EM_ERR_BAD_ARG), EM_ESCOPE_INIT,
170 "Select EITHER process-per-core OR thread-per-core!");
171
172 /*
173 * Reserve the EM shared memory once at start-up.
174 */
175 uint32_t flags = 0;
176 odp_shm_capability_t shm_capa;
177
178 ret = odp_shm_capability(&shm_capa);
179 RETURN_ERROR_IF(ret, EM_ERR_OPERATION_FAILED, EM_ESCOPE_INIT,
180 "shm capability error:%d", ret);
181
182 if (shm_capa.flags & ODP_SHM_SINGLE_VA)
183 flags |= ODP_SHM_SINGLE_VA;
184
185 odp_shm_t shm = odp_shm_reserve("em_shm", sizeof(em_shm_t),
186 ODP_CACHE_LINE_SIZE, flags);
187
188 RETURN_ERROR_IF(shm == ODP_SHM_INVALID, EM_ERR_ALLOC_FAILED,
189 EM_ESCOPE_INIT, "Shared memory reservation failed!");
190
191 em_shm = odp_shm_addr(shm);
192
193 RETURN_ERROR_IF(em_shm == NULL, EM_ERR_NOT_FOUND, EM_ESCOPE_INIT,
194 "Shared memory ptr NULL!");
195
196 memset(em_shm, 0, sizeof(em_shm_t));
197
198 /* Store shm handle, can be used in em_term() to free the memory */
199 em_shm->this_shm = shm;
200
201 /* Store the given EM configuration */
202 em_shm->conf = *conf;
203
204 if (!EM_API_HOOKS_ENABLE) {
205 memset(&em_shm->conf.api_hooks, 0,
206 sizeof(em_shm->conf.api_hooks));
207 }
208
209 /* Initialize the log & error handling */
210 log_init();
211 error_init();
212
213 /* Check that the ODP API version (headers) is supported */
214 stat = check_odp_version();
215 RETURN_ERROR_IF(stat != EM_OK, EM_ERR_NOT_SUPPORTED, EM_ESCOPE_INIT,
216 "ODP API version not supported!");
217
218 /* Initialize libconfig */
219 ret = em_libconfig_init_global(&em_shm->libconfig);
220 RETURN_ERROR_IF(ret != 0, EM_ERR_OPERATION_FAILED, EM_ESCOPE_INIT,
221 "libconfig initialization failed:%d", ret);
222
223 /*
224 * Initialize the physical-core <-> EM-core mapping
225 *
226 * EM-core <-> ODP-thread id mappings cannot be set up yet,
227 * the ODP thread id is assigned only when that thread is initialized.
228 * Set this mapping in core_map_init_local()
229 */
230 stat = core_map_init(&em_shm->core_map);
231 RETURN_ERROR_IF(stat != EM_OK, EM_ERR_LIB_FAILED, EM_ESCOPE_INIT,
232 "core_map_init() failed:%" PRI_STAT "", stat);
233
234 /* Initialize the EM event dispatcher */
235 stat = dispatch_init();
236 RETURN_ERROR_IF(stat != EM_OK, EM_ERR_LIB_FAILED, EM_ESCOPE_INIT,
237 "dispatch_init() failed:%" PRI_STAT "", stat);
238
239 /*
240 * Initialize Event State Verification (ESV), if enabled at compile time
241 */
242 stat = esv_init();
243 RETURN_ERROR_IF(stat != EM_OK, EM_ERR_LIB_FAILED, EM_ESCOPE_INIT,
244 "esv_init() failed:%" PRI_STAT "", stat);
245
246 /* Initialize EM callbacks/hooks */
247 stat = hooks_init(&conf->api_hooks, &conf->idle_hooks);
248 RETURN_ERROR_IF(stat != EM_OK, EM_ERR_LIB_FAILED, EM_ESCOPE_INIT,
249 "hooks_init() failed:%" PRI_STAT "", stat);
250
251 /*
252 * Initialize the EM buffer pools and create the EM_DEFAULT_POOL.
253 * Create also startup pools if configured in the runtime config
254 * file through option 'startup_pools'.
255 */
256 stat = pool_init(&em_shm->mpool_tbl, &em_shm->mpool_pool,
257 &conf->default_pool_cfg);
258 RETURN_ERROR_IF(stat != EM_OK, EM_ERR_LIB_FAILED, EM_ESCOPE_INIT,
259 "pool_init() failed:%" PRI_STAT "", stat);
260
261 stat = event_init();
262 RETURN_ERROR_IF(stat != EM_OK, EM_ERR_LIB_FAILED, EM_ESCOPE_INIT,
263 "event_init() failed:%" PRI_STAT "", stat);
264
265 stat = event_group_init(&em_shm->event_group_tbl,
266 &em_shm->event_group_stash);
267 RETURN_ERROR_IF(stat != EM_OK, EM_ERR_LIB_FAILED, EM_ESCOPE_INIT,
268 "event_group_init() failed:%" PRI_STAT "", stat);
269
270 stat = queue_init(&em_shm->queue_tbl, &em_shm->queue_pool,
271 &em_shm->queue_pool_static, &em_shm->queue_pool_aggr);
272 RETURN_ERROR_IF(stat != EM_OK, EM_ERR_LIB_FAILED, EM_ESCOPE_INIT,
273 "queue_init() failed:%" PRI_STAT "", stat);
274
275 stat = queue_group_init(&em_shm->queue_group_tbl,
276 &em_shm->queue_group_pool);
277 RETURN_ERROR_IF(stat != EM_OK, EM_ERR_LIB_FAILED, EM_ESCOPE_INIT,
278 "queue_group_init() failed:%" PRI_STAT "", stat);
279
280 stat = atomic_group_init(&em_shm->atomic_group_tbl,
281 &em_shm->atomic_group_pool);
282 RETURN_ERROR_IF(stat != EM_OK, EM_ERR_LIB_FAILED, EM_ESCOPE_INIT,
283 "atomic_group_init() failed:%" PRI_STAT "", stat);
284
285 stat = eo_init(&em_shm->eo_tbl, &em_shm->eo_pool);
286 RETURN_ERROR_IF(stat != EM_OK, EM_ERR_LIB_FAILED, EM_ESCOPE_INIT,
287 "eo_init() failed:%" PRI_STAT "", stat);
288
290 RETURN_ERROR_IF(stat != EM_OK, EM_ERR_LIB_FAILED, EM_ESCOPE_INIT,
291 "create_shared_ctrl_queue() failed:%" PRI_STAT "", stat);
292
293 /* Initialize EM Timer */
294 if (conf->event_timer) {
295 stat = timer_init(&em_shm->timers);
296 RETURN_ERROR_IF(stat != EM_OK,
297 EM_ERR_LIB_FAILED, EM_ESCOPE_INIT,
298 "timer_init() failed:%" PRI_STAT "",
299 stat);
300 }
301
302 /* Initialize basic Event Chaining support */
303 stat = chaining_init(&em_shm->event_chaining);
304 RETURN_ERROR_IF(stat != EM_OK, EM_ERR_LIB_FAILED, EM_ESCOPE_INIT,
305 "chaining_init() failed:%" PRI_STAT "", stat);
306
307 /* Initialize em_cli */
308 stat = emcli_init();
309 RETURN_ERROR_IF(stat != EM_OK, EM_ERR_LIB_FAILED, EM_ESCOPE_INIT,
310 "emcli_init() failed:%" PRI_STAT "", stat);
311
312 /*
313 * Print EM and ODP version information
314 */
315 print_version_info();
316
317 em_shm->is_init = true;
318 return EM_OK;
319}
320
322{
323 RETURN_ERROR_IF(!conf_opts, EM_ERR_BAD_POINTER, EM_ESCOPE_CONF_OPTS,
324 "Conf pointer NULL!");
325
327 EM_ESCOPE_CONF_OPTS,
328 "EM not initialized - call em_init() first!");
329
330 *conf_opts = em_shm->conf;
331 return EM_OK;
332}
333
335{
336 conf_opts_print();
337}
338
340{
341 if (unlikely(!conf_local)) {
343 EM_ESCOPE_CONF_LOCAL_INIT, "conf_local pointer NULL!");
344 return;
345 }
346 memset(conf_local, 0, sizeof(*conf_local));
347 conf_local->core_id = -1; /* let EM assign core-id */
349}
350
352{
353 em_status_t status = EM_OK;
354 em_locm_t *const locm = &em_locm;
355 odp_thread_type_t thrtype_odp = odp_thread_type();
356
358 EM_ESCOPE_INIT_LOCAL,
359 "Must call em_init() first before %s!", __func__);
360
361 RETURN_ERROR_IF(!conf_local, EM_FATAL(EM_ERR_BAD_ARG), EM_ESCOPE_INIT_LOCAL,
362 "conf_local pointer NULL!");
363
365 EM_ERR_NOT_INITIALIZED, EM_ESCOPE_INIT_LOCAL,
366 "Not initialized: em_conf_local_init(conf_local) not called");
367
369 conf_local->core_type >= EM_CORE_TYPE_LAST,
370 EM_ERR_BAD_TYPE, EM_ESCOPE_INIT_LOCAL,
371 "Unsupported core_type=%d", conf_local->core_type);
372
373 RETURN_ERROR_IF(conf_local->core_id < -1, EM_ERR_BAD_ARG, EM_ESCOPE_INIT_LOCAL,
374 "Invalid core id: %d!", conf_local->core_id);
375
376 RETURN_ERROR_IF(is_core_initialized(), EM_ERR_BAD_STATE, EM_ESCOPE_INIT_LOCAL,
377 "Core already initialized! core_id:%d", locm->core_id);
378
379 switch (conf_local->core_type) {
381 RETURN_ERROR_IF(thrtype_odp != ODP_THREAD_WORKER,
382 EM_ERR_BAD_TYPE, EM_ESCOPE_INIT_LOCAL,
383 "ODP thread-type:%d not 'worker' for EM worker core!",
384 thrtype_odp);
385 status = init_local(conf_local, EM_ESCOPE_INIT_LOCAL);
386 break;
387
389 RETURN_ERROR_IF(thrtype_odp != ODP_THREAD_CONTROL,
390 EM_ERR_BAD_TYPE, EM_ESCOPE_INIT_LOCAL,
391 "ODP thread-type:%d not 'control' for EM control core!",
392 thrtype_odp);
393 status = init_local(conf_local, EM_ESCOPE_INIT_LOCAL);
394 break;
395
397 RETURN_ERROR_IF(thrtype_odp != ODP_THREAD_CONTROL,
398 EM_ERR_BAD_TYPE, EM_ESCOPE_INIT_LOCAL,
399 "ODP thread-type:%d not 'control' for EM external thread!",
400 thrtype_odp);
401 status = init_extthr(conf_local, EM_ESCOPE_INIT_LOCAL);
402 break;
403
404 default:
405 return INTERNAL_ERROR(EM_ERR_BAD_TYPE, EM_ESCOPE_INIT_LOCAL,
406 "Unsupported core_type=%d", conf_local->core_type);
407 }
408
409 if (status == EM_OK)
410 locm->is_core_local_inited = true;
411
412 return status;
413}
414
416{
417 const em_locm_t *const locm = &em_locm;
418
419 RETURN_ERROR_IF(!conf_local_opts, EM_ERR_BAD_POINTER,
420 EM_ESCOPE_CONF_LOCAL_OPTS, "Conf pointer NULL!");
421
422 RETURN_ERROR_IF(!is_core_initialized(), EM_ERR_BAD_STATE, EM_ESCOPE_CONF_LOCAL_OPTS,
423 "Not initialized locally: call em_init_local() or em_init_core() first!");
424
425 *conf_local_opts = locm->conf_local;
426
427 return EM_OK;
428}
429
431{
432 if (!is_core_initialized()) {
433 INTERNAL_ERROR(EM_ERR_BAD_STATE, EM_ESCOPE_CONF_LOCAL_OPTS,
434 "Not initialized locally, call em_init_local/core() first!");
435 return;
436 }
437
438 conf_local_opts_print();
439}
440
442{
443 em_conf_local_t conf_local;
444 em_status_t status = EM_OK;
445 em_locm_t *const locm = &em_locm;
446 odp_thread_type_t thrtype_odp = odp_thread_type();
447
449 EM_ESCOPE_INIT_CORE,
450 "Must call em_init() first before %s!", __func__);
451
452 RETURN_ERROR_IF(is_core_initialized(), EM_ERR_BAD_STATE, EM_ESCOPE_INIT_CORE,
453 "Core already initialized! core_id:%d", locm->core_id);
454
455 RETURN_ERROR_IF(thrtype_odp != ODP_THREAD_WORKER,
456 EM_ERR_BAD_TYPE, EM_ESCOPE_INIT_CORE,
457 "ODP thread-type:%d not 'worker' for EM worker core!",
458 thrtype_odp);
459
460 em_conf_local_init(&conf_local);
461 conf_local.core_type = EM_CORE_TYPE_WORKER;
462
463 status = init_local(&conf_local, EM_ESCOPE_INIT_CORE);
464 if (status == EM_OK)
465 locm->is_core_local_inited = true;
466
467 return status;
468}
469
471{
472 if (unlikely(!term_local)) {
474 EM_ESCOPE_TERM_LOCAL_INIT,
475 "term_local pointer NULL!");
476 return;
477 }
478 memset(term_local, 0, sizeof(*term_local));
480}
481
483{
484 em_locm_t *const locm = &em_locm;
485 const em_conf_local_t *conf_local = &locm->conf_local;
486 em_status_t status = EM_OK;
487
489 EM_ESCOPE_TERM_LOCAL, "term_local pointer NULL!");
490
492 EM_ESCOPE_TERM_LOCAL,
493 "EM not initialized - call em_init() first!");
494
495 RETURN_ERROR_IF(!is_core_initialized(), EM_ERR_BAD_STATE, EM_ESCOPE_TERM_LOCAL,
496 "Not initialized: em_init_local() or em_init_core() not called");
497
499 EM_ERR_NOT_INITIALIZED, EM_ESCOPE_TERM_LOCAL,
500 "Not initialized: em_term_local_init() not called");
501
502 switch (conf_local->core_type) {
503 case EM_CORE_TYPE_WORKER: /* fallthrough */
505 status = term_core(EM_ESCOPE_TERM_LOCAL);
506 break;
507
509 status = term_extthr(EM_ESCOPE_TERM_LOCAL);
510 break;
511
512 default:
513 return INTERNAL_ERROR(EM_ERR_BAD_TYPE, EM_ESCOPE_TERM_LOCAL,
514 "Unsupported core_type=%d", conf_local->core_type);
515 }
516
517 *locm = locm_init_values;
518
519 return status;
520}
521
523{
524 em_status_t status = EM_OK;
525 em_locm_t *const locm = &em_locm;
526 odp_thread_type_t thrtype_odp = odp_thread_type();
527
529 EM_ESCOPE_TERM_CORE,
530 "EM not initialized - call em_init() first!");
531
532 RETURN_ERROR_IF(!is_core_initialized(), EM_ERR_BAD_STATE, EM_ESCOPE_TERM_CORE,
533 "Not initialized: em_init_local() or em_init_core() not called");
534
535 RETURN_ERROR_IF(thrtype_odp != ODP_THREAD_WORKER,
536 EM_ERR_BAD_TYPE, EM_ESCOPE_TERM_CORE,
537 "ODP thread-type:%d not 'worker' for EM worker core!",
538 thrtype_odp);
539
540 status = term_core(EM_ESCOPE_TERM_CORE);
541 *locm = locm_init_values;
542 return status;
543}
544
546{
547 em_locm_t *const locm = &em_locm;
548 em_status_t stat;
549 int ret;
550
552 EM_ESCOPE_TERM, "EM not initialized or already terminated!");
553
554 /*
555 * Join all queue groups to be able to flush all events
556 * from the scheduler from this core.
557 */
558 queue_group_join_all();
559
560 /*
561 * Flush all events in the scheduler.
562 * Run loop twice: first with sched enabled and then paused.
563 */
564 if (locm->is_sched_paused) {
565 locm->is_sched_paused = false;
566 odp_schedule_resume();
567 }
568 for (int i = 0; i < 2; i++) {
569 flush_scheduler_events();
570 locm->is_sched_paused = true;
571 odp_schedule_pause();
572 }
573
574 stat = delete_ctrl_queues();
575 RETURN_ERROR_IF(stat != EM_OK, EM_ERR_LIB_FAILED, EM_ESCOPE_TERM,
576 "delete_ctrl_queues() failed:%" PRI_STAT "", stat);
577
579 timer_term(&em_shm->timers);
580
581 stat = emcli_term();
582 if (unlikely(stat != EM_OK)) {
583 INTERNAL_ERROR(EM_ERR_LIB_FAILED, EM_ESCOPE_TERM,
584 "emcli_term() failed:%" PRI_STAT "", stat);
585 /* Continue teardown after CLI error */
586 }
587
588 stat = chaining_term(&em_shm->event_chaining);
589 RETURN_ERROR_IF(stat != EM_OK, EM_ERR_LIB_FAILED, EM_ESCOPE_TERM,
590 "chaining_term() failed:%" PRI_STAT "", stat);
591
592 ret = em_libconfig_term_global(&em_shm->libconfig);
593 RETURN_ERROR_IF(ret != 0, EM_ERR_LIB_FAILED, EM_ESCOPE_TERM,
594 "EM config term failed:%d");
595
596 stat = pool_term(&em_shm->mpool_tbl);
597 RETURN_ERROR_IF(stat != EM_OK, EM_ERR_LIB_FAILED, EM_ESCOPE_TERM,
598 "pool_term() failed:%" PRI_STAT "", stat);
599
600 env_shared_free(em_shm->queue_tbl.queue_elem);
601
602 stat = event_group_term();
603 RETURN_ERROR_IF(stat != EM_OK, EM_ERR_LIB_FAILED, EM_ESCOPE_TERM,
604 "event_group_term() failed.");
605
606 /* Destroy all ODP schedule groups before freeing shared memory */
607 stat = queue_group_term();
608 if (unlikely(stat != EM_OK)) {
609 INTERNAL_ERROR(EM_ERR_LIB_FAILED, EM_ESCOPE_TERM,
610 "queue_group_term() failed:" PRI_STAT "", stat);
611 /* Continue teardown even if queue group term fails */
612 }
613
614 /*
615 * Free the EM shared memory
616 */
617 ret = odp_shm_free(em_shm->this_shm);
618 RETURN_ERROR_IF(ret != 0, EM_ERR_LIB_FAILED, EM_ESCOPE_TERM,
619 "odp_shm_free() failed:%d", ret);
620 /* Set em_shm = NULL to allow a new call to em_init() */
621 em_shm = NULL;
622
623 return EM_OK;
624}
625
626uint16_t em_device_id(void)
627{
628 return em_shm->conf.device_id;
629}
630
632{
633 RETURN_ERROR_IF(!cfgfile_opts, EM_ERR_BAD_ARG, EM_ESCOPE_CFGFILE_OPTS,
634 "cfgfile_opts pointer cannot be NULL!");
635
637 EM_ESCOPE_CFGFILE_OPTS,
638 "EM not initialized - call em_init() first!");
639
640 *cfgfile_opts = em_shm->opt;
641 return EM_OK;
642}
643
645{
646 cfgfile_opts_print();
647}
#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_LOCM_INIT_VALUES
Definition em_init.h:61
#define EM_CHECK_INIT_CALLED
em_status_t delete_ctrl_queues(void)
Delete EM's internal unscheduled control queues at teardown.
em_status_t create_shared_ctrl_queue(void)
Create EM's internal shared unscheduled control queue at startup.
ENV_LOCAL em_locm_t em_locm
#define EM_API_HOOKS_ENABLE
em_shm_t * em_shm
em_status_t emcli_term(void)
Terminate the EM CLI (if enabled)
Definition em_cli.c:2460
em_status_t emcli_init(void)
Initialize the EM CLI (if enabled)
Definition em_cli.c:2450
@ EM_CORE_TYPE_CONTROL
@ EM_CORE_TYPE_LAST
@ EM_CORE_TYPE_EXTERNAL
@ EM_CORE_TYPE_UNDEF
@ EM_CORE_TYPE_WORKER
#define EM_OK
#define EM_FATAL(error)
uint32_t em_status_t
@ EM_ERR_NOT_FOUND
@ EM_ERR_OPERATION_FAILED
@ EM_ERR_ALLOC_FAILED
@ EM_ERR_BAD_ARG
@ EM_ERR_NOT_SUPPORTED
@ EM_ERR_BAD_STATE
@ EM_ERR_BAD_TYPE
@ EM_ERR_LIB_FAILED
@ EM_ERR_NOT_INITIALIZED
@ EM_ERR_BAD_POINTER
void em_pool_cfg_init(em_pool_cfg_t *const pool_cfg)
em_status_t em_term(void)
em_status_t em_conf_local_opts(em_conf_local_t *conf_local_opts)
em_status_t em_term_local(const em_term_local_t *term_local)
em_status_t em_conf_opts(em_conf_t *conf_opts)
void em_term_local_init(em_term_local_t *term_local)
void em_cfgfile_opts_print(void)
void em_conf_local_init(em_conf_local_t *conf_local)
em_status_t em_init_local(const em_conf_local_t *conf_local)
em_status_t em_term_core(void)
void em_conf_local_opts_print(void)
void em_conf_init(em_conf_t *conf)
em_status_t em_init(const em_conf_t *conf)
em_status_t em_cfgfile_opts(em_cfgfile_opts_t *cfgfile_opts)
uint16_t em_device_id(void)
void em_conf_opts_print(void)
em_status_t em_init_core(void)
em_core_type_t core_type
em_log_func_t log_fn
struct em_conf_t::@2 log
em_api_hooks_t api_hooks
em_vlog_func_t vlog_fn
em_pool_cfg_t default_pool_cfg
uint32_t __internal_check
em_idle_hooks_t idle_hooks
bool is_core_local_inited
Definition em_mem.h:260
bool is_sched_paused
Definition em_mem.h:252
em_conf_local_t conf_local
Definition em_mem.h:295
int core_id
Definition em_mem.h:239
odp_shm_t this_shm
Definition em_mem.h:87
em_conf_t conf
Definition em_mem.h:93
em_cfgfile_opts_t opt
Definition em_mem.h:99
bool is_init
Definition em_mem.h:95