#include <marclock.h>
Public Types | |
typedef MarHW | inherited |
Public Member Functions | |
MarClock (QObject *parent=0) | |
Private Member Functions | |
void | mar_clock () |
void | set_timer_params (double val) |
void | set_timer_grain (double val) |
void | init_clock () |
Static Private Member Functions | |
static void | mar_heartbeat (int) |
static void | start_timer (void(*fcn)(int), int speed) |
static void | enqueue_fcn (void(*fcn)(int), int arg, double dtval) |
static void | clock_heartbeat (int) |
Definition at line 6 of file marclock.h.
typedef MarHW MarClock::inherited |
Reimplemented from MarHW.
Definition at line 12 of file marclock.h.
MarClock::MarClock | ( | QObject * | parent = 0 | ) |
Definition at line 42 of file marclock.cpp.
: inherited(parent) { }
void MarClock::clock_heartbeat | ( | int | ) | [static, private] |
Definition at line 196 of file marclock.cpp.
References block_heartbeat, clq_st::clq_arg, clq_st::clq_fcn, clq_st::clq_ival, clq_st::clq_next, clq_st::clq_prev, clq_st::clq_used, and start_timer().
Referenced by init_clock().
{ clq *qp; if(block_heartbeat == 1) { /* * If the heartbeat is blocked (e.g., by the enqueue_fcn * routine), then we just re-enable the timer to be called * again in 1/5th the normal clock grain. Since functions * which block heartbeat must be quick, this fast time * will cause sucessful execution on the next timer callout. */ start_timer(clock_heartbeat,0); return; } if(clqhead == NULL) { /* * There are no functions queued for execution. Depending * on how the application which uses these routines is * written, this condition may indicate an error. In a * completely clock callout driver application, this should * happen ONLY before the first callout is queued, and never * again. Since there are other ways to use these routines, * we don't flag an error here. */ start_timer(clock_heartbeat,1); return; } /* * Decrement the clq_ival variables in all active queue * entries. Do not decrement any entries whose clq_ival * has already gone to zero. These will executed on a * first come, first served basis. */ for(qp = clqhead; qp != NULL; qp = qp->clq_next) { if(qp->clq_ival > 0) qp->clq_ival--; } /* * Queue the next heartbeat now. */ start_timer(clock_heartbeat,1); /* * Find the first entry in the queue whose clq_ival value * is zero. Unqueue it and execute it. */ for(qp = clqhead; qp != NULL; qp = qp->clq_next) if(qp->clq_ival == 0) { if(qp->clq_prev == NULL) { clqhead = qp->clq_next; if(qp->clq_next != NULL) (qp->clq_next)->clq_prev = NULL; } else { (qp->clq_prev)->clq_next = qp->clq_next; if(qp->clq_next != NULL) (qp->clq_next)->clq_prev = qp->clq_prev; } qp->clq_used = 0; (void) (*qp->clq_fcn)(qp->clq_arg); return; } return; }
void MarClock::enqueue_fcn | ( | void(*)(int) | fcn, |
int | arg, | ||
double | dtval | ||
) | [static, private] |
Definition at line 148 of file marclock.cpp.
References block_heartbeat, clq_st::clq_arg, clq_st::clq_fcn, clq_is_init, clq_st::clq_ival, clq_st::clq_next, clq_st::clq_prev, clq_st::clq_used, heartbeat_grain, i, j, and MAXCLQUEUE.
Referenced by mar_clock(), and mar_heartbeat().
{ int i,j; clq *qp; block_heartbeat = 1; if(clq_is_init == 0) { clqhead = NULL; for(i = 0;i < MAXCLQUEUE; i++) clqueue[i].clq_used = 0; clq_is_init = 1; } for(i = 0;i < MAXCLQUEUE;i++) if(clqueue[i].clq_used == 0) { clqueue[i].clq_used = 1; j = .5 + dtval / heartbeat_grain; if(j == 0) j = 1; clqueue[i].clq_ival = j; clqueue[i].clq_fcn = fcn; clqueue[i].clq_arg = arg; clqueue[i].clq_next = NULL; if(clqhead == NULL) { clqhead = &clqueue[i]; clqueue[i].clq_prev = NULL; block_heartbeat = 0; return; } for(qp = clqhead; ; qp = qp->clq_next) if(qp->clq_next == NULL) { qp->clq_next = &clqueue[i]; clqueue[i].clq_prev = qp; block_heartbeat = 0; return; } } fprintf(stdout,"enqueue_fcn: no more clock queue entries avail\n"); ::exit(1); }
void MarClock::init_clock | ( | ) | [private] |
Definition at line 285 of file marclock.cpp.
References clock_heartbeat(), clq_is_init, heartbeat_grain, i, MAXCLQUEUE, set_timer_params(), and start_timer().
Referenced by mar_clock().
{ int i; if(clq_is_init == 0) { clqhead = NULL; for(i = 0;i < MAXCLQUEUE; i++) clqueue[i].clq_used = 0; clq_is_init = 1; } set_timer_params(heartbeat_grain); start_timer(clock_heartbeat,1); }
void MarClock::mar_clock | ( | ) | [private] |
Definition at line 63 of file marclock.cpp.
References enqueue_fcn(), i, init_clock(), and mar_heartbeat().
{ int i, killtimer = 0; enqueue_fcn(mar_heartbeat,0,1.0); // enqueue_fcn((void (*)(int))get_status,0,1.0); init_clock(); while(killtimer == 0) { pause(); } }
void MarClock::mar_heartbeat | ( | int | ) | [static, private] |
Definition at line 51 of file marclock.cpp.
References enqueue_fcn().
Referenced by mar_clock().
{ /* * Re-enable the timer, and return. */ enqueue_fcn(mar_heartbeat,0,1.0); }
void MarClock::set_timer_grain | ( | double | val | ) | [private] |
Definition at line 136 of file marclock.cpp.
References heartbeat_grain, and set_timer_params().
{ heartbeat_grain = val; set_timer_params(val); }
void MarClock::set_timer_params | ( | double | val | ) | [private] |
Definition at line 82 of file marclock.cpp.
References heartbeat_fast_sec, heartbeat_fast_usec, heartbeat_grain_sec, heartbeat_grain_usec, and i.
Referenced by init_clock(), and set_timer_grain().
{ double x; int i; x = val; i = (int) x; heartbeat_grain_sec = i; x = x - i; if(x < 0) x = 0; i = x * 1000000; heartbeat_grain_usec = i; x = val / 5; /* for the fast timer on heartbeat block */ i = (int) x; heartbeat_fast_sec = i; x = x - i; if(x < 0) x = 0; i = x * 1000000; heartbeat_fast_usec = i; return; }
void MarClock::start_timer | ( | void(*)(int) | fcn, |
int | speed | ||
) | [static, private] |
Definition at line 110 of file marclock.cpp.
References heartbeat_fast_sec, heartbeat_fast_usec, heartbeat_grain_sec, and heartbeat_grain_usec.
Referenced by clock_heartbeat(), and init_clock().
{ struct itimerval tv; tv.it_interval.tv_sec = 0; tv.it_interval.tv_usec = 0; if(speed == 0) { tv.it_value.tv_sec = heartbeat_fast_sec; tv.it_value.tv_usec = heartbeat_fast_usec; } else { tv.it_value.tv_sec = heartbeat_grain_sec; tv.it_value.tv_usec = heartbeat_grain_usec; } signal(SIGALRM,fcn); setitimer(ITIMER_REAL,&tv,NULL); }