Search code examples
c++multithreadingpthreadspreemptive

How to implement Priority Preemptive Scheduling (similar to interrupts) with threads in C++


I want to write a C++ program on Windows (but preferably to support cross-platform) in which I have two threads that are scheduled based on Priority Preemptive Scheduling - which is like an interrupt behavior (when the interrupt occurs, the main thread pauses wherever it is and only when the interrupt thread goes back to sleep the main thread will resume from where it was paused).

These are the threads:

  1. Thread T_main
  2. Thread T_interrupt.

T_main runs all the time in a while loop. T_interrupt is supposed to be executed once every second and it does something very quick.

The code in T_main is rather large (thousands of lines of code).

It must be extremely time accurate.

I want that when the time comes for the T_interrupt thread to run, it will be prioritized so that it will run without interruption until it finishes and only then the thread T_main will resume from where it paused.

If you are wondering what I am trying to do then here is a basic explanation: Basically, I am running a simulation of my embedded project. I mocked my entire hardware and I want to run my application on a simulator on the PC. The purpose is to test the logic implementation of my application. Compiler differences and other imperfections are taken into consideration. What is critical for me is to be able to simulate a 1-second tick timer based interrupt that exists on my MCU. I am finding it difficult to simulate this behavior as thread scheduling seems to be cooperative and not preemptive.

I tried using priorities and setting scheduling methods such as Round Robin SCHED_RR or FIFO SCHED_FIFO but in all cases the scheduling implementation is still cooperative and not preemptive.

Here is my code:

#include <iostream>
#include <thread>
#include <pthread.h>
#include <string>

using namespace std;

void MainApplicationFunc(void)
{
    // Infinite loop in which the app is running
    while(1)
    {
        MainProgram();
    }
}

void TickTimerInterruptFunc()
{
    while(1)
    {
        TickTimer();
        std::this_thread::sleep_for(1s);
    }
}

void setScheduling(std::thread &th, int policy, int priority)
{
    sched_param sch_params;
    sch_params.sched_priority = priority;
    if(pthread_setschedparam(th.native_handle(), policy, &sch_params))
    {
        std::cerr << "Failed to set Thread scheduling" << std::endl;
    }
}

int main()
{
    std::thread T_interrupt(TickTimerInterruptFunc);
    setScheduling(T_interrupt, SCHED_FIFO, 1);
    std::thread T_main(MainApplicationFunc);
    setScheduling(T_main, SCHED_FIFO, 20);

    T_main.join();
    T_interrupt.join();
}

Solution

  • I found several solutions for this issue and I thought I'd share them here for everybody else. Throughout stackoverflow I found others who asked similar questions to this one and there are several possible solutions.

    Possible Solutions to Implement interrupt behavior with threads:

    1. Force a context switch on your thread. I found some useful reference to how to do this on Windows as depicted in FreeRTOS Windows Simulator. For me personally, this seems to be the best option. Moreover, I might just use this simulator instead of building my own.
    2. Write a windows driver as mentioned here: https://stackoverflow.com/a/13819216/4441211
    3. Use SuspendThread and ResumeThread. Although when using this method you should be aware that they are async in nature as depicted here so this is not ideal.