#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include "cm_setup.h"
#include "cm_error_handler.h"
#define APP_MAX_TEXT_LEN 128
#define APP_TIMEOUT_MODULO_MS 30000
#define APP_TIMEOUT_MIN_MS 100
#define APP_PERIOD_MS 1000
#define APP_EO_NAME "Control EO"
typedef enum app_cmd_t {
APP_CMD_TMO,
APP_CMD_HELLO
} app_cmd_t;
typedef struct app_msg_t {
app_cmd_t command;
uint64_t count;
char text[APP_MAX_TEXT_LEN];
} app_msg_t;
typedef struct app_eo_ctx_t {
em_queue_t my_q;
uint64_t hz;
} app_eo_ctx_t;
typedef struct timer_app_shm_t {
em_pool_t pool;
app_eo_ctx_t eo_context;
em_queue_t eo_q;
em_timer_t tmr;
} timer_app_shm_t;
static em_status_t app_eo_start(app_eo_ctx_t *eo_ctx, em_eo_t eo,
static em_status_t app_eo_start_local(app_eo_ctx_t *eo_ctx, em_eo_t eo);
static em_status_t app_eo_stop(app_eo_ctx_t *eo_ctx, em_eo_t eo);
static void app_eo_receive(app_eo_ctx_t *eo_ctx, em_event_t event,
void *q_ctx);
static void new_rand_timeout(app_eo_ctx_t *eo_ctx);
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) {
m_shm = env_shared_reserve("TimerAppShMem",
sizeof(timer_app_shm_t));
} else {
m_shm = env_shared_lookup("TimerAppShMem");
}
if (m_shm == NULL) {
"init failed on EM-core: %u",
} else if (core == 0) {
memset(m_shm, 0, sizeof(timer_app_shm_t));
}
}
void test_start(const appl_conf_t *appl_conf)
{
em_eo_t eo;
em_queue_t queue;
em_event_t event;
app_msg_t *msg;
app_eo_ctx_t *eo_ctx;
uint64_t period;
if (appl_conf->num_pools >= 1)
m_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,
m_shm->pool);
"Undefined application event pool!");
&m_shm->eo_context);
test_fatal_if(eo ==
EM_EO_UNDEF,
"Failed to create EO!");
eo_ctx = &m_shm->eo_context;
test_fatal_if(stat !=
EM_OK,
"Failed to create queue!");
m_shm->eo_q = queue;
strncpy(attr.
name,
"ExampleTimer", EM_TIMER_NAME_LEN);
test_fatal_if(m_shm->tmr ==
EM_TIMER_UNDEF,
"Failed to create timer!");
test_fatal_if(stat !=
EM_OK,
"Failed to start EO!");
eo_ctx->my_q);
test_fatal_if(eo_ctx->periodic_tmo ==
EM_TMO_UNDEF,
"Can't allocate tmo!\n");
msg->command = APP_CMD_TMO;
msg->tmo = eo_ctx->periodic_tmo;
msg->count = 0;
if (eo_ctx->hz < 1000) {
APPL_ERROR("WARNING - timer hz very low!\n");
}
eo_ctx->my_q);
test_fatal_if(eo_ctx->random_tmo ==
EM_TMO_UNDEF,
"Can't allocate tmo!\n");
period = eo_ctx->hz / 1000;
period *= APP_PERIOD_MS;
test_fatal_if(stat !=
EM_OK,
"Can't activate tmo!\n");
}
void test_stop(const appl_conf_t *appl_conf)
{
em_eo_t eo;
(void)appl_conf;
APPL_PRINT("%s() on EM-core %d\n", __func__, core);
test_fatal_if(eo ==
EM_EO_UNDEF,
"Could not find EO:%s", APP_EO_NAME);
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);
test_fatal_if(ret !=
EM_OK,
"Timer:%" PRI_TMR " delete:%" PRI_STAT
"",
m_shm->tmr, ret);
}
void test_term(const appl_conf_t *appl_conf)
{
(void)appl_conf;
APPL_PRINT("%s() on EM-core %d\n", __func__, core);
if (m_shm != NULL) {
env_shared_free(m_shm);
m_shm = NULL;
}
}
static em_status_t app_eo_start(app_eo_ctx_t *eo_ctx, em_eo_t eo,
{
em_timer_t tmr;
int num_timers;
(void)eo;
(void)conf;
APPL_PRINT("EO start\n");
APPL_PRINT("System has %d timer(s)\n", num_timers);
APPL_ERROR("Can't get timer info!\n");
}
APPL_PRINT(
"Timer \"%s\" info:\n", attr.
name);
APPL_PRINT(
" -num_tmo: %d\n", attr.
num_tmo);
APPL_PRINT(" -tick Hz: %" PRIu64 " hz\n",
eo_ctx->my_q = m_shm->eo_q;
}
static em_status_t app_eo_start_local(app_eo_ctx_t *eo_ctx, em_eo_t eo)
{
(void)eo_ctx;
(void)eo;
APPL_PRINT("EO local start\n");
}
static em_status_t app_eo_stop(app_eo_ctx_t *eo_ctx, em_eo_t eo)
{
APPL_PRINT("EO stop\n");
}
}
test_fatal_if(ret !=
EM_OK,
"EO remove queue all:%" PRI_STAT
" EO:%" PRI_EO "",
ret, eo);
}
static void app_eo_receive(app_eo_ctx_t *eo_ctx, em_event_t event,
void *q_ctx)
{
int reuse = 0;
(void)queue;
(void)q_ctx;
if (unlikely(appl_shm->exit_flag)) {
return;
}
switch (msgin->command) {
case APP_CMD_TMO:
msgin->count++;
if (msgin->count & 1)
APPL_PRINT("%" PRIu64 ". ",
(msgin->count / 2) + 1);
APPL_PRINT((msgin->count & 1) ? "tick\n" : "tock\n");
test_fatal_if(ret !=
EM_OK,
"em_tmo_ack():%" PRI_STAT, ret);
reuse = 1;
if (msgin->count == 10)
new_rand_timeout(eo_ctx);
break;
case APP_CMD_HELLO:
APPL_PRINT("%s\n\n", msgin->text);
new_rand_timeout(eo_ctx);
break;
default:
"Invalid event!\n");
}
} else {
"Invalid event type!\n");
}
if (!reuse)
}
void new_rand_timeout(app_eo_ctx_t *eo_ctx)
{
int rnd;
app_msg_t *msg;
uint64_t period;
m_shm->pool);
if (!event) {
"Can't allocate event!");
}
msg->command = APP_CMD_HELLO;
do {
rnd = rand_r(&m_randseed);
rnd %= APP_TIMEOUT_MODULO_MS;
} while (rnd < APP_TIMEOUT_MIN_MS);
snprintf(msg->text, APP_MAX_TEXT_LEN, "%d ms gone!\n", rnd);
msg->text[APP_MAX_TEXT_LEN - 1] = 0;
APPL_PRINT("Meditation time: what can you do in %d ms?\n", rnd);
period = eo_ctx->hz / 1000;
period *= rnd;
if (rnd > (APP_TIMEOUT_MODULO_MS + APP_TIMEOUT_MIN_MS) / 2)
else
period, event);
"Can't activate tmo!\n");
}