Thread Safety
In EEROS, blocks are basically accessed by multiple threads. EEROS blocks feature thread safety by providing exclusive access to critical memory locations by a mutex.
Concurrency can not be tested by Google Test framework. Therefore, test executables are needed which can be executed manually or via bash scripts.
To provide an example, a test program testing the Gain block is described below. The full source code is available on GitHub at: https://github.com/eeros-project/eeros-framework/blob/master/examples/devel/multithreading.cpp
The problem
The following code snipped and image show the issue simulated in the test program. The main thread calls g1.run() on the gain object. This method is doing a long calculation. Thread t2 is unfortunately changing the gain by calling g1.setGain(gM2) during the main threads calculation. This will finally lead to an unexpected result.
Matrix<M,N> gM1;
Matrix<M,N> gM2;
Gain<Matrix<M,N>, Matrix<M,N>,true> g1{gM1};
Constant<Matrix<M,N>> c1{m2};
std::thread t2{[&] {
g1.setGain(gM2);
}};
g1.run();
Matrix<M,N> res = g1.getOut().getSignal().getValue();
// Note: The above code is simplified for a better understanding.
The solution
The Gain block is now implemented thread safe by using the class lock_guard and a mutex. The code snipped below shows the setGain() method as an example.
virtual void setGain(Tgain c) {
std::lock_guard<std::mutex> lock(mtx);
gain = c;
}
The test program will not show an unexpected result anymore. To see the unexpected result, the locking mechanism must be removed (comment std::lock_guard<std::mutex> lock(mtx);).
