Find the answer to your Linux question:
Results 1 to 8 of 8
Like Tree1Likes
  • 1 Post By JohnGraham
I'm trying to get a recurring timer, one that fires every 1/30 of a second. Right now I have this code to support the timer... At program start: Code: tt_spec.it_value.tv_sec ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Linux Newbie Syndacate's Avatar
    Join Date
    May 2012
    Location
    Hell..no literally, this state is hell..
    Posts
    192

    POSIX Recurring Timer Help


    I'm trying to get a recurring timer, one that fires every 1/30 of a second.

    Right now I have this code to support the timer...
    At program start:
    Code:
            tt_spec.it_value.tv_sec = 1;
            tt_spec.it_interval.tv_nsec = REFRESH_NSEC;
    
            struct sigevent sig;
            sig.sigev_notify = SIGEV_SIGNAL;
            sig.sigev_signo = REFRESH_SIG;
            
            timer_create(CLOCK_MONOTONIC, &sig, &refresh_timer_id)
    
            struct sigaction action;
            action.sa_handler = &sig_handler;
            sigaction(REFRESH_SIG, &action, NULL);
    To create the timer, where "refresh_timer_id" is a "timer_t" type which is global and "tt_spec" is of type "itimerspec."

    NOTE: tt_spec.it_value.tv_sec = 1 is just to make the itimerspec struct non-zero, as that's what is apparently required according to the POSIX API for this.

    sig_handler is a function which doesn't do anything at the moment except print that a timer signal was received. It's prototype is as follows (for completeness sake):
    Code:
    void sig_handler(int sig_received);
    The timer is armed as follows:
    Code:
            timer_settime(refresh_timer_id, 0, &drtt_spec, NULL);
    The result I get almost instantly (which is terminating the program with an exit code of 155). When I say almost instantly I mean under a second, but with a varying and seemingly random number of successful signal receptions before-so. The error message it prints before exiting is as follows (btw: It doesn't seem to be dumping the core, this is some kind of 'graceful' quit which I haven't seen before)
    Code:
    ./run.sh: line 10: 20973 Profiling timer expired <path to file>/a.out
    Where "run.sh" is simply a launcher script which sets up some env stuff, and at line 10 it calls the binary (a.out).

    So....anybody have any idea why the hell it keeps quitting almost instantly. If I disable the timer functionality it's fine. There's nothing "wrong" with the signal handler as there's nothing there (empty function now, before it simply had a print statement).

    Thanks, hopefully somebody knows what I'm doing wrong .

  2. #2
    Linux Newbie Syndacate's Avatar
    Join Date
    May 2012
    Location
    Hell..no literally, this state is hell..
    Posts
    192
    lol, I like how my post shows up in the linux forums daily news, but I have no answers .

    C'mon, somebody out there has to know POSIX timers, lol.

  3. #3
    Linux Newbie
    Join Date
    Mar 2010
    Posts
    152
    There are a lot of things that can go wrong with signals, etc. - please post a complete, compilable example that demonstrates the issue you see.
    Programming and other random guff: cat /dev/thoughts > blogspot.com (previously prognix.blogspot.com)

  4. #4
    Linux Newbie Syndacate's Avatar
    Join Date
    May 2012
    Location
    Hell..no literally, this state is hell..
    Posts
    192
    Quote Originally Posted by JohnGraham View Post
    There are a lot of things that can go wrong with signals, etc. - please post a complete, compilable example that demonstrates the issue you see.
    Unfortunately due to "licensing" restrictions (it's not even licensing, but I can't disclose it) I am unable to post that base code...but I can probably throw together an example of something that will do the same thing...

  5. #5
    Linux Newbie
    Join Date
    Mar 2010
    Posts
    152
    Quote Originally Posted by Syndacate View Post
    I can probably throw together an example of something that will do the same thing...
    Yes, that's what I mean - boil it down to the simplest thing that demonstrates the problem. This may also clarify things to yourself. Alternatively, if you can't concoct such an example then you know the problem is probably not directly in your timer code, but something to do with other things in your application (and that's also useful information to post).
    Syndacate likes this.
    Programming and other random guff: cat /dev/thoughts > blogspot.com (previously prognix.blogspot.com)

  6. #6
    Linux Newbie Syndacate's Avatar
    Join Date
    May 2012
    Location
    Hell..no literally, this state is hell..
    Posts
    192
    So I have some good news and some bad news....

    Good news is that i was able to pull out the timer stuff and-reorg it for distribution. Bad news is that the problem doesn't persist.

    Here's the code:
    Code:
    #include <signal.h>
    #include <stdio.h>
    #include <time.h>
    
    #define REFRESH_SIG 27
    #define REFRESH_NSEC (1000000000 / 30)
    
    struct itimerspec t_spec;
    timer_t refresh_timer_id;
    int ij = 0;
    
    void sig_handler(int sig_received)
    {
    	//printf("%d signal received\n", sig_received);
    	ij++;
    	if (ij % 30 == 0)
    		printf("Second passed\n");
    }
    
    int main()
    {
    	t_spec.it_value.tv_sec = 1;
    	t_spec.it_interval.tv_nsec = REFRESH_NSEC;
    
    	struct sigevent sig;
    	sig.sigev_notify = SIGEV_SIGNAL;
    	sig.sigev_signo = REFRESH_SIG;
    
    	if (timer_create(CLOCK_MONOTONIC, &sig, &refresh_timer_id))
    		printf("time_create() failed\n");
    
    	struct sigaction action;
    	action.sa_handler = &sig_handler;
    	sigaction(REFRESH_SIG, &action, NULL);
    
    	timer_settime(refresh_timer_id, 0, &t_spec, NULL);
    
    	while (1);
    }
    The code is virtually identical (albeit variable names, where stuff is located, etc. is a bit different, but the operation is identical, I promise).

    I noticed, though, that when I made this code, that I was using the wrong units for what I thought was nanoseconds. I was using microseconds instead. This code has that updated.

    Perhaps it was going too fast and I was getting a weird timing force. I'll have to let you guys know later what happened with it, until then, I'm not sure if the problem persists...I had to create a work-around timer in the meanwhile using a different system and I just tried switching it back but something else was giving me issues and I need to go to work now -.-.

    Thanks, I'll post back when I know more, but if you see any issues with the way I set that timer up, do tell!

    EDIT:
    Making the refresh rate come on as microseconds / 30 instead of nanoseconds / 30 means the timer was running 1000x faster than I intended (33MS vs 33,333MS firing interval). It's definitely possible the issue was there and they were coming in too quickly..

  7. #7
    Linux Newbie
    Join Date
    Mar 2010
    Posts
    152
    When I run your code, I get a segmentation fault until I initialize things to zero - i.e. on the appropriate lines:

    Code:
    struct itimerspec t_spec = {{0}};
    timer_t refresh_timer_id = {0};
    // ...
    struct sigevent sig = {{0}};
    // ...
    struct sigaction action = {{0}};
    It is very possible your problems are the result of these values containing garbage, which would change depending on random factors and would explain why you can't get it to fail in the same way in a simple test program.
    Programming and other random guff: cat /dev/thoughts > blogspot.com (previously prognix.blogspot.com)

  8. #8
    Linux Newbie Syndacate's Avatar
    Join Date
    May 2012
    Location
    Hell..no literally, this state is hell..
    Posts
    192
    Quote Originally Posted by JohnGraham View Post
    When I run your code, I get a segmentation fault until I initialize things to zero - i.e. on the appropriate lines:

    Code:
    struct itimerspec t_spec = {{0}};
    timer_t refresh_timer_id = {0};
    // ...
    struct sigevent sig = {{0}};
    // ...
    struct sigaction action = {{0}};
    It is very possible your problems are the result of these values containing garbage, which would change depending on random factors and would explain why you can't get it to fail in the same way in a simple test program.
    This is possible, and yeah, uninitialized variables is a newb mistake that I should have considered, but I've never seen it be a problem in the past - at least not like this. Either way, it's proper coding standards (at least in my book) to init all vars...but I suppose you get lazy over the years or something. I don't even think about it at work because the code analyzer will pick it up, heh. Gotta get my coding standards together here!!

    Never-the-less, I'll have to make those changes and see the results accordingly. Especially now that it's 1000x slower than it used to be.

    What OS are you running that it seg faulted, and if it's not too much trouble, can you just throw a gdb debug hook in there and tell me which statement it's crashing on?

    ..

    It'll be a bit before I get back here with any real findings. Essentially won't have a dev machine until 4/14 and I'm not entirely sure how useful my mobile dev machine will be, never used it for this type of stuff (CUDA). Also don't know how quick the internet will be if I need to connect to my dev machine :-\.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •