EM-ODP  3.8.0-1
Event Machine on ODP
em_init.c
1 /* Copyright (c) 2020 Nokia Solutions and Networks
2  * All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include "em_include.h"
8 
9 static em_status_t poll_drain_mask_check(const em_core_mask_t *logic_mask,
10  const em_core_mask_t *poll_drain_mask)
11 {
12  /* check if mask is zero (all cores, OK) */
13  if (em_core_mask_iszero(poll_drain_mask))
14  return EM_OK;
15 
16  /* check mask validity */
17  for (int i = 0; i < EM_MAX_CORES; i++) {
18  if (em_core_mask_isset(i, poll_drain_mask) &&
19  !em_core_mask_isset(i, logic_mask))
21  }
22  return EM_OK;
23 }
24 
25 em_status_t input_poll_check(const em_core_mask_t *logic_mask, const em_conf_t *conf)
26 {
27  return poll_drain_mask_check(logic_mask, &conf->input.input_poll_mask);
28 }
29 
30 em_status_t output_drain_check(const em_core_mask_t *logic_mask, const em_conf_t *conf)
31 {
32  return poll_drain_mask_check(logic_mask, &conf->output.output_drain_mask);
33 }
34 
35 static bool poll_drain_check_local(int core_id, const em_core_mask_t *mask)
36 {
37  if (em_core_mask_iszero(mask) || em_core_mask_isset(core_id, mask))
38  return true;
39 
40  return false;
41 }
42 
43 em_status_t input_poll_init_local(void)
44 {
45  const em_conf_t *conf = &em_shm->conf;
46  em_locm_t *const locm = &em_locm;
47 
48  if (conf->input.input_poll_fn == NULL) {
49  locm->do_input_poll = false;
50  return EM_OK;
51  }
52 
53  const em_core_mask_t *input_poll_mask = &conf->input.input_poll_mask;
54 
55  locm->do_input_poll = poll_drain_check_local(locm->core_id, input_poll_mask);
56 
57  return EM_OK;
58 }
59 
60 em_status_t output_drain_init_local(void)
61 {
62  const em_conf_t *conf = &em_shm->conf;
63  em_locm_t *const locm = &em_locm;
64 
65  if (conf->output.output_drain_fn == NULL) {
66  locm->do_output_drain = false;
67  return EM_OK;
68  }
69  const em_core_mask_t *output_drain_mask = &conf->output.output_drain_mask;
70 
71  locm->do_output_drain = poll_drain_check_local(locm->core_id, output_drain_mask);
72 
73  return EM_OK;
74 }
75 
77 {
78  em_locm_t *const locm = &em_locm;
79 
80  locm->log_fn = func;
81 }
82 
84 {
85  em_locm_t *const locm = &em_locm;
86 
87  locm->vlog_fn = func;
88 }
89 
91 {
92  em_locm_t *const locm = &em_locm;
93  odp_shm_t shm;
94  em_shm_t *shm_addr;
95  em_status_t stat = EM_OK;
96 
97  /* Make sure that em_shm is available in this external thread */
98  shm = odp_shm_lookup("em_shm");
99  RETURN_ERROR_IF(shm == ODP_SHM_INVALID,
101  "Shared memory lookup failed!");
102 
103  shm_addr = odp_shm_addr(shm);
105  "Shared memory ptr NULL");
106 
107  if (shm_addr->conf.process_per_core && em_shm == NULL)
108  em_shm = shm_addr;
109 
111  "Shared memory init fails: em_shm:%p != shm_addr:%p",
112  em_shm, shm_addr);
113 
114  stat = emcli_init_local();
116  "Ext emcli_init_local() fails: %" PRI_STAT "", stat);
117 
118  /*
119  * Mark that this is an external thread, i.e. not an EM-core and thus
120  * will not participate in EM event dispatching.
121  */
122  locm->is_external_thr = true;
123 
124  return EM_OK;
125 }
126 
127 em_status_t sync_api_init_local(void)
128 {
129  em_locm_t *const locm = &em_locm;
130  int core = locm->core_id;
131  em_queue_t unsched_queue;
132  queue_elem_t *q_elem;
133 
134  unsched_queue = queue_id2hdl(FIRST_INTERNAL_UNSCHED_QUEUE + core);
135  if (unlikely(unsched_queue == EM_QUEUE_UNDEF))
136  return EM_ERR_NOT_FOUND;
137  q_elem = queue_elem_get(unsched_queue);
138  if (unlikely(!q_elem))
139  return EM_ERR_BAD_POINTER;
140  locm->sync_api.ctrl_poll.core_unsched_queue = unsched_queue;
141  locm->sync_api.ctrl_poll.core_unsched_qelem = q_elem;
142  locm->sync_api.ctrl_poll.core_odp_plain_queue = q_elem->odp_queue;
143 
144  unsched_queue = queue_id2hdl(SHARED_INTERNAL_UNSCHED_QUEUE);
145  if (unlikely(unsched_queue == EM_QUEUE_UNDEF))
146  return EM_ERR_NOT_FOUND;
147  q_elem = queue_elem_get(unsched_queue);
148  if (unlikely(!q_elem))
149  return EM_ERR_BAD_POINTER;
150  locm->sync_api.ctrl_poll.shared_unsched_queue = unsched_queue;
151  locm->sync_api.ctrl_poll.shared_unsched_qelem = q_elem;
152  locm->sync_api.ctrl_poll.shared_odp_plain_queue = q_elem->odp_queue;
153 
154  locm->sync_api.in_progress = false;
155 
156  return EM_OK;
157 }
#define RETURN_ERROR_IF(cond, error, escope, fmt,...)
Definition: em_error.h:50
void core_log_fn_set(em_log_func_t func)
Definition: em_init.c:76
em_status_t init_ext_thread(void)
Definition: em_init.c:90
void core_vlog_fn_set(em_vlog_func_t func)
Definition: em_init.c:83
ENV_LOCAL em_locm_t em_locm
em_shm_t * em_shm
int em_core_mask_iszero(const em_core_mask_t *mask)
int em_core_mask_isset(int core, const em_core_mask_t *mask)
@ EM_ERR_NOT_FOUND
@ EM_ERR_OPERATION_FAILED
@ EM_ERR_BAD_POINTER
#define EM_ESCOPE_INIT_CORE
int(* em_log_func_t)(em_log_level_t level, const char *fmt,...) __attribute__((format(printf
int(*) typedef int(* em_vlog_func_t)(em_log_level_t level, const char *fmt, va_list args)
#define EM_OK
uint32_t em_status_t
#define EM_QUEUE_UNDEF
em_status_t emcli_init_local(void)
Initialize the EM CLI locally on an EM core (if enabled)
Definition: em_cli.c:1451
em_core_mask_t input_poll_mask
em_core_mask_t output_drain_mask
em_output_drain_func_t output_drain_fn
struct em_conf_t::@5 output
struct em_conf_t::@4 input
em_input_poll_func_t input_poll_fn
bool do_input_poll
Definition: em_mem.h:203
em_log_func_t log_fn
Definition: em_mem.h:230
em_vlog_func_t vlog_fn
Definition: em_mem.h:233
int core_id
Definition: em_mem.h:196
sync_api_t sync_api
Definition: em_mem.h:236
bool is_external_thr
Definition: em_mem.h:207
bool do_output_drain
Definition: em_mem.h:205
odp_queue_t odp_queue
em_queue_t shared_unsched_queue
queue_elem_t * core_unsched_qelem
odp_queue_t shared_odp_plain_queue
odp_queue_t core_odp_plain_queue
em_queue_t core_unsched_queue
queue_elem_t * shared_unsched_qelem