1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #include "ProfilingStateMachine.hpp"
7
8 #include <common/include/ProfilingException.hpp>
9
10 #include <sstream>
11
12 namespace arm
13 {
14
15 namespace pipe
16 {
17
18 namespace
19 {
20
ThrowStateTransitionException(ProfilingState expectedState,ProfilingState newState)21 void ThrowStateTransitionException(ProfilingState expectedState, ProfilingState newState)
22 {
23 std::stringstream ss;
24 ss << "Cannot transition from state [" << GetProfilingStateName(expectedState) << "] "
25 << "to state [" << GetProfilingStateName(newState) << "]";
26 throw arm::pipe::ProfilingException(ss.str());
27 }
28
29 } // Anonymous namespace
30
GetCurrentState() const31 ProfilingState ProfilingStateMachine::GetCurrentState() const
32 {
33 return m_State.load();
34 }
35
TransitionToState(ProfilingState newState)36 void ProfilingStateMachine::TransitionToState(ProfilingState newState)
37 {
38 ProfilingState currentState = m_State.load(std::memory_order::memory_order_relaxed);
39
40 switch (newState)
41 {
42 case ProfilingState::Uninitialised:
43 do
44 {
45 if (!IsOneOfStates(currentState, ProfilingState::Uninitialised))
46 {
47 ThrowStateTransitionException(currentState, newState);
48 }
49 }
50 while (!m_State.compare_exchange_strong(currentState, newState, std::memory_order::memory_order_relaxed));
51 break;
52 case ProfilingState::NotConnected:
53 do
54 {
55 if (!IsOneOfStates(currentState, ProfilingState::Uninitialised, ProfilingState::NotConnected,
56 ProfilingState::Active, ProfilingState::WaitingForAck))
57 {
58 ThrowStateTransitionException(currentState, newState);
59 }
60 }
61 while (!m_State.compare_exchange_strong(currentState, newState, std::memory_order::memory_order_relaxed));
62 break;
63 case ProfilingState::WaitingForAck:
64 do
65 {
66 if (!IsOneOfStates(currentState, ProfilingState::NotConnected, ProfilingState::WaitingForAck))
67 {
68 ThrowStateTransitionException(currentState, newState);
69 }
70 }
71 while (!m_State.compare_exchange_strong(currentState, newState, std::memory_order::memory_order_relaxed));
72 break;
73 case ProfilingState::Active:
74 do
75 {
76 if (!IsOneOfStates(currentState, ProfilingState::WaitingForAck, ProfilingState::Active))
77 {
78 ThrowStateTransitionException(currentState, newState);
79 }
80 }
81 while (!m_State.compare_exchange_strong(currentState, newState, std::memory_order::memory_order_relaxed));
82 break;
83 default:
84 break;
85 }
86 }
87
Reset()88 void ProfilingStateMachine::Reset()
89 {
90 m_State.store(ProfilingState::Uninitialised);
91 }
92
93 } // namespace pipe
94
95 } // namespace arm
96