31.01.2014 Views

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 ...

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!