Ph.D. - geht es zur Homepage der Informatik des Fachbereiches 3 ...
Ph.D. - geht es zur Homepage der Informatik des Fachbereiches 3 ...
Ph.D. - geht es zur Homepage der Informatik des Fachbereiches 3 ...
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Chapter 8. openETCS Domain Framework<br />
8.6.2. Data Flow Implementation<br />
Most of the functionality of CFunctionBlock elements is simple to implement, like mathematical<br />
operations, but also the implementation of braking curv<strong>es</strong> is mainly a transfer of a mathematical<br />
/ physical model to C++ code. More crucial for the correct operation of any data flow is the<br />
execution in equidistant time points, which will be discussed here.<br />
Section 8.4 demonstrated that the cycl<strong>es</strong> are generated in the CEVCState class by an own<br />
thread for each independent data flow. Those threads are implemented in the following method:<br />
void CEVCStateMachine : : CEVCState : : DataFlowThread ( const unsigned int& i I n d e x ) throw ( ) ;<br />
Since for each independent CDataFlow object an additional thread of this method is started,<br />
iIndex determin<strong>es</strong> for which CDataFlow object in m_CurrentDataFlow the thread is r<strong>es</strong>ponsible.<br />
In the implementation, the m_CurrentDataFlow aggregation is declared as<br />
: : s t d : : v e c t o r < CDataFlow∗ > m_CurrentDataFlow ;<br />
Creating threads according to C++11 is done by using the ::std::thread class [7, Ch. 30].<br />
Hence, all data flow threads are created and started by the lin<strong>es</strong> of code in Listing D.1 in<br />
Appendix D.<br />
Th<strong>es</strong>e are located in the definition of the following method:<br />
void CEVCStateMachine : : CEVCState : : S t a r t ( ) throw ( : : oETCS : : DF : : E r r o r : : CException )<br />
Since the CEVCStateMachine::CEVCState::Start() method should be blocking and should<br />
only return if all threads are terminated, the ::std::thread::join() method is used, which<br />
blocks until the corr<strong>es</strong>ponding thread has been terminated in Listing D.2. While this is mainly<br />
an object-oriented and platform independent way of starting a group of worker-thread, the<br />
thread-method implementation is more complex and therefore of more inter<strong>es</strong>t.<br />
The execution of the related CDataFlow object at equidistant time points must be implemented,<br />
which is done in corr<strong>es</strong>ponding CEVCState method:<br />
void CEVCStateMachine : : CEVCState : : DataFlowThread ( const unsigned int & i I n d e x ) throw ( )<br />
Furthermore, all m_Threads must be synchronised in that way that the execution of each<br />
thread should start for every k at the same time point t = kT s (see (7.1)). This problem is<br />
related to real-time scheduling [77, pp. 457-504]. Although this is very difficult to realise in real<br />
technical systems, the time difference between the execution start points should be minimised.<br />
Figure 8.20 sketch<strong>es</strong> a sample execution in the time domain for two unsynchronised threads.<br />
B<strong>es</strong>id<strong>es</strong> that the second thread always starts the execution with a delay ∆t i , those delays<br />
also differ: ∆t 1 ≠ ∆t 2 ≠ ∆t 3 ≠ . . . . As already discussed in Section 7.6, this can lead to an<br />
undefined behaviour of the data flows in the time domain. The ideal sample execution for two<br />
threads is shown in Figure 8.21<br />
The execution is implemented as a loop that calculat<strong>es</strong> for each execution cycle k the<br />
consumed time and puts the thread for the remaining time to the next execution time point<br />
(k + 1)T s to sleep. The corr<strong>es</strong>ponding C++ source code can be found in Listing D.3 in<br />
Appendix D.<br />
At the very first execution of the while-loop, the time point of the execution start is measured<br />
once (Line 21) by the ::std::chrono::high_r<strong>es</strong>olution_clock::now() method, which is<br />
150