EM-ODP 4.4.0
Event Machine on ODP
Loading...
Searching...
No Matches
event_machine_core.c
1/*
2 * Copyright (c) 2015-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#ifndef _GNU_SOURCE
32#define _GNU_SOURCE
33#endif
34
35#ifdef HAVE_CONFIG_H
36#include "config.h"
37#endif
38
39#include <stdint.h>
40
41#include <odp_api.h>
42
43#include <event_machine.h>
44
45#include "em_core.h"
46#include "em_core_types.h"
47#include "em_error.h"
48#include "em_mem.h"
49
50/* Per core (thread) state of em_core_id_first/next() */
51static ENV_LOCAL struct {
52 int idx;
53 em_core_mask_t *src_core_mask;
54} _core_id_iter = {.idx = -1, .src_core_mask = NULL};
55
56int em_core_id(void)
57{
58 return em_locm.core_id;
59}
60
61uint32_t em_core_count(void)
62{
63 return odp_atomic_load_u32(&em_shm->core_map.current_core_count);
64}
65
66uint32_t em_core_count_max(void)
67{
68 return em_shm->conf.core_count;
69}
70
72{
73 core_map_t *const core_map = &em_shm->core_map;
74 int count;
75
76 switch (core_type) {
78 count = odp_atomic_load_u32(&core_map->worker_core_count);
79 break;
81 count = odp_atomic_load_u32(&core_map->control_core_count);
82 break;
84 count = odp_atomic_load_u32(&core_map->external_thread_count);
85 break;
87 count = odp_atomic_load_u32(&core_map->current_core_count);
88 break;
89 default:
90 count = 0;
91 break;
92 }
93
94 return count;
95}
96
97int em_core_id_first(em_core_type_t core_type, uint32_t *num /*out*/)
98{
99 core_map_t *const core_map = &em_shm->core_map;
100 uint32_t current_core_count;
101 odp_atomic_u32_t *src_core_count;
102 em_core_mask_t *src_core_mask;
103 em_core_mask_t dst_core_mask;
104
105 if (unlikely(!(core_type == EM_CORE_TYPE_UNDEF ||
106 core_type == EM_CORE_TYPE_CONTROL ||
107 core_type == EM_CORE_TYPE_WORKER))) {
108 _core_id_iter.idx = -1;
109 if (num)
110 *num = 0;
111 return -1;
112 }
113
114 if (core_type == EM_CORE_TYPE_WORKER) {
115 src_core_count = &core_map->worker_core_count;
116 src_core_mask = &core_map->rwlocked.worker_mask;
117 } else if (core_type == EM_CORE_TYPE_CONTROL) {
118 src_core_count = &core_map->control_core_count;
119 src_core_mask = &core_map->rwlocked.control_mask;
120 } else {
121 src_core_count = &core_map->current_core_count;
122 src_core_mask = &core_map->rwlocked.logic_mask;
123 }
124
125 odp_rwlock_read_lock(&core_map->rwlock);
126 current_core_count = odp_atomic_load_u32(src_core_count);
127 em_core_mask_copy(&dst_core_mask, src_core_mask);
128 odp_rwlock_read_unlock(&core_map->rwlock);
129
130 if (num)
131 *num = current_core_count;
132
133 if (current_core_count == 0) {
134 _core_id_iter.idx = -1;
135 return -1;
136 }
137
138 _core_id_iter.idx = em_core_mask_first(&dst_core_mask);
139 _core_id_iter.src_core_mask = src_core_mask;
140
141 return _core_id_iter.idx;
142}
143
145{
146 core_map_t *const core_map = &em_shm->core_map;
147 const em_core_mask_t *src_core_mask = _core_id_iter.src_core_mask;
148 em_core_mask_t dst_core_mask;
149
150 if (unlikely(_core_id_iter.idx < 0))
151 return -1;
152
153 odp_rwlock_read_lock(&core_map->rwlock);
154 em_core_mask_copy(&dst_core_mask, src_core_mask);
155 odp_rwlock_read_unlock(&core_map->rwlock);
156
157 _core_id_iter.idx = em_core_mask_next(&dst_core_mask, _core_id_iter.idx);
158 if (unlikely(_core_id_iter.idx < 0)) {
159 _core_id_iter.idx = -1;
160 return -1;
161 }
162
163 return _core_id_iter.idx;
164}
165
167 em_core_mask_t *core_mask /*out*/)
168{
169 core_map_t *const core_map = &em_shm->core_map;
170 uint32_t current_core_count;
171 odp_atomic_u32_t *src_core_count;
172 const em_core_mask_t *src_core_mask;
173
174 if (unlikely(!core_mask ||
175 !(core_type == EM_CORE_TYPE_UNDEF ||
176 core_type == EM_CORE_TYPE_CONTROL ||
177 core_type == EM_CORE_TYPE_WORKER))) {
178 if (core_mask)
179 em_core_mask_zero(core_mask);
180 return 0;
181 }
182
183 if (core_type == EM_CORE_TYPE_WORKER) {
184 src_core_count = &core_map->worker_core_count;
185 src_core_mask = &core_map->rwlocked.worker_mask;
186 } else if (core_type == EM_CORE_TYPE_CONTROL) {
187 src_core_count = &core_map->control_core_count;
188 src_core_mask = &core_map->rwlocked.control_mask;
189 } else {
190 src_core_count = &core_map->current_core_count;
191 src_core_mask = &core_map->rwlocked.logic_mask;
192 }
193
194 odp_rwlock_read_lock(&core_map->rwlock);
195 current_core_count = odp_atomic_load_u32(src_core_count);
196 em_core_mask_copy(core_mask, src_core_mask);
197 odp_rwlock_read_unlock(&core_map->rwlock);
198
199 return current_core_count;
200}
201
ENV_LOCAL em_locm_t em_locm
em_shm_t * em_shm
int em_core_mask_first(const em_core_mask_t *mask)
void em_core_mask_copy(em_core_mask_t *dst, const em_core_mask_t *src)
int em_core_mask_next(const em_core_mask_t *mask, int idx)
void em_core_mask_zero(em_core_mask_t *mask)
int em_core_id_next(void)
int em_core_id(void)
uint32_t em_core_ids_available(em_core_type_t core_type, em_core_mask_t *core_mask)
em_core_type_t
int em_core_id_first(em_core_type_t core_type, uint32_t *num)
em_core_type_t em_core_type(void)
uint32_t em_core_count(void)
uint32_t em_core_count_max(void)
uint32_t em_core_type_count(em_core_type_t core_type)
@ EM_CORE_TYPE_CONTROL
@ EM_CORE_TYPE_EXTERNAL
@ EM_CORE_TYPE_UNDEF
@ EM_CORE_TYPE_WORKER
odp_atomic_u32_t external_thread_count
odp_rwlock_t rwlock
odp_atomic_u32_t current_core_count
odp_atomic_u32_t worker_core_count
em_core_mask_t logic_mask
odp_atomic_u32_t control_core_count
em_core_mask_t worker_mask
em_core_mask_t control_mask
em_core_type_t core_type
uint32_t core_count
em_conf_local_t conf_local
Definition em_mem.h:295
int core_id
Definition em_mem.h:239
em_conf_t conf
Definition em_mem.h:93