Have a timer restart every 100ms in C / C++ - c++

I am working with a application where the requirement is execute a function after every 100ms.
Below is my code
checkOCIDs()
{
// Do something that might take more than 100ms of time
}
void TimeOut_CallBack(int w)
{
struct itimerval tout_val;
int ret = 0;
signal(SIGALRM,TimeOut_CallBack);
/* Configure the timer to expire after 100000 ... */
tout_val.it_value.tv_sec = 0;
tout_val.it_value.tv_usec = 100000; /* 100000 timer */
/* ... and every 100 msec after that. */
tout_val.it_interval.tv_sec = 0 ;
tout_val.it_interval.tv_usec = 100000;
checkOCIDs();
setitimer(ITIMER_REAL, &tout_val,0);
return ;
}
Function TimeOut_CallBack ( ) is called only once and then on checkOCIDs( ) function must be executed after a wait of 100ms continuously.
Currently, The application is going for a block as checkOCIDs( ) function takes more than 100ms of time to complete and before that the Timer Out is triggered.
I do not wish to use while(1) with sleep( ) / usleep( ) as it eats up my CPU enormously.
Please suggest a alternative to achieve my requirement.

It is not clear whether the "check" function should be executed while it is in progress and timer expires. Maybe it would be ok to you to introduce variable to indicate that timer expired and your function should be executed again after it completes, pseudo-code:
static volatile bool check_in_progress = false;
static volatile bool timer_expired = false;
void TimeOut_CallBack(int w)
{
// ...
if (check_in_progress) {
timer_expired = true;
return;
}
// spawn/resume check function thread
// ...
}
void checkThreadProc()
{
check_in_progress = true;
do {
timer_expired = false;
checkOCIDs();
} while(timer_expired);
check_in_progress = false;
// end thread or wait for a signal to resume
}
Note, that additional synchronization may be required to avoid race conditions (for instance when one thread exists do-while loop and check_in_progress is still set and the other sets timer_expired, check function will not be executed), but that's depends on your requirements details.

Related

How to allocate a period of time for a thread to execute?

I have a class executing in a thread.
But I only want to allow it to run for 10 seconds.
Note... I have no means of passing any boolean into the class to stop execution.
So, How can I set up a thread to terminate after 10 seconds?
The class I am testing has potential infinite recursion that may take place and it is pointless to let it run longer than 10 seconds.
TEST_METHOD(TM_ClientServer_Threads)
{
bool bDone = false;
int ii = 0;
std::thread tCounter([&bDone, &ii]()
{
// Black Box: can't touch this; can't pass in a Boolean
while(true)
{
ii++;
}
}
);
std::thread tTimer([&bDone, &tCounter]()
{
Sleep(1000);
bDone = true;
// kill the tCounter thread ?
}
);
tCounter.join();
tTimer.join();
ii = ii + 0; // break point here
}

detached std::thread on esp32 arduino sometimes blocks, sometimes doesn't

I have some code running on ESP32 microcontroller with arduino core,
In the setup() function I wish to have some code threadPressureCalib run independently in its own thread, so I do the following:
std::unique_ptr<std::thread> sensorCalib;
void setup()
{
sensorCalib.reset(new std::thread(threadPressureCalib));
std::thread* pc = sensorCalib.get();
pc->detach();
}
void loop()
{
...
}
Then, I define threadPressureCalib() as follows:
void threadPressureCalib()
{
float pressure=0;
int count;
for(timestarted = millis();(millis()-timestarted) < 10000;)
{ // THIS ONE BLOCKS SETUP() AND LOOP() CODE EXECUTION
Serial.println("Doing things");
}
Serial.println("Doing other things");
for (count=1; count<= 5;count++)
{ //THIS ONE DOES NOT BLOCK SETUP() and LOOP()
float temp;
while(!timer2.Delay(2000)); //Not sure if this is blocking anything
do{
temp = adc_pressure();
}while(temp>104.0 || temp<70.0); //Catch errors
pressure += temp;
}
changeSetting(pressure/5.0);
return;
}
Problem: During the first for loop, the setup() function's execution is stopped (as well as loop())
During the second for loop, nothing is stopped and the rest of the code runs in parallel (as expected)
Why is it that the first half of this code blocks, and then the second half does not?
Sorry if the question is vague or improperly asked, my first q here.
Explanation of timer2 per request in comments:
timer2 is a custom timer class, timer2.Delay(TIMEOUT) stores timestamp the first time it's called and returns false on every subsequent call until the current time = TIMEOUT, then it returns true and resets itself
NonBlockDelay timer2;
//time delay function (time in seconds to delay)
// Set iTimeout to current millis plus milliseconds to wait for
/**
* Called with milliseconds to delay.
* Return true if timer expired
*
*/
//Borrowed from someone on StackOverflow...
bool NonBlockDelay::Delay (unsigned long t)
{
if(TimingActive)
{
if((millis() >iTimeout)){
TimingActive = 0;
return(1);
}
return(0);
}
iTimeout = millis() + t;
TimingActive = 1;
return(0);
};
// returns true if timer expired
bool NonBlockDelay::Timeout (void)
{
if(TimingActive){
if((millis() >iTimeout)){
TimingActive = 0;
iTimeout = 0;
return(1);
}
}
return(false);
}
// Returns the current timeout value in milliseconds
unsigned long NonBlockDelay::Time(void)
{
return iTimeout;
}
There is not enough information here to tell you the answer but it seems that you have no idea what you are doing.
std::unique_ptr<std::thread> sensorCalib;
void setup(){
sensorCalib.reset(new std::thread(threadPressureCalib));
std::thread* pc = sensorCalib.get();
pc->detach();
}
So here you store a new thread that executes threadPressureCalib then immediately detach it. Once the thread is detached the instance std::thread no longer manages it. So what's the point of even having std::unique_ptr<std::thread> sensorCalib; in the first place if it literally does nothing? Do you realize that normally you need to join the thread if you wish to wait till it's completion? Could it be that you just start a bunch of instances of these threadPressureCalib - as you probably don't verify that they finished execution - and they interfere with each other?

ESP-IDF How to ckeck if task is already running?

I have a job that should be ran with minimum interval of 5 seconds. Trigger that starts this job can be executed in any moment and in any frequency.
What is the best way to solve such a case in RTOS environment?
I want to make a function that creates a task if it does not exist. Existing task should wait for minimum interval to pass before doing anything. While it is waiting, function that should create it should skip the creation of a new task.
What is the right way to check if task was created but didn't finish yet?
Should I use tasks at all in this case?
Code example below:
#define CONFIG_MIN_INTERVAL 5000
uint32_t last_execution_timestamp = 0;
TaskHandle_t *task_handle = NULL;
bool task_done = true;
static void report_task(void *context)
{
if (esp_timer_get_time() / 1000 < last_execution_timestamp + CONFIG_MIN_INTERVAL)
{
ESP_LOGI(stateTAG, "need to wait for for right time");
int time_to_wait = last_execution_timestamp + CONFIG_MIN_INTERVAL - esp_timer_get_time() / 1000;
vTaskDelay(time_to_wait / portTICK_PERIOD_MS);
}
// do something...
task_done = true;
vTaskDelete(task_handle);
}
void init_report_task(uint32_t context)
{
if (!task_done)
{
ESP_LOGI(stateTAG, "TASK already exists");
}
else
{
ESP_LOGI(stateTAG, "Creating task");
xTaskCreate(&report_task, "report_task", 8192, (void *)context, 4, task_handle);
task_done = false;
}
}
eTaskGetState can be used to check if a task is already running, but such a solution can be susceptible to races. For example your task is technically still "running" when it's in fact "finishing", i.e. setting task_done = true; and preparing for exit.
A better solution could be to use a queue (or a semaphore) and have the task run continuously, waiting for the messages to arrive and processing them in a loop.
Using a semaphore, you can do xSemaphoreTake(sem, 5000 / portTICK_PERIOD_MS); to wait for either a wake-up condition or a timeout of 5 seconds, whichever comes first.
== EDIT ==
if there is no events task should wait. Only if event happens it should run the job. It should run it immediately if there was no execution in past 5 seconds. If there was an execution it should wait until 5 seconds since last execution and only then run it
You can achieve that by carefully managing the semaphore's ticks to wait. Something like this (untested):
TickType_t nextDelay = portMAX_DELAY;
TickType_t lastWakeup = 0;
const TickType_t minDelay = 5000 / portTICK_PERIOD_MS;
for (;;) {
bool signalled = xSemaphoreTake(sem, nextDelay);
TickType_t now = (TickType_t)(esp_timer_get_time() / (portTICK_PERIOD_MS * 1000));
if (signalled) {
TickType_t ticksSinceLastWakeup = now - lastWakeup;
if (ticksSinceLastWakeup < minDelay) {
// wakeup too soon - schedule next wakeup and go back to sleep
nextDelay = minDelay - ticksSinceLastWakeup;
continue;
}
}
lastWakeup = now;
nextDelay = portMAX_DELAY;
// do work ...
}

