Monday, October 19, 2009

millisecond tick in C++

To compile run
g++ -l pthread -o millisecondtick millisecondtick.cpp

Turned out I had to use one static member function to jump off onto another to get up and running.

/* millisecondtick.cpp
 * Creates Millisecond Tick 
 */

#include 
#include 
#include 

#include "millisecondtick.h"

MilliSecond_Tick::MilliSecond_Tick(){
   Running = FALSE;
};



void* MilliSecond_Tick::runx(void *pMilliSecond_Tick){

    ((MilliSecond_Tick*)pMilliSecond_Tick)->run(NULL);
}



int MilliSecond_Tick::start( pFnVoid func ){

pFnVoidVoid  prun;

 
  prun = runx;
 
   if (MilliSecond_Tick::Running != FALSE){
     printf("Error MilliSecond_Tick already started, can not start second instance\n");
     return 0 ;
   }

  callback = func;
  pthread_create(&tid, NULL, prun , this);
    Running = TRUE;

  return 0;
}




void MilliSecond_Tick::stop(){
MilliSecond_Tick::Running = FALSE;
pthread_join(tid, NULL);

}


void MilliSecond_Tick::tick(){
  (*callback)(); 
}


void* MilliSecond_Tick::run(void * nothing){

    struct sched_param sparam;

    sparam.sched_priority = sched_get_priority_max(SCHED_FIFO);
    if (pthread_setschedparam(pthread_self(), SCHED_FIFO, &sparam) == 0) {
                        // success, this application has sufficient privileges
    }
    else {
            // setting priority failed, probably due to insufficient privieges
    }

    for (;;) {                           // for-ever loop of the ticker thread
        static const struct timespec nanowait = {0, 0*1000*1000};    // 1 ms
        nanosleep(&nanowait, (struct timespec *)0);

     if (Running == FALSE){
        break;
 }

        tick();
    }
}



void tickss( ){
 static int x = 0, y = 0;
x++;
  if (x > 1000){
     x = 0;
     y++;
     printf(">%d\n",y);
     } 
}



int main(){

 MilliSecond_Tick cmt;

 cmt.start(&tickss );

 sleep(10);
 cmt.stop();

}

// millisecondtick.h

#include 

#define TRUE 1
#define FALSE 0 

typedef void(*pFnVoid)();
typedef void*(*pFnVoidVoid)( void *);

class MilliSecond_Tick
{
  private:
    int  Running;
    pFnVoid callback; 
    pthread_t tid;
    static void *runx(void *pMilliSecond_Tick);
    void tick();
  public:

  MilliSecond_Tick(); 
  ~MilliSecond_Tick(){};
  int start( pFnVoid func ) ;
  void stop(); 
  void * run(void * nothing);
};

No comments: