gcc 4.4.3
vc++ 2008
I would like to make a timer application would be portable on windows and linux. However, would be suffice to start with.
My idea is to start a timer and set it for a specified number of seconds. When the time expires call a callback function.
Is that the best way to do this?
Many thanks,
There are many ways to do a timer. It is not hard but you need to think exactly what you want. If you want to call a callback, you usually use a thread that sleep until your delay is elapsed, before calling your callback. If you don't want to use a thread, you can call periodically a checker function that compute the time delta.
You api will be a function taking the delay and a function pointer plus the callback parameters. It will launch a thread that will sleep for the delay, then call the callback with the given parameters.
Check general purpose libraries, they usually have timers implemented (gtk+ glib, boost::timer I think).
my2c
Edit:
For the portability part, you have of course to write two versions of your timer function. If you use thread that means it is better to use a lib. As libs give you timers ... Use a lib :)
Windows and linux do timers differently. I suggest that you encapsulate the timing functionality into a class. You'll have to write the class twice (once for each platform) but then the rest of the program can be the same.
Alternatively you can use a toolkit where somebody else gas already done it for you. e.g. QT or Boost.
I have worked with several such timers in both C and C++. For C GTK example on the following url may be helpful http://zetcode.com/tutorials/gtktutorial/gtkevents/. In C++ I used glib timer https://developer.gnome.org/glibmm/2.34/classGlib_1_1SignalTimeout.html (although it is not precise). I also work with libev (which uses epoll() on Linux and select() on Windows) for better precision timer. For C, I present an example below
//This program is demo for using pthreads with libev.
//Try using Timeout values as large as 1.0 and as small as 0.000001
//and notice the difference in the output
//(c) 2013 enthusiasticgeek for stack overflow
//Free to distribute and improve the code. Leave credits intact
//On Ubuntu (assuming libev is installed) compile with the command - gcc -g test.c -o test -lev
#include <ev.h>
#include <stdio.h> // for printf
#include <stdlib.h>
double timeout = 1.0; //seconds
ev_timer timeout_watcher;
int timeout_count = 0;
static void timeout_cb (EV_P_ ev_timer *w, int revents) // Timer callback function
{
++timeout_count;
printf("%d\n", timeout_count);
w->repeat = timeout;
ev_timer_again(loop, &timeout_watcher); //Start the timer again.
}
int main (int argc, char** argv)
{
struct ev_loop *loop = EV_DEFAULT; //or ev_default_loop (0);
ev_timer_init (&timeout_watcher, timeout_cb, timeout, 0.); // Non repeating timer. The timer starts repeating in the timeout callback function
ev_timer_start (loop, &timeout_watcher);
// now wait for events to arrive
ev_loop(loop, 0);
return 0;
}
For more docs on libev view http://doc.dvgu.ru/devel/ev.html
Related
Is it possible (preferably in an OS-independent fashion, although I happen to be using Windows) to request a timer interrupt in a userspace program?
Here is some pseudo-code which may illustrate what kind of functionality I'm looking for:
#include <time_library_x.h> //For setHandler() and set_timer_for_ms()
void timerInterruptHandler() {
update_something();
set_timer_for_ms(50);
}
void main() {
setHandler(timerInterruptHandler);
set_timer_for_ms(50);
while(1) {
very_boring_data_collection();
}
}
Anyone know what "library x" is?
In Windows, there is Timers object to create Timer object and register callback function.
In Linux using SIGALRM and setitimer is common to implement timer things, but I have not seen such libraries which integrates those for mult-platform use.
Windows Timers Example : https://msdn.microsoft.com/en-us/library/windows/desktop/ms644901(v=vs.85).aspx
Is there any function in C to check if the computer is going to sleep,hibernate or locked and waking up from these state?
In msdn they provided for C#, C++ but not for C.
My OS is windows7
Like below is the code I'm using to check the time duration between starting the program and terminating it(shutting down the system will terminate the program so this way time duration can be measured).
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include<time.h>
clock_t start_time=0;
void bye (void)
{
FILE *read,*write;
write=fopen("F:\\count.txt","w");
clock_t end_time=clock();
fprintf(write,"Time: %d",(end_time-start_time)/CLOCKS_PER_SEC);
fclose(write);
}
int main (void)
{
start_time=clock();
atexit (bye);
//exit (EXIT_SUCCESS);
getch();
}
In the same way I want to check for locked/sleep/hibernate.
One possible way to wrap the c++ code(provided in the link) in c as mentioned by #ddriver
But is it not possible in C at all?
The WinAPI has generally at least the same possibilities as .NET framework. What your are asking for is the PowerManagement API.
You will have to register to receive PowerSettingNotificationEvents with the RegisterPowerSettingNotification function. Unfortunately, it is used differently for a GUI application where you give a handle to a window that will then receive a WM_POWERBROADCAST message each time the system is about to change state (one of the suspend modes or the hibernate mode), and for a non GUI (typically a service) that registers a HandlerEx callback with a dwControl parameter of SERVICE_CONTROL_POWEREVENT and a dwEventType of PBT_POWERSETTINGCHANGE.
The link you provide is about signals, emitted when power mode is changing. So, obviously, you can check when the system is about to go to sleep, or it just woke up.
As of checking if the system currently sleeps, that is simply not possible, as user code will simply not be running during deep sleep states. Maybe some platform specific, very low level BIOS API, but those are usually not public, and far from portable.
I should write a linux device driver code that periodically print an information. This information should be printed until the module will be unloaded. I should write something like this
int boolean = 1;
static int hello_init(void)
{
while(boolean){
printk(KERN_ALERT "An information\n");
msleep(1000);
}
return 0;
}
static void hello_exit(void)
{
boolean=0;
printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
Obviously, this code doesn't work (I suppose because __init and __exit can't work concurrently, so the boolean value cannot change). Can anyone help me to solve this problem?
If the task you are performing periodically needs to go to sleep, you may not be able to use timer functions. Delayed workqueues can be used in that situation -- they are not as precise as the hrtimer but if the timing requirements aren't too strict, they work just fine.
I recently posted a question about doing things periodically here:
Calling spi_write periodically in a linux driver
I posted a workqueue example in it that you may find useful.
I also found this documentation to be helpful:
http://www.makelinux.net/ldd3/chp-7-sect-6
However, some changes have been made to the API since it was published. This article outlines these changes:
http://lwn.net/Articles/211279/
You should set up a timer with hrtimer_start() at the hello_init().
The struct hrtimer *timer contains a function pointer what will be called at the time you set. That callback function should contains the printk(). You have to renew the timer each time the callback called.
Don't forget to call the hrtimer_cancel() at the hello_exit().
You can use the ktime_set() function to calculate the expire time you want. Have a look here, there are some related and useful functions: High-resolution timers
Inspired by the last leap second, I've been exploring timing (specifically, interval timers) using POSIX calls.
POSIX provides several ways to set up timers, but they're all problematic:
sleep and nanosleep—these are annoying to restart after they're interrupted by a signal, and they introduce clock skew. You can avoid some, but not all, of this skew with some extra work, but these functions use the realtime clock, so this isn't without pitfalls.
setitimer or the more modern timer_settime—these are designed to be interval timers, but they're per-process, which is a problem if you need multiple active timers. They also can't be used synchronously, but that's less of a big deal.
clock_gettime and clock_nanosleep seem like the right answer when used with CLOCK_MONOTONIC. clock_nanosleep supports absolute timeouts, so you can just sleep, increment the timeout, and repeat. It's easy to restart after an interruption that way, too. Unfortunately, these functions might as well be Linux-specific: there's no support for them on Mac OS X or FreeBSD.
pthread_cond_timedwait is available on the Mac and can work with gettimeofday as a kludgy workaround, but on the Mac it can only work with the realtime clock, so it's subject to misbehavior when the system clock is set or a leap second happens.
Is there an API I'm missing? Is there a reasonably portable way to create well-behaved interval timers on UNIX-like systems, or does this sum up the state of things today?
By well-behaved and reasonably portable, I mean:
Not prone to clock skew (minus, of course, the system clock's own skew)
Resilient to the system clock being set or a leap second occurring
Able to support multiple timers in the same process
Available on at least Linux, Mac OS X, and FreeBSD
A note on leap seconds (in response to R..'s answer):
POSIX days are exactly 86,400 seconds long, but real-world days can rarely be longer or shorter. How the system resolves this discrepancy is implementation-defined, but it's common for the leap second to share the same UNIX timestamp as the previous second. See also: Leap Seconds and What To Do With Them.
The Linux kernel leap second bug was a result of failing to do housekeeping after setting the clock back a second: https://lkml.org/lkml/2012/7/1/203. Even without that bug, the clock would have jumped backwards one second.
kqueue and kevent can be utilized for this purpose. OSX 10.6 and FreeBSD 8.1 add support for EVFILT_USER, which we can use to wake up the event loop from another thread.
Note that if you use this to implement your own condition and timedwait, you do not need locks in order to avoid race conditions, contrary to this excellent answer, because you cannot "miss" an event on the queue.
Sources:
FreeBSD man page
OS X man page
kqueue tutorial
libevent source code
Example Code
Compile with clang -o test -std=c99 test.c
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
// arbitrary number used for the identifier property
const int NOTIFY_IDENT = 1337;
static int kq;
static void diep(const char *s) {
perror(s);
exit(EXIT_FAILURE);
}
static void *run_thread(void *arg) {
struct kevent kev;
struct kevent out_kev;
memset(&kev, 0, sizeof(kev));
kev.ident = NOTIFY_IDENT;
kev.filter = EVFILT_USER;
kev.flags = EV_ADD | EV_CLEAR;
struct timespec timeout;
timeout.tv_sec = 3;
timeout.tv_nsec = 0;
fprintf(stderr, "thread sleep\n");
if (kevent(kq, &kev, 1, &out_kev, 1, &timeout) == -1)
diep("kevent: waiting");
fprintf(stderr, "thread wakeup\n");
return NULL;
}
int main(int argc, char **argv) {
// create a new kernel event queue
kq = kqueue();
if (kq == -1)
diep("kqueue()");
fprintf(stderr, "spawn thread\n");
pthread_t thread;
if (pthread_create(&thread, NULL, run_thread, NULL))
diep("pthread_create");
if (argc > 1) {
fprintf(stderr, "sleep for 1 second\n");
sleep(1);
fprintf(stderr, "wake up thread\n");
struct kevent kev;
struct timespec timeout = { 0, 0 };
memset(&kev, 0, sizeof(kev));
kev.ident = NOTIFY_IDENT;
kev.filter = EVFILT_USER;
kev.fflags = NOTE_TRIGGER;
if (kevent(kq, &kev, 1, NULL, 0, &timeout) == -1)
diep("kevent: triggering");
} else {
fprintf(stderr, "not waking up thread, pass --wakeup to wake up thread\n");
}
pthread_join(thread, NULL);
close(kq);
return EXIT_SUCCESS;
}
Output
$ time ./test
spawn thread
not waking up thread, pass --wakeup to wake up thread
thread sleep
thread wakeup
real 0m3.010s
user 0m0.001s
sys 0m0.002s
$ time ./test --wakeup
spawn thread
sleep for 1 second
thread sleep
wake up thread
thread wakeup
real 0m1.010s
user 0m0.002s
sys 0m0.002s
POSIX timers (timer_create) do not require signals; you can also arrange for the timer expiration to be delivered in a thread via the SIGEV_THREAD notification type. Unfortunately glibc's implementation actually creates a new thread for each expiration (which both has a lot of overhead and destroys any hope of realtime-quality robustness) despite the fact that the standard allows reuse of the same thread for each expiration.
Short of that, I would just recommend making your own thread that uses clock_nanosleep with TIMER_ABSTIME and CLOCK_MONOTONIC for an interval timer. Since you mentioned that some broken systems might lack these interfaces, you could simply have a drop-in implementation (based e.g. on pthread_cond_timedwait) on such systems, and figure it might be lower-quality due to lack of monotonic clock, but that this is just a fundamental limitation of using a low-quality implementation like MacOSX.
As for your concern about leap seconds, if ntpd or similar is making your realtime clock jump backwards when a leap second occurs, that's a serious bug in ntpd. POSIX time (seconds since the epoch) are in units of calendar seconds (exactly 1/86400 of a day) per the standard, not SI seconds, and thus the only place leap second logic belongs on a POSIX system (if anywhere) is in mktime/gmtime/localtime when they convert between time_t and broken-down time. I haven't been following the bugs that hit this time, but they seem to have resulted from system software doing a lot of stupid and wrong stuff, not from any fundamental issue.
You can look at the question here for clock_gettime emulation, which I've also supplied an answer for, but helped me as well. I've recently added a simple timer to a little repository I keep for Mac OS X timing that partially emulates POSIX calls. A simple test runs the timer at 2000Hz. The repo is called PosixMachTiming. Try it out.
PosixMachTiming is based on Mach. It seems some of the timing-related Mach API has disappeared from Apple's pages and has deprecated, but there are still bits of source code floating around. It looks like AbsoluteTime units and kernel abstractions found here are the new way of doing things. Anyways the PosixMachTiming repo still works for me.
Overview of PosixMachTiming
clock_gettime is emulated for CLOCK_REALTIME by a mach function calls that tap into the system realtime clock, dubbed CALENDAR_CLOCK.
The clock_gettime is emulated for CLOCK_MONOTONIC by using a global variable (extern mach_port_t clock_port). This clock is initialized when the computer turns on or maybe wakes up. I'm not sure. In any case, it's the global variable that the function mach_absolute_time() calls.
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, ...) is emulated by using nanosleep on the difference between current time and the absolute monotonic time.
itimer_start() and itimer_step() are based on calling clock_nanosleep for a target absolute monotonic time. It increments the target time by the time-step at each iteration (not the current time) so that clock skew is not an issue.
Note that this does not satisfy your requirement to be able to support multiple timers in the same process.
There's also the new CLOCK_TAI which doesn't take the leap second corrections the real time clocks do.
We can make use of timer_create () or timerfd_create () .
Their examples are present in man page .
How does one create a timer in C?
I want a piece of code to continuously fetch data from a gps parsers output.
Are there good libraries for this or should it be self written?
Simplest method available:
#include <pthread.h>
void *do_smth_periodically(void *data)
{
int interval = *(int *)data;
for (;;) {
do_smth();
usleep(interval);
}
}
int main()
{
pthread_t thread;
int interval = 5000;
pthread_create(&thread, NULL, do_smth_periodically, &interval)
...
}
On POSIX systems you can create (and catch) an alarm. Alarm is simple but set in seconds. If you need finer resolution than seconds then use setitimer.
struct itimerval tv;
tv.it_interval.tv_sec = 0;
tv.it_interval.tv_usec = 100000; // when timer expires, reset to 100ms
tv.it_value.tv_sec = 0;
tv.it_value.tv_usec = 100000; // 100 ms == 100000 us
setitimer(ITIMER_REAL, &tv, NULL);
And catch the timer on a regular interval by setting sigaction.
One doesn't "create a timer in C". There is nothing about timing or scheduling in the C standard, so how that is accomplished is left up to the Operating System.
This is probably a reasonable question for a C noob, as many languages do support things like this. Ada does, and I believe the next version of C++ will probably do so (Boost has support for it now). I'm pretty sure Java can do it too.
On linux, probably the best way would be to use pthreads. In particular, you need to call pthread_create() and pass it the address of your routine, which presumably contains a loop with a sleep() (or usleep()) call at the bottom.
Note that if you want to do something that approximates real-time scheduling, just doing a dumb usleep() isn't good enough because it won't account for the execution time of the loop itself. For those applications you will need to set up a periodic timer and wait on that.
SDL provides a cross platform timer in C.
http://www.libsdl.org/cgi/docwiki.cgi/SDL_AddTimer
If your using Windows, you can use SetTimer,else you can build a timer out of timeGetTime and _beginthreadex along with a queue of timers with callbacks
The question about a timer is quite unspecific, though there are two functions that come to my mind that will help you:
sleep() This function will cause execution to stop for a specified number of seconds. You can also use usleep and nanosleep if you want to specify the sleeptime more exactly
gettimeofday() Using this function you are able to stop between to timesteps.
See manpages for further explanation :)
If the gps data is coming from some hardware device, like over a serial port, then one thing that you may consider is changing the architecture around so that the parser kicks off the code that you are trying to run when more data is available.
It could do this through a callback function or it could send an event - the actual implementation would depend on what you have available.