0

hi i have been tryng to implement a timer using posix timer libs, but i am making a mistake in the implemetation, i was using a example from the web and tryng to encapsulating in a class but, the compiler doesnt like it, basically tryng to asign the callback function int the sigev.sigev_notify_function = TIMER0_IRQHandler; but i cannot get any result. Here goes the code:

The class definition:

#include <sys/time.h>
#include <pthread.h>
#include <signal.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
//se agrego para eliminar el siguiente warning del compilador
//warning: incompatible implicit declaration of built-in function 'memset'
#include <string.h> /* memset */
#include <unistd.h> /* close */


#define TIMEVAL_MAX 0xFFFFFFFF
#define TIMEVAL unsigned int
// The timer is incrementing every 4 us.
//#define MS_TO_TIMEVAL(ms) (ms * 250)
//#define US_TO_TIMEVAL(us) (us>>2)

// The timer is incrementing every 8 us.
#define MS_TO_TIMEVAL(ms) ((ms) * 125)
#define US_TO_TIMEVAL(us) ((us)>>3)

class Timer
{
public:
    Timer();
    void initTimer();
    void setTimer(TIMEVAL aValue);
    TIMEVAL getElapsedTime( void ) ;
    void TIMER0_IRQHandler(sigval_t val);
private:
    struct timeval last_sig;
    timer_t timer;

};

and the function that is conflicting with the compiler:

void Timer::initTimer()
{
        struct sigevent sigev;

        // Take first absolute time ref.
        if(gettimeofday(&last_sig,NULL)){
            perror("gettimeofday()");
        }

        memset (&sigev, 0, sizeof (struct sigevent));
        sigev.sigev_value.sival_int = 0;
        sigev.sigev_notify = SIGEV_THREAD;
        sigev.sigev_notify_attributes = NULL;
        sigev.sigev_notify_function = &TIMER0_IRQHandler;

        if( timer_create (CLOCK_REALTIME, &sigev, &timer)) {
            perror("timer_create()");
        }

}
*//callback function
void Timer::TIMER0_IRQHandler(sigval_t val)
{
    if(gettimeofday(&last_sig,NULL)) {
        perror("gettimeofday()");
    }
    printf("TIMER NOTIFY\n");
}

thx in advance!

Ricardo_arg
  • 520
  • 11
  • 28
  • What is the compiler complaining about? *I don't like it* is quite an unusual error message. – Oswald Aug 07 '13 at 18:00
  • 1
    Firstly, it is unclear what your problem is and what you are asking about. Secondly, your code triggers undefined behavior because you [cannot call `printf()` (and other non async-safe functions) from a signal handler](http://lazarenko.me/2013/01/15/how-not-to-write-a-signal-handler/). –  Aug 07 '13 at 18:00
  • Clearly what i want is to set the callback function when i registering the timer, defining the function as not static, that is worng, for what i see in the next response, i have to wrapp it into another function. "The compiler doesnt like it" is just an expresion, in the future i will use the output message from the compiler, i didnt know about printf(). – Ricardo_arg Aug 07 '13 at 18:40

2 Answers2

2

To call a member function, you also need the pointer to this, which means you can't do this directly. You can, however, use a static function as a wrapper for your callback, which can extract the this pointer and call your real callback:

class Timer
{
public:
    static void handler_wrapper(sigval_t val);
    void handler();
};

void Timer::handler_wrapper(sigval_t val)
{
    Timer *object = (Timer *)val.sival_ptr;
    object->handler();
}

void Timer::handler(void)
{
    // do whatever.  just remember what thread context you're in
}

// in main
sigev.sigev_value.sival_ptr = (void*) this;
sigev.sigev_notify_function = &Timer::handler_wrapper;
Peter
  • 14,559
  • 35
  • 55
  • Thx, peter i was reading your code, but what i see, is that the registering process is donde in a function (in my code), not in the main(), so my question is, because timer.h is essencially a C lib, there is a problem if a declared in a function a then used as my will (well not so like that!). The next question is, that in my code i fill with the the function "getTimeofday" a structure that i defined as private and it is used to get the current time, can i do it in the handler function? – Ricardo_arg Aug 07 '13 at 18:47
  • I can't understand this comment. Since this question is finished, try a new question. But please include some code, and any relevant error messages. – Peter Aug 07 '13 at 19:34
0

You can use std::bind to create a function object to pass non-static member functions to be invoked at the end of timer(or timeout).

std::bind(&class_name::mem_func, obj_ptr, args_list ...);

The drawback with this is similar to static member functions, i.e. the thread does not have context of the parent object, although you might be able to run the member function stand-alone (if it doesn't use any parent object attributes). Which is pretty much the same as with static member function, which requires member attributes of the class to be static in case they are required/accessed/used by it.

Note: Pass the object reference (using std::ref) or pointer in arguments and use it in your member function.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83