How to determine which thread is done

I have a loop which calls pthread_join but the order of the loop does not match the order of thread's termination.
how can i monitor thread completion then call join?
for ( int th=0; th<sections; th++ )
{
cout<<"start joining "<<th<<endl<<flush;
result_code = pthread_join( threads[th] , (void**)&status);
cout<<th<<" join error "<<strerror(result_code)<<endl<<flush;
cout<<"Join status is "<<status<<endl<<flush;
}
This is my solution, which seems to maximize multi-threading throughput by serving the first
done thread . This solution does not depend on pthread_join loop order.
// loop & wait for the first done thread
std::bitset<Nsections> ready;
std::bitset<Nsections> done;
ready.reset();
for (unsigned b=0; b<sections; b++) ready.flip(b);
done = ready;
unsigned currIdx = 1;
int th = 0;
int th_= 0;
int stat;
while ( done.any() )
{
// main loops waiting for 1st thread to complete.
// completion is checked by global vector
// vStatus (singlton write protected)
// and not by pthread_exit returned value,
// in ordder to maximize throughput by
// post processig the first
// finished thread.
if ( (obj.vStatus).empty() ) { Sleep (5); continue; }
while ( ready.any() )
{
if ( sections == 1 ) break;
if ( !(obj.vStatus).empty() )
{
if ( currIdx <= (obj.vStatus).size() )
{
th_ = currIdx-1;
std::string s =
ready.to_string<char,std::string::traits_type,std::string::allocator_type>();
cout<<"checking "<<th_<<"\t"<<s<<"\t"
<<(ready.test(th_)?"T":"F")<<"\t"<<(obj.vStatus)[th_].retVal <<endl;
if ((obj.vStatus)[th_].retVal < 1)
{
if (ready.test(th_))
{
th=th_;
ready.reset(th);
goto retry;
}
}
}
}
Sleep (2);
} // while ready
retry:
cout<<"start joining "<<th<<endl<<flush;
result_code = pthread_join( threads[th] , (void**)&status);
switch (result_code)
{
case EDEADLK: goto retry; break;
case EINVAL:
case ESRCH:
case 0:
currIdx++;
stat = status->retVal;
free (status);
done.reset(th);
std::string s =
done.to_string<char,std::string::traits_type,std::string::allocator_type>();
cout<<"joined thread "<<th<<"\t"<<s<<"\t"
<<(done.test(th)?"T":"F")<<"\t"<<stat <<endl;
while (true)
{
auto ret=pthread_cancel ( threads[th] ) ;
if (ret == ESRCH) { netTH--; break; }
Sleep (20);
}
break;
}
How can I monitor thread completion then call join ?
By letting join detect the completion. (i.e. do nothing special)
I have a loop which calls pthread_join but the order of the loop does not match the order of thread's termination.
The order of the loop does not matter.
a) thread[main] calling thread[1].'join' will simply be suspended until thread[1] exits. After that, thread[main] will be allowed to continue with the rest of the loop.
b) When thread[2] terminates before thread[1], thread[main] calling thread[2].join simply returns immediately. Again, thread[main] continues.
c) The effort to ensure thread[1] terminates prior to thread[2] (to match the loop sequence) is a surprisingly time consuming effort, with no benefit.
Update in progress ... looking for code I thought I have already submitted.

