How to create QThread without task switching - c++

I'm developing an Atmega328P MCU simulator and have a little problem regarding the timer. The timer in Atmega328P is ticking once per 62.5 ns (on 16MHz) and I have to simulate that. To solve problem I have created this class
class DLL_EXPORT Timer : public QThread
...
void Timer::run()
{
CCPU* cpu = dynamic_cast<CCPU*>(parent());
if (cpu == nullptr)
{
exit();
return;
}
QElapsedTimer timer_core;
timer_core.start();
while (1)
{
if (timer_core.nsecsElapsed() >= 62)
{
++cpu->GetIOPorts()[0x26];
timer_core.restart();
}
}
}
It seems to work fine, but there's a little problem regarding task switching process in CPU. How can I disable that process for this certain class?
Or maybe there is another approach for the solution?

Related

Missing capabilities for unit test

I've implemented a C++ Class that will execute something in a timed cycle using a thread. The thread is set to be scheduled with the SCHED_DEADLINE scheduler of the Linux kernel. To setup the Scheduler the process running this must have certain Linux capabilities.
My question is, how to test this?
I can of course make a unit test and create the threat, do some counting an exit the test after a time to validate the cycle counter but that only works if the unit test is allowed to apply the right scheduler. If not, the default scheduler applies and the timing of the cyclic loops will be immediate and therefore executes a different behaviour.
How would you test this scenario?
Some Code Example:
void thread_handler() {
// setup SCHED_DEADLINE Parameters
while (running) {
// execute application logic
sched_yield();
}
}
There two separate units to test here. First the cyclic execution of code and second the strategy with the os interface. The first unit would look like this:
class CyclicThread : public std::thread {
public:
CyclicThread(Strategy& strategy) :
std::thread(bind(&CyclicThread::worker, this)),
strategy(strategy) { }
add_task(std::function<void()> handler) {
...
}
private:
Strategy& strategy;
void worker() {
while (running) {
execute_handler()
strategy.yield();
}
}
}
This is fairly easy to test with a mock object of the strategy.
The Deadline scheduling strategy looks like this:
class DeadlineStrategy {
public:
void yield() {
sched_yield();
}
}
This class can also be tested fairly easy by mocking the sched_yield() system call.

Multi thread problem with loop on ESP8266

I'm using Nodemcu for my IoT project and I should use PHP with that. I'm trying to changing funcs, when I press the button on web site. My func1 has 1000ms delay with millis. func2 has a 360000ms delay, so I can't change func2 to func1 when I want to. I tried so many ways, how can I do that?
My code is like this:
void func1() {
// code for manuel GPIO control
// millis....
}
void func2() {
// code for automatic GPIO control
// millis....
}
void loop() {
// millis....
if (payload == 1) {
func1();
} else if (payload == 0) {
func2();
}
}
Arduino does not support multi-threading, but you can use different programming technique to make your program to work without blocking, for example Blink Without Delay

Threaded Video Player sync

