Go to the documentation of this file.00001 #include "marclock.h"
00002
00003 #include <stdio.h>
00004 #include <signal.h>
00005 #include <sys/time.h>
00006 #include <unistd.h>
00007 #include <stdlib.h>
00008
00009 #define MAXCLQUEUE 100
00010 #define HEART_GRAIN (0.1)
00011
00012 int heartbeat_grain_sec = 0;
00013 int heartbeat_grain_usec = 100000;
00014 int heartbeat_fast_sec = 0;
00015 int heartbeat_fast_usec = 20000;
00016
00017 struct clq_st {
00018 int clq_used;
00019 int clq_ival;
00020 struct clq_st *clq_prev;
00021 struct clq_st *clq_next;
00022 void (*clq_fcn)(int);
00023 int clq_arg;
00024 };
00025
00026 typedef struct clq_st clq;
00027
00028 clq *clqhead;
00029 clq clqueue[MAXCLQUEUE];
00030 int block_heartbeat;
00031 int clq_is_init = 0;
00032
00033 double heartbeat_grain = HEART_GRAIN;
00034
00035
00036
00037
00038
00039
00040
00041
00042 MarClock::MarClock(QObject *parent)
00043 : inherited(parent)
00044 {
00045 }
00046
00047
00048
00049
00050 void
00051 MarClock::mar_heartbeat(int)
00052 {
00053
00054
00055
00056 enqueue_fcn(mar_heartbeat,0,1.0);
00057 }
00058
00059
00060
00061
00062 void
00063 MarClock::mar_clock()
00064 {
00065 int i, killtimer = 0;
00066
00067 enqueue_fcn(mar_heartbeat,0,1.0);
00068
00069
00070 init_clock();
00071
00072 while(killtimer == 0) {
00073 pause();
00074 }
00075 }
00076
00077
00078
00079
00080
00081 void
00082 MarClock::set_timer_params(double val)
00083 {
00084 double x;
00085 int i;
00086
00087 x = val;
00088 i = (int) x;
00089 heartbeat_grain_sec = i;
00090 x = x - i;
00091 if(x < 0) x = 0;
00092 i = x * 1000000;
00093 heartbeat_grain_usec = i;
00094
00095 x = val / 5;
00096 i = (int) x;
00097 heartbeat_fast_sec = i;
00098 x = x - i;
00099 if(x < 0) x = 0;
00100 i = x * 1000000;
00101 heartbeat_fast_usec = i;
00102
00103 return;
00104 }
00105
00106
00107
00108
00109 void
00110 MarClock::start_timer(void (*fcn)(int), int speed)
00111 {
00112 struct itimerval tv;
00113
00114 tv.it_interval.tv_sec = 0;
00115 tv.it_interval.tv_usec = 0;
00116 if(speed == 0)
00117 {
00118 tv.it_value.tv_sec = heartbeat_fast_sec;
00119 tv.it_value.tv_usec = heartbeat_fast_usec;
00120 }
00121 else
00122 {
00123 tv.it_value.tv_sec = heartbeat_grain_sec;
00124 tv.it_value.tv_usec = heartbeat_grain_usec;
00125 }
00126
00127 signal(SIGALRM,fcn);
00128
00129 setitimer(ITIMER_REAL,&tv,NULL);
00130 }
00131
00132
00133
00134
00135 void
00136 MarClock::set_timer_grain(double val)
00137 {
00138 heartbeat_grain = val;
00139
00140 set_timer_params(val);
00141 }
00142
00143
00144
00145
00146
00147 void
00148 MarClock::enqueue_fcn(void (*fcn)(int), int arg, double dtval)
00149 {
00150 int i,j;
00151 clq *qp;
00152
00153 block_heartbeat = 1;
00154 if(clq_is_init == 0)
00155 {
00156 clqhead = NULL;
00157 for(i = 0;i < MAXCLQUEUE; i++)
00158 clqueue[i].clq_used = 0;
00159 clq_is_init = 1;
00160 }
00161 for(i = 0;i < MAXCLQUEUE;i++)
00162 if(clqueue[i].clq_used == 0)
00163 {
00164 clqueue[i].clq_used = 1;
00165 j = .5 + dtval / heartbeat_grain;
00166 if(j == 0) j = 1;
00167 clqueue[i].clq_ival = j;
00168 clqueue[i].clq_fcn = fcn;
00169 clqueue[i].clq_arg = arg;
00170 clqueue[i].clq_next = NULL;
00171 if(clqhead == NULL)
00172 {
00173 clqhead = &clqueue[i];
00174 clqueue[i].clq_prev = NULL;
00175 block_heartbeat = 0;
00176 return;
00177 }
00178 for(qp = clqhead; ; qp = qp->clq_next)
00179 if(qp->clq_next == NULL)
00180 {
00181 qp->clq_next = &clqueue[i];
00182 clqueue[i].clq_prev = qp;
00183 block_heartbeat = 0;
00184 return;
00185 }
00186 }
00187 fprintf(stdout,"enqueue_fcn: no more clock queue entries avail\n");
00188 ::exit(1);
00189 }
00190
00191
00192
00193
00194
00195 void
00196 MarClock::clock_heartbeat(int)
00197 {
00198 clq *qp;
00199
00200 if(block_heartbeat == 1)
00201 {
00202
00203
00204
00205
00206
00207
00208
00209
00210 start_timer(clock_heartbeat,0);
00211
00212 return;
00213 }
00214
00215 if(clqhead == NULL)
00216 {
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 start_timer(clock_heartbeat,1);
00228
00229 return;
00230 }
00231
00232
00233
00234
00235
00236
00237
00238 for(qp = clqhead; qp != NULL; qp = qp->clq_next)
00239 {
00240 if(qp->clq_ival > 0)
00241 qp->clq_ival--;
00242 }
00243
00244
00245
00246
00247
00248 start_timer(clock_heartbeat,1);
00249
00250
00251
00252
00253
00254
00255 for(qp = clqhead; qp != NULL; qp = qp->clq_next)
00256 if(qp->clq_ival == 0)
00257 {
00258 if(qp->clq_prev == NULL)
00259 {
00260 clqhead = qp->clq_next;
00261 if(qp->clq_next != NULL)
00262 (qp->clq_next)->clq_prev = NULL;
00263 }
00264 else
00265 {
00266 (qp->clq_prev)->clq_next = qp->clq_next;
00267 if(qp->clq_next != NULL)
00268 (qp->clq_next)->clq_prev = qp->clq_prev;
00269 }
00270
00271 qp->clq_used = 0;
00272
00273 (void) (*qp->clq_fcn)(qp->clq_arg);
00274
00275 return;
00276 }
00277 return;
00278 }
00279
00280
00281
00282
00283
00284 void
00285 MarClock::init_clock()
00286 {
00287 int i;
00288
00289 if(clq_is_init == 0)
00290 {
00291 clqhead = NULL;
00292 for(i = 0;i < MAXCLQUEUE; i++)
00293 clqueue[i].clq_used = 0;
00294 clq_is_init = 1;
00295 }
00296
00297 set_timer_params(heartbeat_grain);
00298
00299 start_timer(clock_heartbeat,1);
00300 }