EnterCriticalSection Deadlocking

I found some code that claimed to be able to make a thread sleep for an accurate amount of time. Testing the code out, it seems to work great, however it always deadlocks after a short amount of time.
Here is the original code. I put prints before entering and leaving the critical section, and saw that sometimes it leaves or enters twice in a row. It seems to deadlock at the EnterCriticalSection call within the Wait function.
Is there a way I can modify this code to retain its functionality while not deadlocking?
//----------------------------------------------------------------
class PreciseTimer
{
public:
PreciseTimer() : mRes(0), toLeave(false), stopCounter(-1)
{
InitializeCriticalSection(&crit);
mRes = timeSetEvent(1, 0, &TimerProc, (DWORD)this,
TIME_PERIODIC);
}
virtual ~PreciseTimer()
{
mRes = timeKillEvent(mRes);
DeleteCriticalSection(&crit);
}
///////////////////////////////////////////////////////////////
// Function name : Wait
// Description : Waits for the required duration of msecs.
// : Timer resolution is precisely 1 msec
// Return type : void :
// Argument : int timeout : timeout in msecs
///////////////////////////////////////////////////////////////
void Wait(int timeout)
{
if ( timeout )
{
stopCounter = timeout;
toLeave = true;
// this will do the actual delay - timer callback shares
// same crit section
EnterCriticalSection(&crit);
LeaveCriticalSection(&crit);
}
}
///////////////////////////////////////////////////////////////
// Function name : TimerProc
// Description : Timer callback procedure that is called
// : every 1msec
// : by high resolution media timers
// Return type : void CALLBACK :
// Argument : UINT uiID :
// Argument : UINT uiMsg :
// Argument : DWORD dwUser :
// Argument : DWORD dw1 :
// Argument : DWORD dw2 :
///////////////////////////////////////////////////////////////
static void CALLBACK TimerProc(UINT uiID, UINT uiMsg, DWORD
dwUser, DWORD dw1, DWORD dw2)
{
static volatile bool entered = false;
PreciseTimer* pThis = (PreciseTimer*)dwUser;
if ( pThis )
{
if ( !entered && !pThis->toLeave ) // block section as
// soon as we can
{
entered = true;
EnterCriticalSection(&pThis->crit);
}
else if ( pThis->toLeave && pThis->stopCounter == 0 )
// leave section
// when counter
// has expired
{
pThis->toLeave = false;
entered = false;
LeaveCriticalSection(&pThis->crit);
}
else if ( pThis->stopCounter > 0 ) // if counter is set
// to anything, then
// continue to drop
// it...
--pThis->stopCounter;
}
}
private:
MMRESULT mRes;
CRITICAL_SECTION crit;
volatile bool toLeave;
volatile int stopCounter;
};
A deadlock in EnterCriticalSection() usually means that another thread called EnterCriticalSection() but never called LeaveCriticalSection().
As shown, this code is not very thread-safe (and timeSetEvent() is a threaded timer). If multiple PreciseTimer timers are running at the same time, they are using the same TimerProc() callback, and thus are sharing the same entered variable without protecting it from concurrent access. And if multiple threads call Wait() on the same PreciseTimer object at the same time, they are going to step over each other's use of the stopCounter and toLeave members, which are also not protected them from concurrent access. Even a single thread calling Wait() on a single PreciseTimer is not safe since TimerProc() runs in its own thread and stopCounter is not adequately protected.
This code is full of race conditions.