Disclaimer:I asked this question a few days ago on codereview,but got no answer.Here I change the question format from review request to a specific problems.
I am developing a video player with the following design:
The main thread - is GUI thread (Qt SDK).
Second thread - player thread which accepts commands from the GUI thread to play, forward, backward, stop etc. Now,this thread runs in a constant loop and and uses mutexes and wait conditions to live in sync with the main thread commands.
I have 2 problems with this code:
I don't feel my design is completely correct:I am using both mutex locks and atomic variables.I wonder if I can stay only with the atomics and use locks only for setting the wait conditions.
I am experiencing inconsistent bugs(probably due to the condition race when the play command tries to lock mutex which is already locked by the thread while the play loop is working) when I run "play" commands which activates a loop inside the thread loop. So I suppose it blocks the access to the shared variables to the main thread.
I have stripped off the code from unneeded stuff and it generally goes like this:
void PlayerThread::drawThread()//thread method passed into new boost::thread
{
//some init goes here....
while(true)
{
boost::unique_lock<boost::mutex> lock(m_mutex);
m_event.wait(lock); //wait for event
if(!m_threadRun){
break; //exit the tread
}
///if we are in playback mode,play in a loop till interrupted:
if(m_isPlayMode == true){
while(m_frameIndex < m_totalFrames && m_isPlayMode){
//play
m_frameIndex ++;
}
m_isPlayMode = false;
}else{//we are in a single frame play mode:
if(m_cleanMode){ ///just clear the screen with a color
//clear the screen from the last frame
//wait for the new movie to get loaded:
m_event.wait(lock);
//load new movie......
}else{ //render a single frame:
//play single frame....
}
}
}
}
Here are the member functions of the above class which send commands to the thread loop:
void PlayerThread::PlayForwardSlot(){
// boost::unique_lock<boost::mutex> lock(m_mutex);
if(m_cleanMode)return;
m_isPlayMode = false;
m_frameIndex++;
m_event.notify_one();
}
void PlayerThread::PlayBackwardSlot(){
// boost::unique_lock<boost::mutex> lock(m_mutex);
if(m_cleanMode)return;
m_isPlayMode = false;
m_frameIndex-- ;
if(m_frameIndex < 0){
m_frameIndex = 0;
}
m_event.notify_one();
}
void PlayerThread::PlaySlot(){
// boost::unique_lock<boost::mutex> lock(m_mutex);
if(m_cleanMode)return;
m_isPlayMode = true;
m_event.notify_one(); //tell thread to start playing.
}
All the flag members like m_cleanMode, m_isPlayMode and m_frameIndex are atomics:
std::atomic<int32_t> m_frameIndex;
std::atomic<bool> m_isPlayMode;
std::atomic<bool> m_cleanMode;
The questions summary::
Do I need mutex locks when using atomics?
Do I set waiting in the correct place inside the while loop of the
thread?
Any suggestion of a better design?
UPDATE:
Though I got an answer which seems to be in the right direction I don't really understand it.Especially the pseudo-code part which is talking about service.It is completely unclear to me how it would work.I would like to get a more elaborated answer.It is also strange that I received only one constructive answer to such a common problem.So I am resetting the bounty.
The biggest issue with your code is that you wait unconditionally. boost::condition::notify_one only wake up a thread which is waiting. Which means Forward Step\Backward Step then Play if fast enough will ignore the play command. I dont get clean mode, but you need at least
if(!m_isPlayMode)
{
m_event.wait(lock);
}
In your code stop and stepping to a frame are virtually the same thing .You may want to use a tristate PLAY,STEP, STOP to be able to use the recommended way of waiting on a condition variable
while(state == STOP)
{
m_event.wait(lock);
}
1. Do I need mutex locks when using atomics?
Technically yes. In this specific case I don't think so.
Current races conditions (I noticed) :
playing mode, playforward and playbackward will not result in the same m_frameIndex depending whether or not drawThread is within the while(m_frameIndex < m_totalFrames && m_isPlayMode) loop. Indeed m_frameIndexcould be incremented once or twice (playforward).
Entering the playing state in PlaySlot can be ignored if drawThread execute m_isPlayMode = false; before receiving the next event. Right now it is a non-issue because it will only happen if m_frameIndex < m_totalFrames is false. If PlaySlot was modifying m_frameIndex then you will have case of pushing play and nothing happen.
2. Do I set waiting in the correct place inside the while loop of the thread?
I would suggest to have only one wait in your code, for simplicity. And be explicit about the next thing to do using specific commands :
PLAY, STOP, LOADMOVIE, STEP
3. Any suggestion of a better design?
Use an explicit event queue. You can use one which is Qt-based (require Qthreads) or boost based. The one based on boost use a boost::asio::io_service and a boost::thread.
You start the event loop using :
boost::asio::io_service service;
//permanent work so io_service::exec doesnt terminate immediately.
boost::asio::io_service::work work(service);
boost::thread thread(boost::bind(&boost::asio::io_service::exec, boost::ref(service)));
Then you send your commands from the GUI using
MYSTATE state;
service.post(boost::bind(&MyObject::changeState,this, state));
Your play method should request another play given that the state hasn't changed, rather than looping. It allows a better user preemption.
Your step method should request a stop before displaying the frame.
Pseudocode:
play()
{
if(state != PLAYING)
return;
drawframe(index);
index++;
service.post(boost::bind(&MyObject::play, this));
}
stepforward()
{
stop();
index++;
drawframe(index);
}
stepbackward()
{
stop();
index--;
drawframe(index);
}
Edit:
There is only one player thread which is created once and execute only one event loop. Is is equivalent to QThread::start(). The thread will live as long as the loop doesnt return, which is going to be till the work object is destroyed OR when you explicitly stop the service. When you request to stop a service all posted tasks which are still pending are going to be executed first. You can interrupt the thread for fast exit if neccessary.
When there is a call for an action you post in the event loop ran by the player thread.
Note: You will probably need share pointers for the service and the thread. You will also need to put interrupt points in the play method in order to allow stopping the thread cleanly during playback. You don't need as much atomic as before. You don't need a condition variable anymore.
Any suggestion of a better design?
Yes! Since you are using Qt I would heavily suggest to use Qt's eventloop (apart from the UI stuff this is IMO one of the main selling points of that library) and asynchronous signal/slots to do the controlling instead of your homegrown synchronization, which - as you found out - is a very fragile undertaking.
The main change this will bring to your current design is that you will have to do your video logic as part of the Qt event-loop, or, easier, just do a QEventLoop::processEvents. For that you will need a QThread.
Then it's very straightforward: You create some class that inherits from QObject let's say PlayerController which should contain signals like play, pause, stop and a class Player which will have slots onPlay, onPause, onStop (or without the on, your preference). Then create a 'controller' object of the PlayerController class in the GUI thread and the Player object in the 'video' thread (or use QObject::moveToThread). This is important, as Qt has the notion of thread affinity to determine in which thread SLOTs are executed. No connect the objects by doing QObject::connect(controller, SIGNAL(play()), player, SLOT(onPlay())). Any call now to PlayerController:play on the 'controller' from the GUI thread will result in the onPlay method of the 'player' being executed in the video thread on the next event loop iteration. That's where you can then change your boolean status variables or do other kind of action without the need for explicit synchronization as your variables are only changes from the video thread now.
So something along those lines:
class PlayerController: public QObject {
Q_OBJECT
signals:
void play();
void pause();
void stop();
}
class Player: public QObject {
Q_OBJECT
public slots:
void play() { m_isPlayMode = true; }
void pause() { m_isPlayMode = false; }
void stop() { m_isStop = true; };
private:
bool m_isPlayMode;
bool m_isStop;
}
class VideoThread: public QThread {
public:
VideoThread (PlayerController* controller) {
m_controller = controller;
}
protected:
/* override the run method, normally not adviced but we want our special eventloop */
void run() {
QEventLoop loop;
Player* player = new Player;
QObject::connect(m_controller, SIGNAL(play()), player, SLOT(play()));
QObject::connect(m_controller, SIGNAL(pause()), player, SLOT(pause()));
QObject::connect(m_controller, SIGNAL(stop()), player, SLOT(stop()));
m_isStop = false;
m_isPlayMode = false;
while(!m_isStop) {
// DO video related stuff
loop.processEvents();
}
}
private:
PlayerController* m_controller;
}
// somewhere in main thread
PlayerController* controller = new PlayerController();
VideoThread* videoThread = new VideoThread(controller);
videoThread.start();
controller.play();
Any suggestion of a better design?
Instead of using separate thread, use QTimer and play on the main thread. No atomics or mutexes needed. I am not quite tracking with m_cleanMode, so I mostly took it out of the code. If you elaborate more on what it does, I cam add it to the code.
class Player
{
int32_t m_frameIndex;
bool m_cleanMode;
QTimer m_timer;
void init();
void drawFrame();
slots:
void play();
void pause();
void playForward();
void playBackward();
private slots:
void drawFrameAndAdvance();
}
void Player::init()
{
// some init goes here ...
m_timer.setInterval(333); // 30fps
connect(&m_timer, SIGNAL(timeout()), this, SLOT(drawFrameAndAdvance()));
}
void Player::drawFrame()
{
// play 1 frame
}
void Player::drawFrameAndAdvance()
{
if(m_frameIndex < m_totalFrames - 1) {
drawFrame();
m_frameIndex++;
}
else m_timer.stop();
}
void PlayerThread::playForward()
{
if(m_cleanMode) return;
m_timer.stop(); // stop playback
if(m_frameIndex < m_totalFrames - 1) {
m_frameIndex++;
drawFrame();
}
}
void PlayerThread::playBackward()
{
if(m_cleanMode)return;
m_timer.stop(); // stop playback
if(m_frameIndex > 0) {
m_frameIndex--;
drawFrame();
}
}
void PlayerThread::play()
{
if(m_cleanMode) return;
m_timer.start(); // start playback
}
void PlayerThread::pause()
{
if(m_cleanMode) return;
m_timer.stop(); // stop playback
}

