MME2 changes - Propped commits from openmme/paging branch. Added scripts
for code gen
Change-Id: Ie55032217232214ac8544ca76ea34335205329e4
diff --git a/src/stateMachineFwk/Makefile b/src/stateMachineFwk/Makefile
new file mode 100644
index 0000000..a7a88bb
--- /dev/null
+++ b/src/stateMachineFwk/Makefile
@@ -0,0 +1,64 @@
+#
+# Copyright (c) 2019, Infosys Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+include ../../Makefile.common
+
+CC := g++
+CFLAGS += -std=c++11
+
+ifeq ($(DEBUG),true)
+ CFLAGS += -g
+endif
+
+ifeq ($(DEBUG),false)
+ CFLAGS += -O3
+endif
+
+SM_LIBNAME = $(LIBDIR)/libstatemachinefwk.so
+
+SRCS := \
+ ./actionTable.cpp \
+ ./controlBlock.cpp \
+ ./event.cpp \
+ ./permDataBlock.cpp \
+ ./procedureQueue.cpp \
+ ./state.cpp \
+ ./stateMachineEngine.cpp \
+ ./tempDataBlock.cpp
+
+SRCDIR := .
+OBJECTS := $(patsubst $(SRCDIR)/%,$(OBJDIR)/stateMachineFwk/%,$(SRCS:.cpp=.o))
+
+buildSmLIB: $(OBJECTS)
+ @echo "Linking"
+ @mkdir -p $(LIBDIR)
+ $(CC) $(CFLAGS) $(OBJECTS) -shared -o $(SM_LIBNAME)
+
+$(OBJECTS) : $(OBJDIR)/stateMachineFwk/%.o : $(SRCDIR)/%.cpp
+ @mkdir -p $(OBJDIR)/stateMachineFwk
+ $(CC) $(CFLAGS) $(INC_DIRS) -fPIC -c -o $@ $<
+
+all: buildSmLIB
+
+install:all
+ -@echo "Installing"
+ -@mkdir -p $(TARGET_DIR)/lib
+ -@cp $(SM_LIBNAME) $(TARGET_DIR)/lib
+
+clean:
+ @echo " Cleaning...";
+ -@rm -rf $(OBJDIR)/stateMachineFwk $(SM_LIBNAME)
+
diff --git a/src/stateMachineFwk/actionTable.cpp b/src/stateMachineFwk/actionTable.cpp
new file mode 100644
index 0000000..63b1ace
--- /dev/null
+++ b/src/stateMachineFwk/actionTable.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2019, Infosys Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <iostream>
+#include "controlBlock.h"
+#include "actionTable.h"
+#include "state.h"
+#include "log.h"
+
+using namespace std;
+
+namespace SM
+{
+
+ ActionTable::ActionTable()
+ :nextStatep(NULL)
+ {
+ }
+
+ ActionTable::~ActionTable()
+ {
+ }
+
+ ActStatus ActionTable::executeActions(ControlBlock& cb)
+ {
+ ActStatus rt = PROCEED;
+ for(auto it = actionsQ.begin(); it != actionsQ.end(); it++)
+ {
+ ActStatus ret = (*it)(cb);
+ if(PROCEED != ret)
+ {
+ // TODO: error handling
+ break;
+ }
+ }
+
+ if (PROCEED == rt &&
+ nextStatep != NULL)
+ {
+ cb.setNextState(nextStatep);
+ }
+
+ return rt;
+ }
+
+ void ActionTable::addAction(ActionPointer act)
+ {
+ actionsQ.push_back(act);
+ }
+
+ void ActionTable::setNextState(State* st)
+ {
+ nextStatep = st;
+ }
+
+ void ActionTable::display()
+ {
+ if(NULL != nextStatep)
+ {
+ log_msg(LOG_DEBUG,"\nnext State : - %d \n",nextStatep->getStateId());
+ }
+ }
+}
diff --git a/src/stateMachineFwk/controlBlock.cpp b/src/stateMachineFwk/controlBlock.cpp
new file mode 100644
index 0000000..1c41139
--- /dev/null
+++ b/src/stateMachineFwk/controlBlock.cpp
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2019, Infosys Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <iostream>
+#include <string>
+#include "controlBlock.h"
+#include "event.h"
+#include "log.h"
+#include "tempDataBlock.h"
+#include <stateMachineEngine.h>
+
+using namespace std;
+
+namespace SM
+{
+ uint32_t ControlBlock::controlBlockArrayIdx = 0;
+
+ ControlBlock::ControlBlock():mutex_m(), cbIndex_m(++controlBlockArrayIdx),
+ cbState_m(FREE), data_p(NULL), pdb_mp(NULL),
+ tdb_mp(NULL), inProcQueue_m(false)
+ {
+ for (int i = 0; i < MAX_FAST_BLOCK_IDX; i++)
+ fadb_mpa[i] = NULL;
+
+ std::queue<Event> emptyQ;
+ std::swap( eventQ, emptyQ );
+
+ std::deque<debugEventInfo> emptyDQ;
+ std::swap(debugEventInfoQ, emptyDQ);
+ }
+
+ void ControlBlock::reset()
+ {
+ std::lock_guard<std::mutex> lock(mutex_m);
+
+ cbState_m = FREE;
+
+ data_p = NULL;
+ pdb_mp = NULL;
+
+ for (int i = 0; i < MAX_FAST_BLOCK_IDX; i++)
+ fadb_mpa[i] = NULL;
+
+ tdb_mp = NULL;
+
+ inProcQueue_m = false;
+
+ std::queue<Event> emptyQ;
+ std::swap( eventQ, emptyQ );
+
+ std::deque<debugEventInfo> emptyDQ;
+ std::swap(debugEventInfoQ, emptyDQ);
+ }
+
+ ControlBlock::~ControlBlock()
+ {
+ }
+
+ bool ControlBlock::getCurrentEvent(Event &evt)
+ {
+ std::lock_guard<std::mutex> lock(mutex_m);
+
+ if(eventQ.empty())
+ return false;
+
+ evt = eventQ.front();
+ eventQ.pop();
+
+ setMsgData(evt.getEventData());
+
+ return true;
+ }
+
+ State* ControlBlock::getCurrentState()
+ {
+ return tdb_mp->getCurrentState();
+ }
+
+ void ControlBlock::display()
+ {
+ log_msg(LOG_DEBUG,"Displaying control block");
+
+ pdb_mp->display();
+
+ tdb_mp->display();
+
+ }
+
+ void ControlBlock::addEventToProcQ(Event &event)
+ {
+ std::lock_guard<std::mutex> lock(mutex_m);
+
+ if (cbState_m == ALLOCATED)
+ {
+ eventQ.push(event);
+ if (inProcQueue_m == false)
+ {
+ inProcQueue_m = true;
+ if (!SM::StateMachineEngine::Instance()->addCBToProcQ(this))
+ {
+ inProcQueue_m = false;
+ }
+ }
+ }
+ }
+
+ void ControlBlock::setNextState(State* state)
+ {
+ if (tdb_mp != NULL)
+ tdb_mp->setNextState(state);
+ }
+
+ PermDataBlock* ControlBlock::getFastAccessBlock(unsigned short idx) const
+ {
+ PermDataBlock* permBlock_p = NULL;
+
+ if (idx < ControlBlock::MAX_FAST_BLOCK_IDX)
+ permBlock_p = fadb_mpa[idx];
+
+ return permBlock_p;
+ }
+
+ void ControlBlock::setFastAccessBlock(
+ PermDataBlock* pdb_p, unsigned short idx)
+ {
+ if (idx < ControlBlock::MAX_FAST_BLOCK_IDX)
+ fadb_mpa[idx] = pdb_p;
+ }
+
+ PermDataBlock* ControlBlock::getPermDataBlock() const
+ {
+ return pdb_mp;
+ }
+
+ void ControlBlock::setPermDataBlock(PermDataBlock* pdb_p)
+ {
+ pdb_mp = pdb_p;
+ }
+
+ TempDataBlock* ControlBlock::getTempDataBlock() const
+ {
+ return tdb_mp;
+ }
+
+ void ControlBlock::setTempDataBlock(TempDataBlock* tdb_p)
+ {
+ if (tdb_p == NULL)
+ return;
+
+ tdb_mp = tdb_p;
+ }
+
+ void ControlBlock::setCurrentTempDataBlock(TempDataBlock* tdb_p)
+ {
+ if (tdb_p == NULL)
+ return;
+
+ if (tdb_mp != NULL)
+ {
+ tdb_p->setNextTempDataBlock(tdb_mp);
+ }
+
+ tdb_mp = tdb_p;
+ }
+
+ void ControlBlock::addDebugInfo(debugEventInfo& eventInfo)
+ {
+ if(debugEventInfoQ.size()>=10)
+ {
+ debugEventInfoQ.pop_front();
+ }
+ debugEventInfoQ.push_back(eventInfo);
+ }
+
+ uint32_t ControlBlock::getCBIndex()
+ {
+ return cbIndex_m;
+ }
+
+ void ControlBlock::setControlBlockState(ControlBlockState state)
+ {
+ std::lock_guard<std::mutex> lock(mutex_m);
+
+ log_msg(LOG_INFO, "CB state transition from %d to %d\n", cbState_m, state);
+
+ cbState_m = state;
+ }
+
+ ControlBlockState ControlBlock::getControlBlockState()
+ {
+ std::lock_guard<std::mutex> lock(mutex_m);
+
+ return cbState_m;
+ }
+
+ void ControlBlock::setProcQueueFlag(bool flag)
+ {
+ std::lock_guard<std::mutex> lock(mutex_m);
+ inProcQueue_m = flag;
+ }
+
+ bool ControlBlock::isInProcQueue()
+ {
+ std::lock_guard<std::mutex> lock(mutex_m);
+ return inProcQueue_m;
+ }
+}
diff --git a/src/stateMachineFwk/event.cpp b/src/stateMachineFwk/event.cpp
new file mode 100644
index 0000000..6f49536
--- /dev/null
+++ b/src/stateMachineFwk/event.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019, Infosys Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <iostream>
+#include "event.h"
+#include "log.h"
+
+using namespace std;
+
+namespace SM
+{
+ Event::Event():
+ eventID(), eventData_p(NULL)
+ {
+ }
+
+ Event::Event(Event_e evtID, void* ptr)
+ :eventID(evtID), eventData_p(ptr)
+ {
+ }
+
+ Event::~Event()
+ {
+ }
+
+ void *Event::getEventData() const
+ {
+ return eventData_p;
+ }
+
+ void Event::display()
+ {
+ log_msg(LOG_DEBUG,"Event ID - %d",eventID);
+ }
+}
diff --git a/src/stateMachineFwk/permDataBlock.cpp b/src/stateMachineFwk/permDataBlock.cpp
new file mode 100644
index 0000000..4a30bd5
--- /dev/null
+++ b/src/stateMachineFwk/permDataBlock.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2019, Infosys Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <iostream>
+#include "permDataBlock.h"
+#include "log.h"
+
+using namespace std;
+namespace SM
+{
+PermDataBlock::PermDataBlock()
+ :contextID(0)
+{
+}
+
+PermDataBlock::~PermDataBlock()
+{
+}
+
+void PermDataBlock::display()
+{
+ // Display all data fields
+ log_msg(LOG_DEBUG,"\nContext ID - %d \n",contextID);
+}
+}
+
diff --git a/src/stateMachineFwk/procedureQueue.cpp b/src/stateMachineFwk/procedureQueue.cpp
new file mode 100644
index 0000000..ac56a0c
--- /dev/null
+++ b/src/stateMachineFwk/procedureQueue.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2019, Infosys Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <bits/stdc++.h>
+#include <iostream>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include "procedureQueue.h"
+#include "controlBlock.h"
+
+namespace SM
+{
+const size_t PROC_QUE_MAX_SIZE = 1000;
+
+ProcedureQueue::ProcedureQueue():cbQ(), mutex_m()
+{
+ sem_init(&pop_semaphore, 0, 0);
+}
+
+ProcedureQueue::~ProcedureQueue()
+{
+ queue<ControlBlock*> q;
+ swap( cbQ, q);
+ sem_destroy(&pop_semaphore);
+}
+
+ControlBlock* ProcedureQueue::pop()
+{
+ sem_wait(&pop_semaphore);
+
+ std::lock_guard<std::mutex> lock(mutex_m);
+
+ ControlBlock* cb = NULL;
+
+ if(cbQ.empty())
+ {
+ return NULL;
+ }
+
+ cb = cbQ.front();
+ cbQ.pop();
+
+ return cb;
+}
+
+bool ProcedureQueue::push(ControlBlock* cb)
+{
+ std::lock_guard<std::mutex> lock(mutex_m);
+
+ if(PROC_QUE_MAX_SIZE == cbQ.size())
+ {
+ return false;
+ }
+
+ cbQ.push(cb);
+ sem_post(&pop_semaphore);
+
+ return true;
+}
+}
diff --git a/src/stateMachineFwk/state.cpp b/src/stateMachineFwk/state.cpp
new file mode 100644
index 0000000..007ba43
--- /dev/null
+++ b/src/stateMachineFwk/state.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2019, Infosys Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <iostream>
+#include "state.h"
+#include "actionTable.h"
+#include "smTypes.h"
+#include "log.h"
+
+using namespace std;
+
+
+namespace SM
+{
+ State::State(State_e sID)
+ :stateID(sID),
+ eventToActionsMap()
+ {
+ }
+
+ State::~State()
+ {
+ }
+
+ void State::display()
+ {
+ for(auto& eventToActionsMapEntry : eventToActionsMap)
+ {
+ log_msg(LOG_DEBUG, "Event Id = %d \n", eventToActionsMapEntry.first);
+ ActionTable& act = eventToActionsMapEntry.second;
+ act.display();
+ }
+ }
+
+ ActStatus State::executeActions(Event_e evt,ControlBlock& cb)
+ {
+ EventToActionTableMap::iterator itr = eventToActionsMap.find(evt);
+
+ if (itr != eventToActionsMap.end())
+ {
+ ActionTable& actions_r = itr->second;
+ return actions_r.executeActions(cb);
+ }
+ else
+ return ActStatus::HALT;
+ }
+}
diff --git a/src/stateMachineFwk/stateMachineEngine.cpp b/src/stateMachineFwk/stateMachineEngine.cpp
new file mode 100644
index 0000000..79bfa2c
--- /dev/null
+++ b/src/stateMachineFwk/stateMachineEngine.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2019, Infosys Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <iostream>
+#include <time.h>
+#include <msgBuffer.h>
+#include "stateMachineEngine.h"
+#include "controlBlock.h"
+#include "event.h"
+#include "state.h"
+#include "smTypes.h"
+extern "C"
+{
+ #include "log.h"
+}
+using namespace std;
+
+namespace SM
+{
+ StateMachineEngine::StateMachineEngine():
+ procQ_m()
+ {
+ }
+
+
+ StateMachineEngine::~StateMachineEngine()
+ {
+ }
+
+
+ StateMachineEngine* StateMachineEngine::Instance()
+ {
+ static StateMachineEngine SM;
+ return &SM;
+ }
+
+
+ bool StateMachineEngine::addCBToProcQ(ControlBlock* cb)
+ {
+ return procQ_m.push(cb);
+ }
+
+ void StateMachineEngine::run()
+ {
+ ControlBlock* cb = procQ_m.pop();
+
+ if(cb == NULL)
+ return;
+
+ if (cb->getControlBlockState() == FREE)
+ {
+ log_msg(LOG_INFO, "Control block is freed\n");
+ return;
+ }
+
+ while (true)
+ {
+ Event currentEvent;
+ if (cb->getCurrentEvent(currentEvent) == false)
+ {
+ break;
+ }
+
+ State *currentState_p = cb->getCurrentState();
+ if (currentState_p == NULL)
+ {
+ log_msg(LOG_INFO, "Current state is NULL"
+ " for control block idx %d\n", cb->getCBIndex());
+
+ // TODO: free event msg data or cleaner handling
+
+ break;;
+ }
+
+ log_msg(LOG_DEBUG,
+ "################ Executing actions for event: %s and State: %s #################\n",
+ Events[currentEvent.getEventId()], States[currentState_p->getStateId()]);
+
+ time_t mytime = time(NULL);
+ debugEventInfo dEventInfo(currentEvent.getEventId(), currentState_p->getStateId(), mytime);
+ cb->addDebugInfo(dEventInfo);
+
+ ActStatus ret = currentState_p->executeActions(currentEvent.getEventId(),*cb);
+ if(PROCEED != ret)
+ {
+ // TODO: Error Handling, do not process further events for now
+ break;;
+ }
+
+ void * event_data = currentEvent.getEventData();
+ if (event_data != NULL)
+ delete static_cast <cmn::utils::MsgBuffer *>(event_data);
+ }
+
+ if (cb->getControlBlockState() == ALLOCATED)
+ cb->setProcQueueFlag(false);
+ }
+}
+
diff --git a/src/stateMachineFwk/tempDataBlock.cpp b/src/stateMachineFwk/tempDataBlock.cpp
new file mode 100644
index 0000000..bf3fe80
--- /dev/null
+++ b/src/stateMachineFwk/tempDataBlock.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2019, Infosys Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tempDataBlock.h"
+#include "stateMachineEngine.h"
+#include "state.h"
+
+using namespace std;
+
+namespace SM
+{
+TempDataBlock::TempDataBlock(): currentStatep(NULL), next(NULL)
+{
+}
+
+TempDataBlock::~TempDataBlock()
+{
+}
+
+void TempDataBlock::display()
+{
+ if (currentStatep)
+ currentStatep->display();
+}
+
+State* TempDataBlock::getCurrentState()
+{
+ return currentStatep;
+}
+
+void TempDataBlock::setNextState(State* state)
+{
+ currentStatep = state;
+}
+
+TempDataBlock* TempDataBlock::getNextTempDataBlock()
+{
+ return next;
+}
+
+void TempDataBlock::setNextTempDataBlock(TempDataBlock* tdb_p)
+{
+ next = tdb_p;
+}
+
+}