#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "cm_setup.h"
#include "cm_error_handler.h"
#define APPL_ESCOPE_INIT 1
#define APPL_ESCOPE_OTHER 2
#define APPL_ESCOPE_STR 3
#define APPL_ESCOPE_STR_Q 4
#define APPL_ESCOPE_STR_Q_SEQ 5
#define DELAY_SPIN_COUNT 50000000
#define TEST_ERROR_FATAL EM_ERROR_SET_FATAL(0xdead)
#define TEST_ERROR_1 0x1111
#define TEST_ERROR_2 0x2222
#define TEST_ERROR_3 0x3333
#define TEST_ERROR_4 0x4444
typedef struct {
em_queue_t dest;
unsigned int seq;
int fatal;
} error_event_t;
typedef union {
struct {
em_eo_t eo;
char name[16];
};
} eo_context_t;
typedef struct {
em_pool_t pool;
em_queue_t queue_b;
em_queue_t queue_c;
} error_shm_t;
error_start(
void *eo_context, em_eo_t eo,
const em_eo_conf_t *conf);
error_stop(void *eo_context, em_eo_t eo);
static void
em_queue_t queue, void *q_ctx);
va_list args);
va_list args);
combined_error_handler(
const char *handler_name, em_eo_t eo,
em_status_t error,
int main(int argc, char *argv[])
{
return cm_setup(argc, argv);
}
void test_init(const appl_conf_t *appl_conf)
{
(void)appl_conf;
if (core == 0)
error_shm = env_shared_reserve("ErrorSharedMem",
sizeof(error_shm_t));
else
error_shm = env_shared_lookup("ErrorSharedMem");
if (error_shm == NULL)
"Error init failed on EM-core: %u\n",
em_core_id());
else if (core == 0)
memset(error_shm, 0, sizeof(error_shm_t));
}
void test_start(const appl_conf_t *appl_conf)
{
em_eo_t eo;
em_event_t event;
em_queue_t queue;
error_event_t *error;
if (appl_conf->num_pools >= 1)
error_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,
error_shm->pool);
test_fatal_if(ret !=
EM_OK,
"Register global error handler:%" PRI_STAT "", ret);
eo =
em_eo_create(
"EO A", error_start, NULL, error_stop, NULL,
error_receive, &error_shm->eo_error_a);
NULL);
test_fatal_if(ret !=
EM_OK,
"EO add queue:%" PRI_STAT ".\n"
ret, eo, queue);
error_shm->eo_error_a.eo = eo;
error_shm->queue_a = queue;
test_fatal_if(ret !=
EM_OK,
"Register EO error handler:%" PRI_STAT "", ret);
"EO A start:%" PRI_STAT " %" PRI_STAT "");
eo =
em_eo_create(
"EO B", error_start, NULL, error_stop, NULL,
error_receive, &error_shm->eo_error_b);
NULL);
test_fatal_if(ret !=
EM_OK,
"EO add queue:%" PRI_STAT ".\n"
ret, eo, queue);
error_shm->eo_error_b.eo = eo;
error_shm->queue_b = queue;
"EO B start:%" PRI_STAT " %" PRI_STAT "");
eo =
em_eo_create(
"EO C", error_start, NULL, error_stop, NULL,
error_receive, &error_shm->eo_error_c);
NULL);
test_fatal_if(ret !=
EM_OK,
"EO add queue:%" PRI_STAT ".\n"
ret, eo, queue);
error_shm->eo_error_c.eo = eo;
error_shm->queue_c = queue;
"EO C start:%" PRI_STAT " %" PRI_STAT "");
error_shm->pool);
error->dest = error_shm->queue_b;
error->seq = 0;
error->fatal = 0;
ret =
em_send(event, error_shm->queue_a);
test_fatal_if(ret !=
EM_OK,
"Send:%" PRI_STAT
" Queue:%" PRI_QUEUE "",
ret, error_shm->queue_a);
error_shm->pool);
error->seq = 0;
error->fatal = 1;
ret =
em_send(event, error_shm->queue_c);
test_fatal_if(ret !=
EM_OK,
"Send:%" PRI_STAT
" Queue:%" PRI_QUEUE "",
ret, error_shm->queue_c);
}
void test_stop(const appl_conf_t *appl_conf)
{
const em_eo_t eo_a = error_shm->eo_error_a.eo;
const em_eo_t eo_b = error_shm->eo_error_b.eo;
const em_eo_t eo_c = error_shm->eo_error_c.eo;
(void)appl_conf;
APPL_PRINT("%s() on EM-core %d\n", __func__, core);
APPL_EXIT_FAILURE("EO A stop failed!");
APPL_EXIT_FAILURE("EO B stop failed!");
APPL_EXIT_FAILURE("EO C stop failed!");
APPL_EXIT_FAILURE("EO A unregister error handler failed!");
APPL_EXIT_FAILURE("EO A delete failed!");
APPL_EXIT_FAILURE("EO B delete failed!");
APPL_EXIT_FAILURE("EO C delete failed!");
APPL_EXIT_FAILURE("Unregister error handler failed!");
}
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(error_shm);
fflush(NULL);
}
va_list args)
{
return combined_error_handler("Appl EO specific error handler",
eo, error, escope, args);
}
va_list args)
{
return combined_error_handler("Appl Global error handler ",
eo, error, escope, args);
}
combined_error_handler(
const char *handler_name, em_eo_t eo,
em_status_t error,
{
em_queue_t queue;
const char *str;
unsigned int seq;
char error_str[512];
error, escope, args);
APPL_PRINT(
"%s: EO %" PRI_EO " error 0x%" PRIxSTAT
" escope 0x%X\n"
"- EM info: %s",
handler_name, eo, error, escope, error_str);
abort();
return error;
}
if (error == TEST_ERROR_FATAL) {
APPL_PRINT("THIS IS A FATAL ERROR!!\n"
"%s: EO %" PRI_EO " error 0x%" PRIxSTAT
" escope 0x%X\n"
"Return from fatal.\n\n",
handler_name, eo, error, escope);
return error;
}
APPL_PRINT(
"%s: EO %" PRI_EO " error 0x%" PRIxSTAT
" escope 0x%X\n",
handler_name, eo, error, escope);
abort();
}
switch (escope) {
case APPL_ESCOPE_STR:
str = va_arg(args, const char*);
APPL_PRINT(
"%s: EO %" PRI_EO " error 0x%" PRIxSTAT
" escope 0x%X\t"
"ARGS: %s\n", handler_name, eo, error,
escope, str);
break;
case APPL_ESCOPE_STR_Q:
str = va_arg(args, const char*);
queue = va_arg(args, em_queue_t);
APPL_PRINT(
"%s: EO %" PRI_EO " error 0x%" PRIxSTAT
" escope 0x%X\t"
eo, error, escope, str, queue);
break;
case APPL_ESCOPE_STR_Q_SEQ:
str = va_arg(args, const char*);
queue = va_arg(args, em_queue_t);
seq = va_arg(args, unsigned int);
APPL_PRINT(
"%s: EO %" PRI_EO " error 0x%" PRIxSTAT
" escope 0x%X\t"
"ARGS: %s %" PRI_QUEUE " %u\n", handler_name,
eo, error, escope, str, queue, seq);
break;
case APPL_ESCOPE_OTHER:
APPL_PRINT(
"%s: EO %" PRI_EO " error 0x%" PRIxSTAT
" escope 0x%X\n",
handler_name, eo, error, escope);
break;
default:
APPL_PRINT("%s: Unexpected Application Error:\n"
" EO %" PRI_EO " error 0x%" PRIxSTAT
" escope 0x%X\n",
handler_name, eo, error, escope);
abort();
};
return error;
}
static void
em_queue_t queue, void *q_ctx)
{
em_queue_t dest;
eo_context_t *eo_ctx = eo_context;
error_event_t *errev;
unsigned int seq;
(void)type;
(void)q_ctx;
if (unlikely(appl_shm->exit_flag)) {
return;
}
dest = errev->dest;
errev->dest = queue;
if (errev->fatal) {
APPL_PRINT("\nError log from %s [%u] on core %i!\n",
em_error(TEST_ERROR_FATAL, APPL_ESCOPE_OTHER);
return;
}
APPL_PRINT("Error log from %s [%u] on core %i!\n", eo_ctx->name,
em_error(TEST_ERROR_1, APPL_ESCOPE_OTHER);
em_error(TEST_ERROR_2, APPL_ESCOPE_STR,
"Second error");
em_error(TEST_ERROR_3, APPL_ESCOPE_STR_Q,
"Third error", queue);
em_error(TEST_ERROR_4, APPL_ESCOPE_STR_Q_SEQ,
"Fourth error",
queue, errev->seq);
errev->seq++;
seq = errev->seq;
delay_spin(DELAY_SPIN_COUNT);
if (unlikely(ret !=
EM_OK)) {
test_fatal_if(!appl_shm->exit_flag,
ret, dest);
return;
}
if ((seq & 0x7) == 0x7) {
error_shm->pool);
errev->seq = 0;
errev->fatal = 1;
ret =
em_send(event, error_shm->queue_c);
if (unlikely(ret !=
EM_OK)) {
test_fatal_if(!appl_shm->exit_flag,
ret, error_shm->queue_c);
return;
}
}
}
error_start(
void *eo_context, em_eo_t eo,
const em_eo_conf_t *conf)
{
eo_context_t *eo_ctx = eo_context;
(void)conf;
APPL_PRINT(
"Error test start (%s, eo id %" PRI_EO ")\n",
eo_ctx->name, eo);
}
error_stop(void *eo_context, em_eo_t eo)
{
(void)eo_context;
APPL_PRINT(
"Error test stop function (EO:%" PRI_EO ")\n", eo);
APPL_EXIT_FAILURE(
"EO:%" PRI_EO " rem all queues failed!", eo);
}