Precise interval in QThread

I have written a thread in Qt that does lot of things (calculations, data sampling, ...).
This thread has to be run in an interval of 1000ms.
The allowed error with the timer is about 5ms.
I have changed the priority of the thread to QThread::HighPriority but the thread runs in interval about to 1060ms-1100ms.
How can I make the interval more precise? (I have subclassed QThread and used msleep(interval) in the run() method).
You have coded your thread's run() method essentially as:
void MyThread::run() {
forever {
doSomething();
msleep(1000);
}
}
There are several problems:
doSomething() doesn't take zero amount of time. At the minimum, you'd need to time how long doSomething() takes and sleep that much shorter than 1000ms.
Both doSomething() and msleep() can take a variable amount of time, since your thread is never guaranteed not to be preempted, nor is it guaranteed to immediately start running once it's made runnable by the sleep expiring. Thus you need to keep track of time absolutely, not relatively to the start of doSomething().
You're using a generic sleep function without possibly leveraging better APIs that the underlying platform might offer.
A reasonably correct way to go about it would be expressed using this pseudocode:
const qint64 kInterval = 1000;
qint64 mtime = QDateTime::currentMSecsSinceEpoch();
forever {
doSomething();
mtime += kInterval;
qint64 sleepFor = mtime - QDateTime::currentMSecsSinceEpoch();
if (sleepFor < 0) {
// We got preempted for too long - for all we know, the system could
// have even gotten suspended (lid close on a laptop).
// Note: We should avoid the implementation-defined behavior of
// modulus (%) for negative values.
sleepFor = kInterval - ((-sleepFor) % kInterval);
}
OS_Precise_Wait_ms(sleepFor); // use the appropriate API on given platform
}
As luck would have it, Qt provides an API that does all this for you: the timers. They are a source of reasonably behaved periodic "ticks". Most naive re-implementations of this functionality are likely to get it wrong in one way or another, since it's not as simple as it looks.
Here is how you can reorganize the code:
class Worker : public QObject {
QBasicTimer m_timer;
void doSomething() {
// do the work
}
void timerEvent(QTimerEvent * ev) {
if (ev->timerId() != m_timer.timerId()) {
QObject::timerEvent(ev);
return;
}
doSomething();
}
public:
Worker(QObject * parent = 0) : QObject(parent) {
m_timer.start(1000, Qt::PreciseTimer, this);
}
};
int main(int argc, char ** argv) {
QCoreApplication app(argc, argv);
Worker worker;
QThread workerThread;
worker.moveToThread(workerThread);
workerThread.start(QThread::HighPriority);
// Example of how to terminate the application after 10 seconds
// Requires Qt 5 and a C++11 compiler.
QTimer timer;
QObject::connect(&timer, &QTimer::timeout, [&](){
workerThread.quit();
workerThread.wait();
app.quit();
});
timer.setTimerType(Qt::VeryCoarseTimer);
timer.setSingleShot(true);
timer.start(10000);
return app.exec();
}
From the docs of QTimer class:
Accuracy and Timer Resolution
The accuracy of timers depends on the underlying operating system and
hardware. Most platforms support a resolution of 1 millisecond, though
the accuracy of the timer will not equal this resolution in many
real-world situations.
The accuracy also depends on the timer type. For Qt::PreciseTimer,
QTimer will try to keep the accurance at 1 millisecond. Precise timers
will also never time out earlier than expected.
For Qt::CoarseTimer and Qt::VeryCoarseTimer types, QTimer may wake up
earlier than expected, within the margins for those types: 5% of the
interval for Qt::CoarseTimer and 500 ms for Qt::VeryCoarseTimer.
All timer types may time out later than expected if the system is busy
or unable to provide the requested accuracy. In such a case of timeout
overrun, Qt will emit activated() only once, even if multiple timeouts
have expired, and then will resume the original interval.

