blob: bfbed5768b0491dfab71a26ba9ee98a4a158af33 [file] [log] [blame]
// --------------------------------------------------------
// Code generated by Papyrus C++
// --------------------------------------------------------
#define SimpleSM_classes_SimpleSM_BODY
/************************************************************
SimpleSM class body
************************************************************/
// include associated header file
#include "SimpleSM/classes/SimpleSM.h"
// Derived includes directives
#include "statemachine/Event_t.h"
#include "statemachine/Pkg_statemachine.h"
#include "sysinterfaces/IStart.h"
// Include from Include declaration (body)
#include <iostream>
using namespace std;
#include <unistd.h>
// End of Include declaration (body)
namespace SimpleSM {
namespace classes {
// static attributes (if any)
/**
*
*/
void SimpleSM::dispatchEvent() {
bool popDeferred = false;
while (true) {
//run-to-completion: need to have a mutex here
currentEvent = eventQueue.pop(popDeferred);
dispatchFlag = true;
if (currentEvent != NULL) {
SIMPLESM_GET_CONTROL
switch (currentEvent->eventID) {
case TE_VALUE_250_UNIT_MS__ID:
processTE_value_250_unit_ms_();
break;
case TE_VALUE_500_UNIT_MS__ID:
processTE_value_500_unit_ms_();
break;
case COMPLETIONEVENT_ID:
processCompletionEvent();
break;
}
if (systemState == statemachine::EVENT_DEFERRED) {
eventQueue.saveDeferred(*currentEvent);
}
popDeferred = (systemState != statemachine::EVENT_DEFERRED);
systemState = statemachine::IDLE;
SIMPLESM_RELEASE_CONTROL
}
}
}
/**
*
* @param a
* @param b
* @return res
*/
::PrimitiveTypes::Integer SimpleSM::add(::PrimitiveTypes::Integer /*in*/a,
::PrimitiveTypes::Integer /*in*/b) {
this->processCE_CServer_impl_add(a, b);
// original method code
cout << "a=" << a << " b=" << b << " a+b=" << a + b << endl;
return a + b;
}
/**
*
*/
void SimpleSM::run() {
cout << "call add (2, 3);" << endl;
cout << "result: " << add(2, 3) << endl;
cout << "sleeping for 15 seconds (statemachine remains active);" << endl;
sleep(15);
}
/**
*
* @param enter_mode
*/
void SimpleSM::SMSimple_Region0_Enter(char /*in*/enter_mode) {
switch (enter_mode) {
case SMSIMPLE_REGION0_DEFAULT:
activeStateID = FLIP_ID;
setFlag(SIMPLESM_TE_INDEX(TE_VALUE_250_UNIT_MS__ID),
statemachine::TF_TIME_EVENT, true);
//TODO: set systemState to EVENT_CONSUMED
break;
}
}
/**
*
*/
SimpleSM::SimpleSM() {
startBehavior();
}
/**
*
*/
void SimpleSM::startBehavior() {
systemState = statemachine::IDLE;
doActivityTable[FLIP_ID] = states[FLIP_ID].doActivity;
doActivityTable[FLOP_ID] = states[FLOP_ID].doActivity;
// initialize all threads, the threads wait until the associated flag is set
for (int i = 0; i < (int) STATE_MAX; i++) {
if (states[i].doActivity != &SimpleSM::doActivity_dft) {
threadStructs[i].id = i;
threadStructs[i].ptr = this;
threadStructs[i].func_type = statemachine::TF_DO_ACTIVITY;
mutexes[i] = PTHREAD_MUTEX_INITIALIZER;
conds[i] = PTHREAD_COND_INITIALIZER;
pthread_create(&threads[i], NULL, &SimpleSM::thread_func_wrapper,
&threadStructs[i]);
}
}
timeEventThreadStructs[SIMPLESM_TE_INDEX(TE_VALUE_250_UNIT_MS__ID)].duration =
250;
timeEventThreadStructs[SIMPLESM_TE_INDEX(TE_VALUE_500_UNIT_MS__ID)].duration =
500;
for (int i = SIMPLESM_TIME_EVENT_LOWER_BOUND; i < 2; i++) {
timeEventThreadStructs[SIMPLESM_TE_INDEX(i)].id = i;
timeEventThreadStructs[SIMPLESM_TE_INDEX(i)].ptr = this;
timeEventThreadStructs[SIMPLESM_TE_INDEX(i)].func_type =
statemachine::TF_TIME_EVENT;
timeEventMutexes[SIMPLESM_TE_INDEX(i)] = PTHREAD_MUTEX_INITIALIZER;
timeEventConds[SIMPLESM_TE_INDEX(i)] = PTHREAD_COND_INITIALIZER;
pthread_create(&timeEventThreads[SIMPLESM_TE_INDEX(i)], NULL,
&SimpleSM::thread_func_wrapper,
&timeEventThreadStructs[SIMPLESM_TE_INDEX(i)]);
while (timeEventFlags[SIMPLESM_TE_INDEX(i)]) {
}
}
runToCompletionMutex = PTHREAD_MUTEX_INITIALIZER;
runToCompletionCond = PTHREAD_COND_INITIALIZER;
dispatchStruct = statemachine::StructForThread_t(this, 0, 0,
statemachine::TF_STATE_MACHINE_TYPE, 0);
SimpleSM_THREAD_CREATE(dispatchThread, dispatchStruct)
while (!dispatchFlag) {
}
//initialze root active state
//execute initial effect
SMSimple_Region0_Enter (SMSIMPLE_REGION0_DEFAULT);
}
/**
*
* @param a
* @param b
*/
void SimpleSM::processCE_CServer_impl_add(::PrimitiveTypes::Integer /*in*/a,
::PrimitiveTypes::Integer /*in*/b) {
SIMPLESM_GET_CONTROL systemState = statemachine::EVENT_PROCESSING;
if (systemState == statemachine::EVENT_PROCESSING) {
switch (activeStateID) {
case FLIP_ID:
//from Flip to Flop
if (true) {
setFlag(SIMPLESM_TE_INDEX(TE_VALUE_250_UNIT_MS__ID),
statemachine::TF_TIME_EVENT, false);
activeStateID = FLOP_ID;
//starting the counters for time events
setFlag(SIMPLESM_TE_INDEX(TE_VALUE_500_UNIT_MS__ID),
statemachine::TF_TIME_EVENT, true);
systemState = statemachine::EVENT_CONSUMED;
}
break;
default:
//do nothing
break;
}
}
SIMPLESM_RELEASE_CONTROL
}
/**
*
*/
void SimpleSM::processTE_value_250_unit_ms_() {
systemState = statemachine::EVENT_PROCESSING;
if (systemState == statemachine::EVENT_PROCESSING) {
switch (activeStateID) {
case FLIP_ID:
//from Flip to Flop
if (true) {
setFlag(SIMPLESM_TE_INDEX(TE_VALUE_250_UNIT_MS__ID),
statemachine::TF_TIME_EVENT, false);
std::cout << "From Flip to Flop" << std::endl;
activeStateID = FLOP_ID;
//starting the counters for time events
setFlag(SIMPLESM_TE_INDEX(TE_VALUE_500_UNIT_MS__ID),
statemachine::TF_TIME_EVENT, true);
systemState = statemachine::EVENT_CONSUMED;
}
break;
default:
//do nothing
break;
}
}
}
/**
*
*/
void SimpleSM::processTE_value_500_unit_ms_() {
systemState = statemachine::EVENT_PROCESSING;
if (systemState == statemachine::EVENT_PROCESSING) {
switch (activeStateID) {
case FLOP_ID:
//from Flop to Flip
if (true) {
setFlag(SIMPLESM_TE_INDEX(TE_VALUE_500_UNIT_MS__ID),
statemachine::TF_TIME_EVENT, false);
std::cout << "From Flop to Flip" << std::endl;
activeStateID = FLIP_ID;
//starting the counters for time events
setFlag(SIMPLESM_TE_INDEX(TE_VALUE_250_UNIT_MS__ID),
statemachine::TF_TIME_EVENT, true);
systemState = statemachine::EVENT_CONSUMED;
}
break;
default:
//do nothing
break;
}
}
}
/**
*
*/
void SimpleSM::processCompletionEvent() {
systemState = statemachine::EVENT_PROCESSING;
}
/**
*
* @param data
* @return ret
*/
void* SimpleSM::thread_func_wrapper(void* /*in*/data) {
statemachine::StructForThread_t* cptr =
(statemachine::StructForThread_t*) data;
SimpleSM* ptr = (SimpleSM*) cptr->ptr;
switch (cptr->func_type) {
case statemachine::TF_TIME_EVENT:
ptr->listenTimeEvent(SIMPLESM_TE_INDEX(cptr->id), cptr->duration);
break;
case statemachine::TF_STATE_MACHINE_TYPE:
ptr->dispatchEvent();
break;
}
return NULL;
}
/**
*
* @param id
*/
void SimpleSM::doCallActivity(int /*in*/id) {
flags[id] = false;
while (true) {
pthread_mutex_lock (&mutexes[id]);
while (!flags[id]) {
pthread_cond_wait(&conds[id], &mutexes[id]);
}
(this->*doActivityTable[id])();
bool commitEvent = false;
if (flags[id]) {
commitEvent = true;
flags[id] = false;
}
pthread_cond_signal (&conds[id]);
pthread_mutex_unlock(&mutexes[id]);
}
}
/**
*
* @param id
* @param func_type
* @param value
*/
void SimpleSM::setFlag(int /*in*/id, char /*in*/func_type, bool /*in*/value) {
//value = true => start activity
//value = false => stop activity
if (func_type == statemachine::TF_TIME_EVENT) {
pthread_mutex_lock (&timeEventMutexes[SIMPLESM_TE_INDEX(id)]);
timeEventFlags[SIMPLESM_TE_INDEX(id)] = value;
pthread_cond_signal (&timeEventConds[SIMPLESM_TE_INDEX(id)]);
pthread_mutex_unlock(&timeEventMutexes[SIMPLESM_TE_INDEX(id)]);
return;
}
if (func_type == statemachine::TF_DO_ACTIVITY) {
}
}
/**
*
* @param id
* @param duration
*/
void SimpleSM::listenTimeEvent(int /*in*/id, int /*in*/duration) {
struct timeval tv;
struct timespec ts;
int timedWaitResult;
while (true) {
pthread_mutex_lock (&timeEventMutexes[id]);
while (!timeEventFlags[id]) {
pthread_cond_wait(&timeEventConds[id], &timeEventMutexes[id]);
}
gettimeofday(&tv, NULL);
ts.tv_sec = time(NULL) + duration / 1000;
ts.tv_nsec = tv.tv_usec * 1000 + 1000 * 1000 * (duration % 1000);
ts.tv_sec += ts.tv_nsec / (1000 * 1000 * 1000);
ts.tv_nsec %= (1000 * 1000 * 1000);
timedWaitResult = pthread_cond_timedwait(&timeEventConds[id],
&timeEventMutexes[id], &ts);
bool commitEvent = false;
if (timedWaitResult != 0) {
//timeout
commitEvent = true;
}
timeEventFlags[id] = false;
pthread_cond_signal (&timeEventConds[id]);
pthread_mutex_unlock(&timeEventMutexes[id]);
if (commitEvent) {
//the state does not change, push time event to the queue
eventQueue.push(statemachine::PRIORITY_2, NULL, id,
statemachine::TIME_EVENT, id);
}
}
}
/**
*
*/
void SimpleSM::entry_dft() {
}
/**
*
*/
void SimpleSM::exit_dft() {
}
/**
*
*/
void SimpleSM::doActivity_dft() {
}
} // of namespace classes
} // of namespace SimpleSM
/************************************************************
End of SimpleSM class body
************************************************************/