#include <inttypes.h>
#include <string.h>
#include <stdio.h>
#include "cm_setup.h"
#include "cm_error_handler.h"
#define USAGE_FMT \
"\n" \
"Usage: %s EM-ODP options -- APP SPECIFIC OPTIONS\n" \
" E.g. %s -c 0xfe -t -- -l l -e 10\n" \
"\n" \
"Open Event Machine example application.\n" \
"\n" \
"Note to get EM-ODP options:\n" \
" -h, --help before/without -- option.\n" \
"\n" \
"APP specific options\n" \
" -l, --loop <loop_type)\n" \
" run tests for loop type, (default: loop)\n" \
" l: loop\n" \
" r: refs\n" \
" v: vectors\n" \
" m: multircv\n" \
" p: pairs\n" \
" -f, --free Free each received event and allocate it a new\n" \
" (default: not freed)\n" \
" -u, --use-prio Use different queue priority levels.\n" \
" (default: single priority level used)\n" \
" -d, --data-size Event payload data size in bytes. (default: 250 B)\n" \
" (maximum: 256 B)\n" \
" -e, --eo-count Number of test EOs and queues. Must be an even number.\n" \
" (default: 128) (maximum: 128)\n" \
" -n, --event-amount Number of events per queue.\n" \
" (default: 32 and 128 for refs and multircv)\n" \
" (maximum: 128, for vectors max is 32)\n" \
" -q, --queue-type <queue_type>\n" \
" Queue type. (default: atomic, but for refs parallel)\n" \
" a: atomic\n" \
" p: parallel\n" \
" -c, --count-to-print The number of events to be received before printing\n" \
" a result.\n" \
" (default is 0xff0000 and 0x3f0000 for refs)\n" \
" (maximum: 0x7fffffff)\n" \
" -m, --multi-send The maximum number of events to be sent in multi event\n" \
" sending. Valid only for multircv.\n" \
" (default: 32) (maximum: 32)\n" \
" -v, --vector-size The size of vector to be sent in vector loop.\n" \
" Valid only for vectors. (default: 8) (maximum: 8)\n" \
" -h, --help Display help and exit.\n" \
"\n"
#define SEND_MULTI_MAX 32
#define MAX_VECTOR_SIZE 8
#define MAX_DATA_SIZE 256
#define MAX_NUM_EO 128
#define MAX_NUM_EVENTS 128
#define MAX_PRINT_EVENT_COUNT 0x7fffffff
typedef enum loop_type_t {
LOOP_TYPE_UNDEF = 0,
LOOP_TYPE_LOOP = 1,
LOOP_TYPE_VECTOR = 2,
LOOP_TYPE_MULTIRCV = 3,
LOOP_TYPE_REFS = 4,
LOOP_TYPE_PAIRS = 5
} loop_type_t;
#define RESULT_PRINTF_FMT \
"cycles/event:% -8.2f Mevents/s/core: %-6.2f %5.0f MHz core%02d %" PRIu64 "\n"
typedef struct {
int64_t events;
uint64_t begin_cycles;
uint64_t end_cycles;
uint64_t print_count;
} perf_stat_t;
typedef struct {
em_queue_t dest;
} eo_context_t;
typedef struct {
eo_context_t eo_ctx_tbl[MAX_NUM_EO];
em_eo_t eo_tbl[MAX_NUM_EO];
em_pool_t pool;
em_pool_t vec_pool;
} perf_shm_t;
static struct {
uint8_t queue_type;
uint32_t loop_type;
int64_t print_event_count;
int number_event_per_queue;
int data_size;
int number_eo;
int num_multi_events;
int vector_size;
bool free_event;
bool use_prio;
} perf_args;
perf_start(
void *eo_context, em_eo_t eo,
const em_eo_conf_t *conf);
perf_stop(void *eo_context, em_eo_t eo);
static void
em_queue_t queue, void *q_ctx);
static void
perf_receive_free(
void *eo_context, em_event_t event,
em_event_type_t type,
em_queue_t queue, void *q_ctx);
static void
perf_receive_pairs(
void *eo_context, em_event_t event,
em_event_type_t type,
em_queue_t queue, void *q_ctx);
static void
perf_receive_pairs_free(
void *eo_context, em_event_t event,
em_event_type_t type,
em_queue_t queue, void *q_ctx);
static void
perf_receive_multi(void *eo_context, em_event_t event_tbl[], int num,
em_queue_t queue, void *queue_context);
static void
perf_receive_multi_free(void *eo_context, em_event_t event_tbl[], int num,
em_queue_t queue, void *queue_context);
static void
print_result(perf_stat_t *const perf_stat);
get_queue_priority(const int index);
static void
set_default_opts(void);
static void
update_default_opts(bool queue_type_set, bool count_to_print_set, bool number_event_per_queue_set);
static void
print_loop_options(void);
static const char
*get_loop_type_str(uint32_t loop_type);
static void
create_vector_pool(void);
static void
send_burst(em_queue_t queue, em_event_t *events);
static void
alloc_send_events_ref(em_queue_t *queues);
static void
alloc_send_events_multircv(em_queue_t *queues);
static void
alloc_send_events(em_queue_t *queues, uint32_t num_eos);
static void
alloc_send_events_vector(em_queue_t *queues);
static void
create_queues_eos(uint32_t num_of_eos, em_queue_t *queues,
const char *eo_name, const char *queue_name,
uint8_t shift_eo_ctx_tbl, em_eo_t *eos);
static void
sync_to_queues_and_start_eos(em_queue_t *queues, em_queue_t *target_queues,
uint32_t offset, uint32_t num_of_eos, em_eo_t *eos);
static inline void send_event(em_event_t event, em_queue_t queue);
static inline void start_measurement(void);
static inline void end_measurement(void);
static inline void restart_measurement(int64_t *events);
static void
usage(char *progname)
{
APPL_PRINT(USAGE_FMT, NO_PATH(progname), NO_PATH(progname));
}
static void parse_app_specific_args(int argc, char *argv[])
{
int pca_argv_idx = 0;
for (int i = 1; i < argc; i++) {
if (!strcmp(argv[i], "--")) {
pca_argv_idx = i;
break;
}
}
set_default_opts();
bool queue_type_set = false;
bool count_to_print_set = false;
bool number_event_per_queue_set = false;
if (!pca_argv_idx)
return;
optind = pca_argv_idx + 1;
static const struct option longopts[] = {
{"loop", required_argument, NULL, 'l'},
{"free", no_argument, NULL, 'f'},
{"use-prio", no_argument, NULL, 'u'},
{"data-size", required_argument, NULL, 'd'},
{"eo-count", required_argument, NULL, 'e'},
{"event-amount", required_argument, NULL, 'n'},
{"queue-type", required_argument, NULL, 'q'},
{"count-to-print", required_argument, NULL, 'c'},
{"multi-send", required_argument, NULL, 'm'},
{"vector-size", required_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
static const char *shortopts = "l:fud:e:n:q:c:m:v:h";
while (1) {
int opt;
int long_idx;
opt = getopt_long(argc, argv, shortopts, longopts, &long_idx);
if (opt == -1)
break;
switch (opt) {
case 'l': {
if (*optarg == 'l') {
perf_args.loop_type = LOOP_TYPE_LOOP;
} else if (*optarg == 'v') {
perf_args.loop_type = LOOP_TYPE_VECTOR;
} else if (*optarg == 'm') {
perf_args.loop_type = LOOP_TYPE_MULTIRCV;
} else if (*optarg == 'r') {
perf_args.loop_type = LOOP_TYPE_REFS;
} else if (*optarg == 'p') {
perf_args.loop_type = LOOP_TYPE_PAIRS;
} else {
APPL_PRINT("Loop type must be l, v, m, r or p\n");
APPL_EXIT_FAILURE("Invalid type of loop: %s", optarg);
}
}
break;
case 'f': {
perf_args.free_event = true;
}
break;
case 'u': {
perf_args.use_prio = true;
}
break;
case 'd': {
perf_args.data_size = atoi(optarg);
if (perf_args.data_size <= 0 ||
perf_args.data_size > MAX_DATA_SIZE)
APPL_EXIT_FAILURE("Invalid data size: %s",
optarg);
}
break;
case 'e': {
perf_args.number_eo = atoi(optarg);
if (perf_args.number_eo <= 0 ||
perf_args.number_eo > MAX_NUM_EO ||
(perf_args.number_eo % 2))
APPL_EXIT_FAILURE("Invalid EO amount: %s",
optarg);
}
break;
case 'n': {
perf_args.number_event_per_queue = atoi(optarg);
number_event_per_queue_set = true;
if (perf_args.number_event_per_queue <= 0 ||
perf_args.number_event_per_queue > MAX_NUM_EVENTS)
APPL_EXIT_FAILURE("Invalid events amount: %s",
optarg);
}
break;
case 'q': {
if (*optarg == 'a') {
} else if (*optarg == 'p') {
} else {
APPL_PRINT("Queue type must be a (atomic) or p (parallel)\n");
APPL_EXIT_FAILURE("Invalid type of queue: %s", optarg);
}
queue_type_set = true;
}
break;
case 'c': {
char *end_ptr;
perf_args.print_event_count = strtol(optarg, &end_ptr, 16);
count_to_print_set = true;
if (perf_args.print_event_count <= 0 ||
perf_args.print_event_count > MAX_PRINT_EVENT_COUNT)
APPL_EXIT_FAILURE("Invalid print event count: %s",
optarg);
}
break;
case 'm': {
perf_args.num_multi_events = atoi(optarg);
if (perf_args.num_multi_events <= 0 ||
perf_args.num_multi_events > SEND_MULTI_MAX)
APPL_EXIT_FAILURE("Invalid multi-events count: %s",
optarg);
}
break;
case 'v': {
perf_args.vector_size = atoi(optarg);
if (perf_args.vector_size <= 0 ||
perf_args.vector_size > MAX_VECTOR_SIZE)
APPL_EXIT_FAILURE("Invalid vector size: %s",
optarg);
}
break;
case 'h':
usage(argv[0]);
exit(EXIT_SUCCESS);
break;
case ':':
usage(argv[0]);
APPL_EXIT_FAILURE("Missing arguments!\n");
break;
default:
usage(argv[0]);
APPL_EXIT_FAILURE("Unknown option!\n");
break;
}
}
update_default_opts(queue_type_set, count_to_print_set, number_event_per_queue_set);
print_loop_options();
optind = 1;
}
static void
set_default_opts(void)
{
perf_args.loop_type = LOOP_TYPE_LOOP;
perf_args.free_event = false;
perf_args.use_prio = false;
perf_args.data_size = 250;
perf_args.number_eo = 128;
perf_args.number_event_per_queue = 32;
perf_args.print_event_count = 0xff0000;
perf_args.num_multi_events = 32;
perf_args.vector_size = 8;
}
static void
update_default_opts(bool queue_type_set, bool count_to_print_set, bool number_event_per_queue_set)
{
if (!number_event_per_queue_set) {
if (perf_args.loop_type == LOOP_TYPE_REFS ||
perf_args.loop_type == LOOP_TYPE_MULTIRCV) {
perf_args.number_event_per_queue = 128;
}
}
if (!queue_type_set) {
if (perf_args.loop_type == LOOP_TYPE_REFS)
}
if (!count_to_print_set) {
if (perf_args.loop_type == LOOP_TYPE_REFS)
perf_args.print_event_count = 0x3f0000;
}
if (perf_args.loop_type == LOOP_TYPE_VECTOR) {
perf_args.free_event = false;
if (perf_args.number_event_per_queue > 32)
APPL_EXIT_FAILURE("With vector loop max nbr of events per queue is 32\n");
}
}
static void
print_loop_options(void)
{
APPL_PRINT("EM loop options:\n");
APPL_PRINT(" Loop type: %s\n", get_loop_type_str(perf_args.loop_type));
APPL_PRINT(" Free: %s\n", perf_args.free_event ? "on" : "off");
APPL_PRINT(" Priorities: %s\n", perf_args.use_prio ? "on" : "off");
APPL_PRINT(" Data size: %d\n", perf_args.data_size);
APPL_PRINT(" EO count: %d\n", perf_args.number_eo);
APPL_PRINT(" Event amount: %d\n", perf_args.number_event_per_queue);
? "ATOMIC" : "PARALLEL");
APPL_PRINT(" print count: 0x%lx / (%ld)\n", perf_args.print_event_count,
perf_args.print_event_count);
if (perf_args.loop_type == LOOP_TYPE_MULTIRCV)
APPL_PRINT(" multi send: %d\n", perf_args.num_multi_events);
if (perf_args.loop_type == LOOP_TYPE_VECTOR)
APPL_PRINT(" vector size: %d\n", perf_args.vector_size);
}
static const char
*get_loop_type_str(uint32_t loop_type)
{
const char *type_str;
switch (loop_type) {
case LOOP_TYPE_UNDEF:
type_str = "UNDEF";
break;
case LOOP_TYPE_LOOP:
type_str = "LOOP";
break;
case LOOP_TYPE_VECTOR:
type_str = "VECTOR";
break;
case LOOP_TYPE_REFS:
type_str = "REFS";
break;
case LOOP_TYPE_MULTIRCV:
type_str = "MULTIRCV";
break;
case LOOP_TYPE_PAIRS:
type_str = "PAIRS";
break;
default:
type_str = "UNKNOWN";
break;
}
return type_str;
}
int main(int argc, char *argv[])
{
parse_app_specific_args(argc, argv);
if (perf_args.loop_type == LOOP_TYPE_MULTIRCV)
core_stat.events = 0;
else
core_stat.events = -perf_args.print_event_count;
return cm_setup(argc, argv);
}
void test_init(const appl_conf_t *appl_conf)
{
(void)appl_conf;
if (core == 0) {
perf_shm = env_shared_reserve("PerfSharedMem",
sizeof(perf_shm_t));
} else {
perf_shm = env_shared_lookup("PerfSharedMem");
}
if (perf_shm == NULL)
else if (core == 0)
memset(perf_shm, 0, sizeof(perf_shm_t));
}
void test_start(const appl_conf_t *appl_conf)
{
if (appl_conf->num_pools >= 1)
perf_shm->pool = appl_conf->pools[0];
else
APPL_PRINT("\n"
"***********************************************************\n"
"EM APPLICATION: '%s' initializing:\n"
" %s: %s() - EM-core:%d\n"
" Application running on %u EM-cores (procs:%u, threads:%u)\n"
"***********************************************************\n"
"\n",
appl_conf->name, NO_PATH(__FILE__), __func__,
em_core_id(),
appl_conf->core_count, appl_conf->num_procs, appl_conf->num_threads,
perf_shm->pool);
"Undefined application event pool!");
switch (perf_args.loop_type) {
case LOOP_TYPE_LOOP: {
em_queue_t queues[perf_args.number_eo];
em_eo_t eos[perf_args.number_eo];
create_queues_eos(perf_args.number_eo, queues, "loop-eo",
"queue A", 0, eos);
sync_to_queues_and_start_eos(queues, queues, 0, perf_args.number_eo, eos);
alloc_send_events(queues, perf_args.number_eo);
break;
}
case LOOP_TYPE_VECTOR: {
em_queue_t queues[perf_args.number_eo];
em_eo_t eos[perf_args.number_eo];
create_vector_pool();
create_queues_eos(perf_args.number_eo, queues, "loop-eo",
"queue A", 0, eos);
sync_to_queues_and_start_eos(queues, queues, 0, perf_args.number_eo, eos);
alloc_send_events_vector(queues);
break;
}
case LOOP_TYPE_MULTIRCV: {
em_queue_t queues[perf_args.number_eo];
em_eo_t eos[perf_args.number_eo];
create_queues_eos(perf_args.number_eo, queues, "loop-eo",
"queue A", 0, eos);
sync_to_queues_and_start_eos(queues, queues, 0, perf_args.number_eo, eos);
alloc_send_events_multircv(queues);
break;
}
case LOOP_TYPE_REFS: {
em_queue_t queues[perf_args.number_eo];
em_eo_t eos[perf_args.number_eo];
create_queues_eos(perf_args.number_eo, queues, "loop-eo",
"queue A", 0, eos);
sync_to_queues_and_start_eos(queues, queues, 0, perf_args.number_eo, eos);
alloc_send_events_ref(queues);
break;
}
case LOOP_TYPE_PAIRS: {
int half_num_eo = perf_args.number_eo / 2;
em_queue_t queues_a[half_num_eo];
em_queue_t queues_b[half_num_eo];
em_eo_t eos_a[half_num_eo];
em_eo_t eos_b[half_num_eo];
create_queues_eos(half_num_eo, queues_a, "pairs-eo-a",
"queue-A", 0, eos_a);
create_queues_eos(half_num_eo, queues_b, "pairs-eo-b",
"queue-B", half_num_eo, eos_b);
sync_to_queues_and_start_eos(queues_a, queues_b, 0, half_num_eo, eos_a);
sync_to_queues_and_start_eos(queues_b, queues_a, half_num_eo,
half_num_eo, eos_b);
alloc_send_events(queues_a, half_num_eo);
alloc_send_events(queues_b, half_num_eo);
break;
}
default:
break;
}
}
static void
send_burst(em_queue_t queue, em_event_t *events)
{
const int send_rounds = perf_args.number_event_per_queue
/ perf_args.num_multi_events;
const int left_over = perf_args.number_event_per_queue
% perf_args.num_multi_events;
int num_sent = 0;
int m, n;
for (m = 0, n = 0; m < send_rounds; m++, n += perf_args.num_multi_events) {
num_sent +=
em_send_multi(&events[n], perf_args.num_multi_events,
queue);
}
if (left_over) {
queue);
}
test_fatal_if(num_sent != perf_args.number_event_per_queue,
"Event send multi failed:%d (%d)\n"
num_sent, perf_args.number_event_per_queue, queue);
}
static void
alloc_send_events_ref(em_queue_t *queues)
{
em_event_t ev =
em_alloc(perf_args.data_size,
"Event allocation failed");
for (int i = 0; i < perf_args.number_eo; i++) {
em_queue_t queue = queues[i];
em_event_t events[perf_args.number_event_per_queue];
for (int j = 0; j < perf_args.number_event_per_queue; j++) {
"Event ref creation failed (%d, %d)", i, j);
events[j] = ref;
}
send_burst(queue, events);
}
env_sync_mem();
}
static void
alloc_send_events_multircv(em_queue_t *queues)
{
for (int i = 0; i < perf_args.number_eo; i++) {
em_queue_t queue = queues[i];
em_event_t events[perf_args.number_event_per_queue];
int num, tot = 0;
do {
perf_args.number_event_per_queue - tot,
perf_args.data_size,
tot += num;
} while (tot < num && num > 0);
test_fatal_if(tot != perf_args.number_event_per_queue,
"Allocated:%d of requested:%d events",
tot, perf_args.number_event_per_queue);
send_burst(queue, events);
}
env_sync_mem();
}
static void
alloc_send_events(em_queue_t *queues, uint32_t num_eos)
{
for (uint32_t i = 0; i < num_eos; i++) {
em_event_t ev;
em_queue_t queue = queues[i];
em_event_t events[perf_args.number_event_per_queue];
for (int j = 0; j < perf_args.number_event_per_queue; j++) {
"Event allocation failed (%d, %d)", i, j);
events[j] = ev;
}
send_burst(queue, events);
}
env_sync_mem();
}
static void
alloc_send_events_vector(em_queue_t *queues)
{
for (int i = 0; i < perf_args.number_eo; i++) {
em_event_t ev;
em_queue_t queue = queues[i];
em_event_t events[perf_args.number_event_per_queue];
for (int j = 0; j < perf_args.number_event_per_queue; j++) {
uint32_t vec_sz = (j % perf_args.vector_size) + 1;
perf_shm->vec_pool);
"Vector allocation failed (%d, %d)", i, j);
em_event_t *vectbl = NULL;
test_fatal_if(curr_sz || !vectbl,
"Vector table invalid: sz=%d vectbl=%p)",
curr_sz, vectbl);
for (uint32_t k = 0; k < vec_sz; k++) {
"Event allocation failed (%d, %d)", i, j);
vectbl[k] = ev;
}
events[j] = vec;
}
send_burst(queue, events);
}
env_sync_mem();
}
static void
create_vector_pool(void)
{
vec_pool_cfg.
subpool[0].
num = perf_args.number_eo * perf_args.number_event_per_queue;
test_fatal_if(vec_pool ==
EM_POOL_UNDEF,
"vector pool create failed!");
perf_shm->vec_pool = vec_pool;
}
static void
create_queues_eos(uint32_t num_of_eos, em_queue_t *queues,
const char *eo_name, const char *queue_name,
uint8_t shift_eo_ctx_tbl, em_eo_t *eos)
{
em_queue_t queue;
eo_context_t *eo_ctx;
em_eo_t eo;
for (uint32_t i = 0; i < num_of_eos; i++) {
get_queue_priority(i),
"Queue creation failed, round:%d", i);
queues[i] = queue;
switch (perf_args.loop_type) {
case LOOP_TYPE_MULTIRCV:
eo_param.
start = perf_start;
eo_param.
stop = perf_stop;
if (perf_args.free_event)
else
break;
case LOOP_TYPE_PAIRS:
if (perf_args.free_event)
recv_fn = perf_receive_pairs_free;
else
recv_fn = perf_receive_pairs;
eo_ctx = &perf_shm->eo_ctx_tbl[i + shift_eo_ctx_tbl];
eo =
em_eo_create(eo_name, perf_start, NULL, perf_stop, NULL,
recv_fn, eo_ctx);
break;
case LOOP_TYPE_LOOP:
case LOOP_TYPE_VECTOR:
case LOOP_TYPE_REFS:
if (perf_args.free_event)
recv_fn = perf_receive_free;
else
recv_fn = perf_receive;
eo_ctx = &perf_shm->eo_ctx_tbl[i + shift_eo_ctx_tbl];
eo =
em_eo_create(eo_name, perf_start, NULL, perf_stop, NULL,
recv_fn, eo_ctx);
break;
default:
}
"EO(%d) creation failed!", i);
eos[i] = eo;
}
}
static void
sync_to_queues_and_start_eos(em_queue_t *queues, em_queue_t *target_queues,
uint32_t offset, uint32_t num_of_eos, em_eo_t *eos)
{
for (uint32_t i = 0; i < num_of_eos; i++) {
eo_context_t *eo_ctx = &perf_shm->eo_ctx_tbl[i + offset];
eo_ctx->dest = target_queues[i];
perf_shm->eo_tbl[i + offset] = eos[i];
test_fatal_if(ret !=
EM_OK,
"EO add queue:%" PRI_STAT "\n"
ret, eos[i], queues[i]);
"EO start:%" PRI_STAT " %" PRI_STAT "",
ret, start_ret);
}
}
void test_stop(const appl_conf_t *appl_conf)
{
em_eo_t eo;
int i;
(void)appl_conf;
APPL_PRINT("%s() on EM-core %d\n", __func__, core);
for (i = 0; i < perf_args.number_eo; i++) {
eo = perf_shm->eo_tbl[i];
test_fatal_if(ret !=
EM_OK,
"EO:%" PRI_EO " stop:%" PRI_STAT
"", eo, ret);
test_fatal_if(ret !=
EM_OK,
"EO:%" PRI_EO " delete:%" PRI_STAT
"", eo, ret);
}
if (perf_args.loop_type == LOOP_TYPE_VECTOR)
}
void test_term(const appl_conf_t *appl_conf)
{
(void)appl_conf;
APPL_PRINT("%s() on EM-core %d\n", __func__, core);
if (core == 0) {
env_shared_free(perf_shm);
}
}
perf_start(
void *eo_context, em_eo_t eo,
const em_eo_conf_t *conf)
{
(void)eo_context;
(void)eo;
(void)conf;
}
perf_stop(void *eo_context, em_eo_t eo)
{
(void)eo_context;
test_fatal_if(ret !=
EM_OK,
"EO remove queue all:%" PRI_STAT
" EO:%" PRI_EO "",
ret, eo);
return ret;
}
static inline void send_event(em_event_t event, em_queue_t queue)
{
if (unlikely(ret !=
EM_OK)) {
test_fatal_if(!appl_shm->exit_flag,
ret, queue);
}
}
{
em_event_t
event =
em_alloc(data_size, type, perf_shm->pool);
return event;
}
static inline void start_measurement(void)
{
core_stat.begin_cycles = env_get_cycle();
}
static inline void end_measurement(void)
{
core_stat.end_cycles = env_get_cycle();
core_stat.print_count += 1;
print_result(&core_stat);
}
static inline void restart_measurement(int64_t *events)
{
*events = -1;
}
static void
em_queue_t queue, void *queue_context)
{
int64_t events = core_stat.events;
(void)eo_context;
(void)type;
(void)queue_context;
if (unlikely(appl_shm->exit_flag)) {
return;
}
if (unlikely(events == 0)) {
start_measurement();
} else if (unlikely(events == perf_args.print_event_count)) {
end_measurement();
restart_measurement(&events);
}
send_event(event, queue);
events++;
core_stat.events = events;
}
static void
perf_receive_free(
void *eo_context, em_event_t event,
em_event_type_t type,
em_queue_t queue, void *queue_context)
{
int64_t events = core_stat.events;
(void)eo_context;
(void)type;
(void)queue_context;
if (unlikely(appl_shm->exit_flag)) {
return;
}
if (unlikely(events == 0)) {
start_measurement();
} else if (unlikely(events == perf_args.print_event_count)) {
end_measurement();
restart_measurement(&events);
}
event = alloc_event(perf_args.data_size, type);
send_event(event, queue);
events++;
core_stat.events = events;
}
static void
perf_receive_pairs(
void *eo_context, em_event_t event,
em_event_type_t type,
em_queue_t queue, void *queue_context)
{
int64_t events = core_stat.events;
eo_context_t *const eo_ctx = eo_context;
const em_queue_t dst_queue = eo_ctx->dest;
(void)type;
(void)queue;
(void)queue_context;
if (unlikely(appl_shm->exit_flag)) {
return;
}
if (unlikely(events == 0)) {
start_measurement();
} else if (unlikely(events == perf_args.print_event_count)) {
end_measurement();
restart_measurement(&events);
}
send_event(event, dst_queue);
events++;
core_stat.events = events;
}
static void
perf_receive_pairs_free(
void *eo_context, em_event_t event,
em_event_type_t type,
em_queue_t queue, void *queue_context)
{
int64_t events = core_stat.events;
eo_context_t *const eo_ctx = eo_context;
const em_queue_t dst_queue = eo_ctx->dest;
(void)type;
(void)queue;
(void)queue_context;
if (unlikely(appl_shm->exit_flag)) {
return;
}
if (unlikely(events == 0)) {
start_measurement();
} else if (unlikely(events == perf_args.print_event_count)) {
end_measurement();
restart_measurement(&events);
}
event = alloc_event(perf_args.data_size, type);
send_event(event, dst_queue);
events++;
core_stat.events = events;
}
static void
perf_receive_multi(void *eo_context, em_event_t event_tbl[], int num,
em_queue_t queue, void *queue_context)
{
int64_t event_count = core_stat.events;
int ret;
(void)eo_context;
(void)queue_context;
if (unlikely(appl_shm->exit_flag)) {
return;
}
if (unlikely(event_count == 0)) {
start_measurement();
} else if (unlikely(event_count >= perf_args.print_event_count)) {
end_measurement();
event_count = -num;
}
if (unlikely(ret != num)) {
test_fatal_if(!appl_shm->exit_flag,
ret, num, queue);
}
event_count += num;
core_stat.events = event_count;
}
static void
perf_receive_multi_free(void *eo_context, em_event_t event_tbl[], int num,
em_queue_t queue, void *queue_context)
{
int64_t event_count = core_stat.events;
int ret;
(void)eo_context;
(void)queue_context;
if (unlikely(appl_shm->exit_flag)) {
return;
}
if (unlikely(event_count == 0)) {
start_measurement();
} else if (unlikely(event_count >= perf_args.print_event_count)) {
end_measurement();
event_count = -num;
}
test_fatal_if(ret != num, "Allocated %d of num:%d events",
ret, num);
if (unlikely(ret != num)) {
test_fatal_if(!appl_shm->exit_flag,
ret, num, queue);
}
event_count += num;
core_stat.events = event_count;
}
get_queue_priority(const int queue_index)
{
if (perf_args.use_prio) {
int remainder = queue_index % 5;
if (remainder <= 1)
else if (remainder <= 3)
else
} else {
}
return prio;
}
static void
print_result(perf_stat_t *const perf_stat)
{
uint64_t diff;
uint32_t hz;
double mhz;
double cycles_per_event, events_per_sec;
uint64_t print_count;
hz = env_core_hz();
mhz = ((double)hz) / 1000000.0;
diff = env_cycles_diff(perf_stat->end_cycles, perf_stat->begin_cycles);
print_count = perf_stat->print_count;
cycles_per_event = ((double)diff) / ((double)perf_stat->events);
events_per_sec = mhz / cycles_per_event;
APPL_PRINT(RESULT_PRINTF_FMT, cycles_per_event, events_per_sec,
}
#define EM_QUEUE_GROUP_DEFAULT
#define EM_ERROR_SET_FATAL(error)
em_status_t em_eo_remove_queue_all_sync(em_eo_t eo, int delete_queues)
em_eo_t em_eo_create(const char *name, em_start_func_t start, em_start_local_func_t local_start, em_stop_func_t stop, em_stop_local_func_t local_stop, em_receive_func_t receive, const void *eo_ctx)
void(* em_receive_func_t)(void *eo_ctx, em_event_t event, em_event_type_t type, em_queue_t queue, void *q_ctx)
em_status_t em_eo_start_sync(em_eo_t eo, em_status_t *result, const em_eo_conf_t *conf)
void em_eo_multircv_param_init(em_eo_multircv_param_t *param)
em_status_t em_eo_add_queue_sync(em_eo_t eo, em_queue_t queue)
em_status_t em_eo_stop_sync(em_eo_t eo)
em_status_t em_eo_delete(em_eo_t eo)
em_eo_t em_eo_create_multircv(const char *name, const em_eo_multircv_param_t *param)
em_status_t em_unregister_error_handler(void)
em_status_t em_register_error_handler(em_error_handler_t handler)
uint32_t em_event_vector_tbl(em_event_t vector_event, em_event_t **event_tbl)
Get the event vector table from an event of (major) type EM_EVENT_TYPE_VECTOR.
int em_send_multi(const em_event_t events[], int num, em_queue_t queue)
int em_alloc_multi(em_event_t events[], int num, uint32_t size, em_event_type_t type, em_pool_t pool)
em_event_t em_event_ref(em_event_t event)
em_event_t em_alloc(uint32_t size, em_event_type_t type, em_pool_t pool)
void em_free_multi(em_event_t events[], int num)
void em_event_vector_size_set(em_event_t vector_event, uint32_t size)
Set the number of event handles stored in a vector.
em_status_t em_send(em_event_t event, em_queue_t queue)
void em_free(em_event_t event)
em_pool_t em_pool_create(const char *name, em_pool_t pool, const em_pool_cfg_t *pool_cfg)
void em_pool_cfg_init(em_pool_cfg_t *const pool_cfg)
em_status_t em_pool_delete(em_pool_t pool)
em_queue_t em_queue_create(const char *name, em_queue_type_t type, em_queue_prio_t prio, em_queue_group_t group, const em_queue_conf_t *conf)
em_receive_multi_func_t receive_multi
em_event_type_t event_type
struct em_pool_cfg_t::@11 subpool[EM_MAX_SUBPOOLS]