Thread implemented as a Singleton

I have a commercial application made with C,C++/Qt on Linux platform. The app collects data from different sensors and displays them on GUI. Each of the protocol for interfacing with sensors is implemented using singleton pattern and threads from Qt QThreads class. All the protocols except one work fine. Each protocol's run function for thread has following structure:
void <ProtocolClassName>::run()
{
while(!mStop) //check whether screen is closed or not
{
mutex.lock()
while(!waitcondition.wait(&mutex,5))
{
if(mStop)
return;
}
//Code for receiving and processing incoming data
mutex.unlock();
} //end while
}
Hierarchy of GUI.
1.Login screen.
2. Screen of action.
When a user logs in from login screen, we enter the action screen where all data is displayed and all the thread's for different sensors start. They wait on mStop variable in idle time and when data arrives they jump to receiving and processing data. Incoming data for the problem protocol is 117 bytes. In the main GUI threads there are timers which when timeout, grab the running instance of protocol using
<ProtocolName>::instance() function
Check the update variable of singleton class if its true and display the data. When the data display is done they reset the update variable in singleton class to false. The problematic protocol has the update time of 1 sec, which is also the frame rate of protocol. When I comment out the display function it runs fine. But when display is activated the application hangs consistently after 6-7 hours. I have asked this question on many forums but haven't received any worthwhile suggestions. I Hope that here I will get some help. Also, I have read a lot of literature on Singleton, multithreading, and found that people always discourage the use of singletons especially in C++. But in my application I can think of no other design for implementation.
Thanks in advance
A Hapless programmer
I think singleton is not really what you are looking for. Consider this:
You have (lets say) two sensors, each with its own protocol (frame rate, for our purpose).
Now create "server" classes for each sensor instead of an explicit singleton. This way you can hide the details of how your sensors work:
class SensorServer {
protected:
int lastValueSensed;
QThread sensorProtocolThread;
public:
int getSensedValue() { return lastValueSensed; }
}
class Sensor1Server {
public:
Sensor1Server() {
sensorProtocolThread = new Sensor1ProtocolThread(&lastValueSensed);
sensorProtocolThread.start();
}
}
class Sensor1ProtocolThread : public QThread {
protected:
int* valueToUpdate;
const int TIMEOUT = 1000; // "framerate" of our sensor1
public:
Sensor1ProtocolThread( int* vtu ) {
this->valueToUpdate = vtu;
}
void run() {
int valueFromSensor;
// get value from the sensor into 'valueFromSensor'
*valueToUpdate = valueFromSensor;
sleep(TIMEOUT);
}
}
This way you can do away with having to implement a singleton.
Cheers,
jrh.
Just a drive-by analysis but this doesn't smell right.
If the application is "consistently" hanging after 6-7 hours are you sure it isn't a resource (e.g. memory) leak? Is there anything different about the implementation of the problematic protocol from the rest of them? Have you run the app through a memory checker, etc.?
Not sure it's the cause of what you're seeing, but you have a big fat synchronization bug in your code:
void <ProtocolClassName>::run()
{
while(!mStop) //check whether screen is closed or not
{
mutex.lock()
while(!waitcondition.wait(&mutex,5))
{
if(mStop)
return; // BUG: missing mutex.unlock()
}
//Code for receiving and processing incoming data
mutex.unlock();
} //end while
}
better:
void <ProtocolClassName>::run()
{
while(!mStop) //check whether screen is closed or not
{
const QMutexLocker locker( &mutex );
while(!waitcondition.wait(&mutex,5))
{
if(mStop)
return; // OK now
}
//Code for receiving and processing incoming data
} //end while
}