aboutsummaryrefslogtreecommitdiff
path: root/profiling/client/src/ProfilingStateMachine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'profiling/client/src/ProfilingStateMachine.cpp')
-rw-r--r--profiling/client/src/ProfilingStateMachine.cpp95
1 files changed, 95 insertions, 0 deletions
diff --git a/profiling/client/src/ProfilingStateMachine.cpp b/profiling/client/src/ProfilingStateMachine.cpp
new file mode 100644
index 0000000000..e002c052b9
--- /dev/null
+++ b/profiling/client/src/ProfilingStateMachine.cpp
@@ -0,0 +1,95 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "ProfilingStateMachine.hpp"
+
+#include <common/include/ProfilingException.hpp>
+
+#include <sstream>
+
+namespace arm
+{
+
+namespace pipe
+{
+
+namespace
+{
+
+void ThrowStateTransitionException(ProfilingState expectedState, ProfilingState newState)
+{
+ std::stringstream ss;
+ ss << "Cannot transition from state [" << GetProfilingStateName(expectedState) << "] "
+ << "to state [" << GetProfilingStateName(newState) << "]";
+ throw arm::pipe::ProfilingException(ss.str());
+}
+
+} // Anonymous namespace
+
+ProfilingState ProfilingStateMachine::GetCurrentState() const
+{
+ return m_State.load();
+}
+
+void ProfilingStateMachine::TransitionToState(ProfilingState newState)
+{
+ ProfilingState currentState = m_State.load(std::memory_order::memory_order_relaxed);
+
+ switch (newState)
+ {
+ case ProfilingState::Uninitialised:
+ do
+ {
+ if (!IsOneOfStates(currentState, ProfilingState::Uninitialised))
+ {
+ ThrowStateTransitionException(currentState, newState);
+ }
+ }
+ while (!m_State.compare_exchange_strong(currentState, newState, std::memory_order::memory_order_relaxed));
+ break;
+ case ProfilingState::NotConnected:
+ do
+ {
+ if (!IsOneOfStates(currentState, ProfilingState::Uninitialised, ProfilingState::NotConnected,
+ ProfilingState::Active, ProfilingState::WaitingForAck))
+ {
+ ThrowStateTransitionException(currentState, newState);
+ }
+ }
+ while (!m_State.compare_exchange_strong(currentState, newState, std::memory_order::memory_order_relaxed));
+ break;
+ case ProfilingState::WaitingForAck:
+ do
+ {
+ if (!IsOneOfStates(currentState, ProfilingState::NotConnected, ProfilingState::WaitingForAck))
+ {
+ ThrowStateTransitionException(currentState, newState);
+ }
+ }
+ while (!m_State.compare_exchange_strong(currentState, newState, std::memory_order::memory_order_relaxed));
+ break;
+ case ProfilingState::Active:
+ do
+ {
+ if (!IsOneOfStates(currentState, ProfilingState::WaitingForAck, ProfilingState::Active))
+ {
+ ThrowStateTransitionException(currentState, newState);
+ }
+ }
+ while (!m_State.compare_exchange_strong(currentState, newState, std::memory_order::memory_order_relaxed));
+ break;
+ default:
+ break;
+ }
+}
+
+void ProfilingStateMachine::Reset()
+{
+ m_State.store(ProfilingState::Uninitialised);
+}
+
+} // namespace pipe
+
+} // namespace arm