EM-ODP  3.7.0
Event Machine on ODP
em_info.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 /* Copyright (c) 2018, Linaro Limited
32  * Copyright (c) 2020-2021, Nokia
33  * All rights reserved.
34  *
35  * SPDX-License-Identifier: BSD-3-Clause
36  */
37 
38 /* sysinfo printouts from the ODP example: odp_sysinfo.c */
39 /* SW ISA detection from the <arch>/odp_sysinfo_parse.c files */
40 
41 #include "em_include.h"
42 
43 static const char *cpu_arch_name(odp_cpu_arch_t cpu_arch)
44 {
45  switch (cpu_arch) {
46  case ODP_CPU_ARCH_ARM:
47  return "ARM";
48  case ODP_CPU_ARCH_MIPS:
49  return "MIPS";
50  case ODP_CPU_ARCH_PPC:
51  return "PPC";
52  case ODP_CPU_ARCH_RISCV:
53  return "RISC-V";
54  case ODP_CPU_ARCH_X86:
55  return "x86";
56  default:
57  return "Unknown";
58  }
59 }
60 
61 static const char *arm_isa_name(odp_cpu_arch_arm_t isa)
62 {
63  switch (isa) {
64  case ODP_CPU_ARCH_ARMV6:
65  return "ARMv6";
66  case ODP_CPU_ARCH_ARMV7:
67  return "ARMv7-A";
68  case ODP_CPU_ARCH_ARMV8_0:
69  return "ARMv8.0-A";
70  case ODP_CPU_ARCH_ARMV8_1:
71  return "ARMv8.1-A";
72  case ODP_CPU_ARCH_ARMV8_2:
73  return "ARMv8.2-A";
74  case ODP_CPU_ARCH_ARMV8_3:
75  return "ARMv8.3-A";
76  case ODP_CPU_ARCH_ARMV8_4:
77  return "ARMv8.4-A";
78  case ODP_CPU_ARCH_ARMV8_5:
79  return "ARMv8.5-A";
80  case ODP_CPU_ARCH_ARMV8_6:
81  return "ARMv8.6-A";
82  case ODP_CPU_ARCH_ARMV8_7:
83  return "ARMv8.7-A";
84  case ODP_CPU_ARCH_ARMV9_0:
85  return "ARMv9.0-A";
86  case ODP_CPU_ARCH_ARMV9_1:
87  return "ARMv9.1-A";
88  case ODP_CPU_ARCH_ARMV9_2:
89  return "ARMv9.2-A";
90 #if ODP_VERSION_API_NUM(1, 42, 1) <= ODP_VERSION_API
91  case ODP_CPU_ARCH_ARMV8_8:
92  return "ARMv8.8-A";
93  case ODP_CPU_ARCH_ARMV8_9:
94  return "ARMv8.9-A";
95  case ODP_CPU_ARCH_ARMV9_3:
96  return "ARMv9.3-A";
97 #endif
98  default:
99  return "Unknown";
100  }
101 }
102 
103 static const char *x86_isa_name(odp_cpu_arch_x86_t isa)
104 {
105  switch (isa) {
106  case ODP_CPU_ARCH_X86_I686:
107  return "x86_i686";
108  case ODP_CPU_ARCH_X86_64:
109  return "x86_64";
110  default:
111  return "Unknown";
112  }
113 }
114 
115 static const char *cpu_arch_isa_name(odp_cpu_arch_t cpu_arch,
116  odp_cpu_arch_isa_t cpu_arch_isa)
117 {
118  switch (cpu_arch) {
119  case ODP_CPU_ARCH_ARM:
120  return arm_isa_name(cpu_arch_isa.arm);
121  case ODP_CPU_ARCH_MIPS:
122  return "Unknown";
123  case ODP_CPU_ARCH_PPC:
124  return "Unknown";
125  case ODP_CPU_ARCH_RISCV:
126  return "Unknown";
127  case ODP_CPU_ARCH_X86:
128  return x86_isa_name(cpu_arch_isa.x86);
129  default:
130  return "Unknown";
131  }
132 }
133 
134 /*
135  * Detect the ARM ISA used when compiling the em-odp library.
136  * (based on the <arch>/odp_sysinfo_parse.c files)
137  */
138 static odp_cpu_arch_arm_t detect_sw_isa_arm(void)
139 {
140 #if defined(__ARM_ARCH)
141  if (__ARM_ARCH == 8) {
142  #ifdef __ARM_FEATURE_QRDMX
143  /* v8.1 or higher */
144  return ODP_CPU_ARCH_ARMV8_1;
145  #else
146  return ODP_CPU_ARCH_ARMV8_0;
147  #endif
148  }
149 
150  if (__ARM_ARCH == 9) {
151  /* v9.0 or higher */
152  return ODP_CPU_ARCH_ARMV9_0;
153  }
154 
155  if (__ARM_ARCH >= 800) {
156  /*
157  * ACLE 2018 defines that from v8.1 onwards the value includes
158  * the minor version number: __ARM_ARCH = X * 100 + Y
159  * E.g. for Armv8.1 __ARM_ARCH = 801
160  */
161  int major = __ARM_ARCH / 100;
162  int minor = __ARM_ARCH - (major * 100);
163 
164  if (major == 8) {
165  switch (minor) {
166  case 0:
167  return ODP_CPU_ARCH_ARMV8_0;
168  case 1:
169  return ODP_CPU_ARCH_ARMV8_1;
170  case 2:
171  return ODP_CPU_ARCH_ARMV8_2;
172  case 3:
173  return ODP_CPU_ARCH_ARMV8_3;
174  case 4:
175  return ODP_CPU_ARCH_ARMV8_4;
176  case 5:
177  return ODP_CPU_ARCH_ARMV8_5;
178  case 6:
179  return ODP_CPU_ARCH_ARMV8_6;
180  case 7:
181  return ODP_CPU_ARCH_ARMV8_7;
182 #if ODP_VERSION_API_NUM(1, 42, 1) <= ODP_VERSION_API
183  case 8:
184  return ODP_CPU_ARCH_ARMV8_8;
185  case 9:
186  return ODP_CPU_ARCH_ARMV8_9;
187 #endif
188  default:
189  return ODP_CPU_ARCH_ARM_UNKNOWN;
190  }
191  } else if (major == 9) {
192  switch (minor) {
193  case 0:
194  return ODP_CPU_ARCH_ARMV9_0;
195  case 1:
196  return ODP_CPU_ARCH_ARMV9_1;
197  case 2:
198  return ODP_CPU_ARCH_ARMV9_2;
199 #if ODP_VERSION_API_NUM(1, 42, 1) <= ODP_VERSION_API
200  case 3:
201  return ODP_CPU_ARCH_ARMV9_3;
202 #endif
203  default:
204  return ODP_CPU_ARCH_ARM_UNKNOWN;
205  }
206  }
207  }
208 #endif
209  return ODP_CPU_ARCH_ARM_UNKNOWN;
210 }
211 
212 /*
213  * Detect the x86 ISA used when compiling the em-odp library.
214  * (based on the <arch>/odp_sysinfo_parse.c files)
215  */
216 static odp_cpu_arch_x86_t detect_sw_isa_x86(void)
217 {
218  odp_cpu_arch_x86_t isa_x86 = ODP_CPU_ARCH_X86_UNKNOWN;
219 
220 #if defined __x86_64 || defined __x86_64__
221  isa_x86 = ODP_CPU_ARCH_X86_64;
222 #elif defined __i686 || defined __i686__
223  isa_x86 = ODP_CPU_ARCH_X86_I686;
224 #endif
225  return isa_x86;
226 }
227 
228 static odp_cpu_arch_mips_t detect_sw_isa_mips(void)
229 {
230  return ODP_CPU_ARCH_MIPS_UNKNOWN;
231 }
232 
233 static odp_cpu_arch_ppc_t detect_sw_isa_ppc(void)
234 {
235  return ODP_CPU_ARCH_PPC_UNKNOWN;
236 }
237 
238 static odp_cpu_arch_riscv_t detect_sw_isa_riscv(void)
239 {
240  return ODP_CPU_ARCH_RISCV_UNKNOWN;
241 }
242 
243 /*
244  * Detect the SW CPU ISA used when compiling the em-odp library.
245  * (based on the <arch>/odp_sysinfo_parse.c files)
246  */
247 static odp_cpu_arch_isa_t detect_sw_isa(odp_cpu_arch_t cpu_arch)
248 {
249  odp_cpu_arch_isa_t sw_isa;
250 
251  switch (cpu_arch) {
252  case ODP_CPU_ARCH_ARM:
253  sw_isa.arm = detect_sw_isa_arm();
254  break;
255  case ODP_CPU_ARCH_MIPS:
256  sw_isa.mips = detect_sw_isa_mips();
257  break;
258  case ODP_CPU_ARCH_PPC:
259  sw_isa.ppc = detect_sw_isa_ppc();
260  break;
261  case ODP_CPU_ARCH_RISCV:
262  sw_isa.riscv = detect_sw_isa_riscv();
263  break;
264  case ODP_CPU_ARCH_X86:
265  sw_isa.x86 = detect_sw_isa_x86();
266  break;
267  default:
268  sw_isa.arm = ODP_CPU_ARCH_ARM_UNKNOWN;
269  break;
270  }
271 
272  return sw_isa;
273 }
274 
275 void print_core_map_info(void)
276 {
277  EM_PRINT("Core mapping: EM-core <-> phys-core <-> ODP-thread\n");
278 
279  for (int logic_core = 0; logic_core < em_core_count(); logic_core++) {
280  EM_PRINT(" %2i %2i %2i\n",
281  logic_core,
282  em_core_id_get_physical(logic_core),
283  logic_to_thr_core_id(logic_core));
284  }
285 
286  EM_PRINT("\n");
287 }
288 
289 void print_cpu_arch_info(void)
290 {
291  odp_system_info_t sysinfo;
292  int err;
293 
294  err = odp_system_info(&sysinfo);
295  if (err) {
296  EM_PRINT("%s(): odp_system_info() call failed:%d\n",
297  __func__, err);
298  return;
299  }
300 
301  /* detect & print EM SW ISA info here also */
302  odp_cpu_arch_isa_t isa_em = detect_sw_isa(sysinfo.cpu_arch);
303 
304  const char *cpu_arch = cpu_arch_name(sysinfo.cpu_arch);
305  const char *hw_isa = cpu_arch_isa_name(sysinfo.cpu_arch,
306  sysinfo.cpu_isa_hw);
307  const char *sw_isa_odp = cpu_arch_isa_name(sysinfo.cpu_arch,
308  sysinfo.cpu_isa_sw);
309  const char *sw_isa_em = cpu_arch_isa_name(sysinfo.cpu_arch, isa_em);
310 
311  EM_PRINT("CPU model: %s\n"
312  "CPU arch: %s\n"
313  "CPU ISA version: %s\n"
314  " SW ISA version (ODP): %s\n"
315  " SW ISA version (EM): %s\n"
316  "\n",
317  odp_cpu_model_str(), cpu_arch,
318  hw_isa, sw_isa_odp, sw_isa_em);
319 }
320 
321 static void print_mem_info(void)
322 {
323  EM_PRINT("EM shared mem size: %zu B\n"
324  "EM local mem size: %zu B (per core)\n",
325  sizeof(em_shm_t), sizeof(em_locm_t));
326 
327  EM_DBG("\nem_locm_t:\t\t\t offset\t size\n"
328  "\t\t\t\t ------\t ----\n"
329  "current:\t\t\t%5zu B\t%5zu B\n"
330  "idle_state:\t\t\t%5zu B\t%5zu B\n"
331  "core_id:\t\t\t%5zu B\t%5zu B\n"
332  "event_burst_cnt:\t\t%5zu B\t%5zu B\n"
333  "atomic_group_released:\t\t%5zu B\t%5zu B\n"
334  "do_input_poll:\t\t\t%5zu B\t%5zu B\n"
335  "do_output_drain:\t\t%5zu B\t%5zu B\n"
336  "is_external_thr:\t\t%5zu B\t%5zu B\n"
337  "is_sched_paused:\t\t%5zu B\t%5zu B\n"
338  "dispatch_cnt:\t\t\t%5zu B\t%5zu B\n"
339  "dispatch_last_run:\t\t%5zu B\t%5zu B\n"
340  "poll_drain_dispatch_cnt:\t%5zu B\t%5zu B\n"
341  "poll_drain_dispatch_last_run:\t%5zu B\t%5zu B\n"
342  "local_queues:\t\t\t%5zu B\t%5zu B\n"
343  "start_eo_elem:\t\t\t%5zu B\t%5zu B\n"
344  "error_count:\t\t\t%5zu B\t%5zu B\n"
345  "log_fn:\t\t\t\t%5zu B\t%5zu B\n"
346  "sync_api:\t\t\t%5zu B\t%5zu B\n"
347  "debug_ts[]:\t\t\t%5zu B\t%5zu B\n"
348  "output_queue_track:\t\t%5zu B\t%5zu B\n"
349  "end:\t\t\t\t%5zu B\t%5zu B\n\n",
350  offsetof(em_locm_t, current),
351  sizeof_field(em_locm_t, current),
352  offsetof(em_locm_t, idle_state),
353  sizeof_field(em_locm_t, idle_state),
354  offsetof(em_locm_t, core_id),
355  sizeof_field(em_locm_t, core_id),
356  offsetof(em_locm_t, event_burst_cnt),
357  sizeof_field(em_locm_t, event_burst_cnt),
358  offsetof(em_locm_t, atomic_group_released),
359  sizeof_field(em_locm_t, atomic_group_released),
360  offsetof(em_locm_t, do_input_poll),
361  sizeof_field(em_locm_t, do_input_poll),
362  offsetof(em_locm_t, do_output_drain),
363  sizeof_field(em_locm_t, do_output_drain),
364  offsetof(em_locm_t, is_external_thr),
365  sizeof_field(em_locm_t, is_external_thr),
366  offsetof(em_locm_t, is_sched_paused),
367  sizeof_field(em_locm_t, is_sched_paused),
368  offsetof(em_locm_t, dispatch_cnt),
369  sizeof_field(em_locm_t, dispatch_cnt),
370  offsetof(em_locm_t, dispatch_last_run),
371  sizeof_field(em_locm_t, dispatch_last_run),
372  offsetof(em_locm_t, poll_drain_dispatch_cnt),
373  sizeof_field(em_locm_t, poll_drain_dispatch_cnt),
374  offsetof(em_locm_t, poll_drain_dispatch_last_run),
375  sizeof_field(em_locm_t, poll_drain_dispatch_last_run),
376  offsetof(em_locm_t, local_queues),
377  sizeof_field(em_locm_t, local_queues),
378  offsetof(em_locm_t, start_eo_elem),
379  sizeof_field(em_locm_t, start_eo_elem),
380  offsetof(em_locm_t, error_count),
381  sizeof_field(em_locm_t, error_count),
382  offsetof(em_locm_t, log_fn),
383  sizeof_field(em_locm_t, log_fn),
384  offsetof(em_locm_t, sync_api),
385  sizeof_field(em_locm_t, sync_api),
386  offsetof(em_locm_t, debug_ts),
387  sizeof_field(em_locm_t, debug_ts),
388  offsetof(em_locm_t, output_queue_track),
389  sizeof_field(em_locm_t, output_queue_track),
390  offsetof(em_locm_t, end),
391  sizeof_field(em_locm_t, end)
392  );
393 }
394 
395 void print_version_info(void)
396 {
397  EM_PRINT("\n"
398  "===========================================================\n"
399  "EM version information: %s\n"
400  "===========================================================\n"
401  "EM API version: %s\n"
402  "EM version: %s, "
403 #ifdef EM_64_BIT
404  "64 bit "
405 #else
406  "32 bit "
407 #endif
408  "(EM_CHECK_LEVEL:%d, EM_ESV_ENABLE:%d)\n"
409  "EM build info: %s\n"
410  "ODP API version: %s\n"
411  "ODP impl name: %s\n"
412  "ODP impl details: %s\n",
416  odp_version_api_str(),
417  odp_version_impl_name(),
418  odp_version_impl_str());
419 
420  print_cpu_arch_info();
421 }
422 
423 /**
424  * Print information about EM & the environment
425  */
426 void print_em_info(void)
427 {
428  EM_PRINT("\n"
429  "===========================================================\n"
430  "EM Info on target: %s\n"
431  "===========================================================\n",
432  EM_TARGET_STR);
433  print_mem_info();
434  print_core_map_info();
436  print_queue_elem_info();
439  print_pool_elem_info();
440  print_ag_elem_info();
441  print_event_info();
442 }
EM_BUILD_INFO_STR
#define EM_BUILD_INFO_STR
Definition: event_machine_version.h:93
print_queue_capa
void print_queue_capa(void)
Definition: em_queue.c:1472
em_pool_info_print_all
void em_pool_info_print_all(void)
Definition: event_machine_pool.c:313
print_em_info
void print_em_info(void)
Definition: em_info.c:426
em_core_count
int em_core_count(void)
Definition: event_machine_core.c:40
em_core_id_get_physical
int em_core_id_get_physical(int core)
Definition: event_machine_helper.c:106
queue_group_info_print_all
void queue_group_info_print_all(void)
Print EM queue group info.
Definition: em_queue_group.c:1491
em_shm_t
Definition: em_mem.h:53
EM_CHECK_LEVEL
#define EM_CHECK_LEVEL
Definition: event_machine_config.h:253
em_include.h
EM_ESV_ENABLE
#define EM_ESV_ENABLE
Definition: event_machine_config.h:275
EM_TARGET_STR
#define EM_TARGET_STR
Definition: event_machine_version.h:88
em_locm_t
Definition: em_mem.h:188
EM_VERSION_STR
#define EM_VERSION_STR
Definition: event_machine_version.h:139
EM_VERSION_API_STR
#define EM_VERSION_API_STR
Definition: event_machine_version.h:134