EM-ODP  3.7.0
Event Machine on ODP
em_core.c
1 /*
2  * Copyright (c) 2015, 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 #include "em_include.h"
32 
33 em_status_t core_map_init(core_map_t *const core_map, int core_count,
34  const em_core_mask_t *phys_mask)
35 {
36  int phys_id = 0;
37  int logic_id = 0;
38  int mask_count;
39  int last_phys_id;
40 
41  if (core_count > EM_MAX_CORES || core_count > odp_thread_count_max())
42  return EM_ERR_TOO_LARGE;
43 
44  mask_count = em_core_mask_count(phys_mask);
45  if (mask_count != core_count)
46  return EM_ERR_BAD_STATE;
47 
48  last_phys_id = em_core_mask_idx(core_count, phys_mask);
49  if (last_phys_id >= EM_MAX_CORES)
50  return EM_ERR_BAD_ID;
51 
52  memset(core_map, 0, sizeof(core_map_t));
53 
54  env_spinlock_init(&core_map->lock);
55  odp_atomic_init_u32(&core_map->current_core_count, 0);
56 
57  /* Store the EM core count, returned by em_core_count() */
58  core_map->count = core_count;
59 
60  em_core_mask_copy(&core_map->phys_mask, phys_mask);
61  em_core_mask_set_count(core_count, &core_map->logic_mask);
62 
63  while (logic_id < core_count && phys_id < EM_MAX_CORES) {
64  if (em_core_mask_isset(phys_id, &core_map->phys_mask)) {
65  core_map->phys_vs_logic.logic[phys_id] = logic_id;
66  core_map->phys_vs_logic.phys[logic_id] = phys_id;
67  logic_id++;
68  }
69  phys_id++;
70  }
71 
72  return EM_OK;
73 }
74 
75 em_status_t core_map_init_local(core_map_t *const core_map)
76 {
77  em_locm_t *const locm = &em_locm;
78  const int phys_core = odp_cpu_id();
79  const int odp_thr = odp_thread_id();
80  int32_t current_core_count;
81 
82  if (unlikely(phys_core >= EM_MAX_CORES))
83  return EM_ERR_BAD_ID;
84  if (odp_thr >= ODP_THREAD_COUNT_MAX ||
85  odp_thr >= odp_thread_count_max())
86  return EM_ERR_LIB_FAILED;
87 
88  /* Store the EM core id of this core, returned by em_core_id() */
89  locm->core_id = core_map->phys_vs_logic.logic[phys_core];
90 
91  if (unlikely(locm->core_id < 0))
92  return EM_ERR_TOO_SMALL;
93  if (unlikely(locm->core_id >= EM_MAX_CORES))
94  return EM_ERR_TOO_LARGE;
95 
96  env_spinlock_lock(&core_map->lock);
97  current_core_count = odp_atomic_fetch_inc_u32(&core_map->current_core_count);
98  core_map->thr_vs_logic.logic[odp_thr] = locm->core_id;
99  core_map->thr_vs_logic.odp_thr[locm->core_id] = odp_thr;
100  env_spinlock_unlock(&core_map->lock);
101 
102  EM_DBG("EM-core%02d: %s() - current core count:%d\n",
103  em_locm.core_id, __func__, current_core_count + 1);
104 
105  return EM_OK;
106 }
107 
108 em_status_t core_map_term_local(core_map_t *const core_map)
109 {
110  int32_t current_core_count = odp_atomic_fetch_dec_u32(&core_map->current_core_count);
111 
112  if (unlikely(current_core_count < 1)) {
113  EM_LOG(EM_LOG_ERR, "Current core count invalid: %d", current_core_count);
114  return EM_ERR_TOO_SMALL;
115  }
116 
117  EM_DBG("EM-core%02d: %s() - current core count:%d\n",
118  em_locm.core_id, __func__, current_core_count);
119 
120  return EM_OK;
121 }
122 
123 int logic_to_thr_core_id(const int logic_core)
124 {
125  if (unlikely(logic_core >= EM_MAX_CORES))
126  return -1;
127 
128  return em_shm->core_map.thr_vs_logic.odp_thr[logic_core];
129 }
130 
131 int thr_to_logic_core_id(const int thr_id)
132 {
133  if (unlikely(thr_id >= ODP_THREAD_COUNT_MAX))
134  return -1;
135 
136  return em_shm->core_map.thr_vs_logic.logic[thr_id];
137 }
138 
139 void mask_em2odp(const em_core_mask_t *const em_core_mask,
140  odp_thrmask_t *const odp_thrmask /*out*/)
141 {
142  int core_count = em_core_count();
143  int odp_thread_id;
144 
145  odp_thrmask_zero(odp_thrmask);
146 
147  /* EM cores are consecutive 0 -> em_core_count()-1 */
148  for (int i = 0; i < core_count; i++) {
149  if (em_core_mask_isset(i, em_core_mask)) {
150  odp_thread_id = logic_to_thr_core_id(i);
151  odp_thrmask_set(odp_thrmask, odp_thread_id);
152  }
153  }
154 }
155 
156 void mask_em2phys(const em_core_mask_t *const em_core_mask,
157  odp_cpumask_t *const odp_cpumask /*out*/)
158 {
159  int core_count = em_core_count();
160  int cpu_id;
161 
162  odp_cpumask_zero(odp_cpumask);
163 
164  /* EM cores are consecutive 0 -> em_core_count()-1 */
165  for (int i = 0; i < core_count; i++) {
166  if (em_core_mask_isset(i, em_core_mask)) {
167  cpu_id = logic_to_phys_core_id(i);
168  odp_cpumask_set(odp_cpumask, cpu_id);
169  }
170  }
171 }
em_core_mask_set_count
void em_core_mask_set_count(int count, em_core_mask_t *mask)
Definition: event_machine_hw_specific.c:76
EM_OK
#define EM_OK
Definition: event_machine_types.h:329
core_map_t::logic_mask
em_core_mask_t logic_mask
Definition: em_core_types.h:71
core_map_t::phys_mask
em_core_mask_t phys_mask
Definition: em_core_types.h:73
EM_ERR_TOO_SMALL
@ EM_ERR_TOO_SMALL
Definition: event_machine_hw_types.h:296
em_locm
ENV_LOCAL em_locm_t em_locm
core_map_t::current_core_count
odp_atomic_u32_t current_core_count
Definition: em_core_types.h:52
EM_ERR_LIB_FAILED
@ EM_ERR_LIB_FAILED
Definition: event_machine_hw_types.h:291
em_core_mask_isset
int em_core_mask_isset(int core, const em_core_mask_t *mask)
Definition: event_machine_hw_specific.c:58
em_core_mask_t
Definition: event_machine_hw_types.h:242
em_core_count
int em_core_count(void)
Definition: event_machine_core.c:40
EM_ERR_TOO_LARGE
@ EM_ERR_TOO_LARGE
Definition: event_machine_hw_types.h:294
core_map_t
Definition: em_core_types.h:47
EM_ERR_BAD_ID
@ EM_ERR_BAD_ID
Definition: event_machine_hw_types.h:265
core_map_t::odp_thr
uint8_t odp_thr[EM_MAX_CORES]
Definition: em_core_types.h:67
em_locm_t::core_id
int core_id
Definition: em_mem.h:196
em_status_t
uint32_t em_status_t
Definition: event_machine_types.h:321
core_map_t::count
int count
Definition: em_core_types.h:55
em_core_mask_copy
void em_core_mask_copy(em_core_mask_t *dst, const em_core_mask_t *src)
Definition: event_machine_hw_specific.c:82
em_shm
em_shm_t * em_shm
Definition: event_machine_init.c:41
em_include.h
em_core_mask_count
int em_core_mask_count(const em_core_mask_t *mask)
Definition: event_machine_hw_specific.c:87
em_locm_t
Definition: em_mem.h:188
EM_ERR_BAD_STATE
@ EM_ERR_BAD_STATE
Definition: event_machine_hw_types.h:263
em_core_mask_idx
int em_core_mask_idx(int n, const em_core_mask_t *mask)
Definition: event_machine_hw_specific.c:164
core_map_t::logic
uint8_t logic[EM_MAX_CORES]
Definition: em_core_types.h:58
core_map_t::phys
uint8_t phys[EM_MAX_CORES]
Definition: em_core_types.h:60
core_map_t::lock
env_spinlock_t lock
Definition: em_core_types.h:49