Creating a 1 second interval in C++

duragezic

Lifer
Oct 11, 1999
11,234
4
81
I haven't been able to do timing in C/C++ very well the few times I was required to do it (such as timing execution in clock ticks or milliseconds). I never could get a good grasp on what timer to use since there is a lot of ways to do it, as well as platform specific ones such as linux timer functions.


So what I need to do is create a 1 second interval. This would be so easy on a microcontroller! It would go like:

while (some condition)
// do a lot of stuff, so it's not like a simple ISR
end while

I need to run through a bunch of code inside that while loop once per second. I have no idea how long that code will take to run, so it's not like I can delay for the remaining time of one second each iteration.

Any ideas on how to do this and what timer function I should use? It needs to be very close to 1 second (a few clock ticks difference won't matter but 1.1 seconds wouldn't be acceptable).
 

DaveSimmons

Elite Member
Aug 12, 2001
40,730
670
126
Sounds like a job for threads. Start / restart a worker thread once a second, have the main thread go back to sleep immediately.

Or interrupts, set a timer interrupt, (re)start the worker thread whenever it fires.

The only tricky part is knowing not to (re)start the worker thread on a tick if its old work wasn't completed for some reason.
 

xtknight

Elite Member
Oct 15, 2004
12,974
0
71
Something like this:

while (1)
{
Thread thread = new Thread(workerFunction);
usleep(1000000);
thread.terminate();
}
 

duragezic

Lifer
Oct 11, 1999
11,234
4
81
Thanks for the replies all.

LintMan: Indeed, gettimeofday() was my first idea to accomplish this. I've used it once before but don't completely understand it all. I think gettimeofday() returns a timeval struct and then I need to access its fields to get the current seconds or microseconds. I'll have to look up the documentation.

DaveSimmons and xtknight: That's a neat idea and kinda helpful since my thread knowledge is weak. I'll be using pthreads btw. So I believe I'd use the following pthread functions:

Thread thread = new Thread(workerFunction) EQUIVALENT TO: pthread_create(&<thread ID>, NULL, job, (void*) data) // data is a struct for parameters if I need to pass any
thread.terminate() EQUIVALENT TO: pthread.join(<thread ID>, NULL).


One question on that solution, would I necessarily need to create a new worker thread every iteration, or can I create it once and basically restart it?

I'm trying to think if I'd lose any values I'd need to keep between iterations, or if passing it a struct parameter that's a global variable would take care of that. I might need quite a lot of variables for the worker thread to work on and save their values each iteration, such as pointers to several structures and/or classes.

Maybe I should just use vfork() so I get a child process that can use the parent's variables? It would be more costly for the context switch though. And as you said, it would be tough to know if the worker thread has completed its old work. But in my case, it HAS to be complete and do it again precisely every second since it is for a Monte Carlo simulation. I believe that I'll have a lot of code to do in the one second interval (very rough guess of 50-75 lines). They will mostly be fairly basic instructions (shouldn't need MUL/DIV or I/O access), but it's likely I'll have a lot of IFs (branches) so I guess I better make damn well sure I can do everything within the second everytime.
 

DaveSimmons

Elite Member
Aug 12, 2001
40,730
670
126
A pointer to a shared, persistent structure would work, and could prevent memory leak and heap fragmentation issues.

Just starting a new thread is easier than recycling, but it could work if the worker thread can block when it's complete and restart when the parent unblocks it.

I'm a Win32 developer so I don't know how you'd approach that in linux.
 

HigherGround

Golden Member
Jan 9, 2000
1,827
0
0
threads? talk about non-deterministic :) I'm going to suggest a simpler, a little more 'classic' multiplexed IO approach. I wrote this in vi, on top of it I haven't written anything in C++ in years, so excuse the mess and potential errors. Obviously, it's quite simplistic, but it also should be fairly easy to extend. If you have any questions, don't hesitate to ask.