00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "rcs_defs.hh"
00017 #include "dbg_mem.h"
00018
00019 #ifdef VXWORKS
00020
00021 extern "C"
00022 {
00023 #include <vxWorks.h>
00024
00025 #ifndef NO_STDIO
00026 #include <stdio.h>
00027 #endif
00028
00029 #include <string.h>
00030 #include <stdlib.h>
00031 #include <taskLib.h>
00032 #include <tickLib.h>
00033 #include <sysLib.h>
00034 }
00035
00036 #endif
00037
00038 #ifdef LYNX
00039
00040 extern "C"
00041 {
00042 #include <string.h>
00043 #include <stdlib.h>
00044
00045 #ifndef NO_STDIO
00046 #include <stdio.h>
00047 #endif
00048
00049 #include <stdlib.h>
00050 #include <signal.h>
00051
00052 #include <errno.h>
00053 #include <unistd.h>
00054 #include <time.h>
00055
00056 #include <sys/time.h>
00057
00058
00059
00060 }
00061
00062 #endif
00063
00064 #if defined(SUN) || defined(LINUX)
00065
00066 extern "C"
00067 {
00068 #include <stdlib.h>
00069 #include <string.h>
00070
00071 #ifndef NO_STDIO
00072 #include <stdio.h>
00073 #endif
00074
00075 #include <stdlib.h>
00076 #include <signal.h>
00077
00078 #include <errno.h>
00079 #include <unistd.h>
00080 #include <sys/time.h>
00081
00082
00083 #include <sys/types.h>
00084 #include <sys/wait.h>
00085 }
00086
00087 #endif
00088
00089 #ifdef __MSDOS__
00090 #include <stdlib.h>
00091 #include <string.h>
00092 #include <time.h>
00093 #ifndef _WINDOWS
00094 #include <dos.h>
00095 #endif
00096 #endif
00097
00098 #include "inetfile.hh"
00099
00100 #include "timer.hh"
00101
00102 #define INT(x) ((int) (x))
00103 #define FRAC(x) ((x) - INT(x))
00104
00105
00106 #if (defined (SUN) || defined (LYNX)) && !defined(lynxosVME) && !defined(sunos4CC)
00107
00108
00109 int
00110 itimer_set (double time, int periodic)
00111 {
00112 struct itimerval val;
00113 long secs, usecs;
00114
00115
00116 secs = (long) time;
00117 usecs = (long) ((time - (double) secs) * 1000000.0);
00118 val.it_value.tv_sec = secs;
00119 val.it_value.tv_usec = usecs;
00120 if (periodic == 0)
00121 {
00122 val.it_interval.tv_sec = val.it_interval.tv_usec = 0;
00123 }
00124 else
00125 {
00126 val.it_interval.tv_sec = val.it_value.tv_sec;
00127 val.it_interval.tv_usec = val.it_value.tv_usec;
00128 }
00129 return setitimer (ITIMER_REAL, &val, 0);
00130 }
00131
00132
00133 static void
00134 noaction (...)
00135 {
00136 return;
00137 }
00138
00139
00140 void
00141 itimer_attach (RCS_SIGFUNC function)
00142 {
00143 struct sigaction act;
00144
00145
00146 #ifdef sparcworks_sun4
00147 act.sa_handler =
00148 (void (*)(int,...)) ((function == NULL) ? noaction : function);
00149 #else
00150 #if defined(sparcworks_sun5) || defined(sunos5CC)
00151 act.sa_handler = (void (*)(int)) ((function == NULL) ? noaction : function);
00152 #else
00153 act.sa_handler = ((function == NULL) ? noaction : function);
00154 #endif
00155 #endif
00156 sigfillset (&act.sa_mask);
00157 act.sa_flags = 0;
00158 sigaction (SIGALRM, &act, NULL);
00159 }
00160
00161
00162 void
00163 itimer_wait ()
00164 {
00165 sigset_t mask;
00166
00167
00168 sigfillset (&mask);
00169 sigdelset (&mask, SIGALRM);
00170 sigsuspend (&mask);
00171 }
00172
00173 #endif
00174
00175
00176
00177 RCS_TIMER::RCS_TIMER (char *process_name, char *config_file)
00178 {
00179 #if 0
00180 read_config_file (process_name, config_file);
00181 #endif
00182 }
00183
00184 RCS_TIMER::RCS_TIMER (double _timeout, char *process_name, char *config_file)
00185 {
00186 #if 0
00187 read_config_file (process_name, config_file);
00188 #endif
00189 set_timeout (_timeout);
00190 }
00191
00192 void
00193 RCS_TIMER::set_timeout (double _timeout)
00194 {
00195 timeout = _timeout;
00196 if (timeout < clk_tck ())
00197 {
00198 counts_per_real_sleep = (int) (clk_tck () / _timeout) + 1;
00199 }
00200 else
00201 {
00202 counts_per_real_sleep = 0;
00203 }
00204 }
00205
00206 #if 0
00207 void
00208 RCS_TIMER::read_config_file (char *process_name, char *config_file)
00209 {
00210 zero_timer ();
00211 if (NULL == process_name || NULL == config_file)
00212 {
00213 return;
00214 }
00215 INET_FILE *ifp = inet_file_open (config_file, "r");
00216 if (NULL == ifp)
00217 {
00218 return;
00219 }
00220 int process_name_length = strlen (process_name);
00221 char line[256];
00222 char *token;
00223 while (!inet_file_eof (ifp))
00224 {
00225 inet_file_gets (line, 256, ifp);
00226 token = strtok (line, " \r\n:\t\b,;");
00227 if (line[0] == '#')
00228 {
00229 continue;
00230 }
00231 if (token == NULL)
00232 {
00233 continue;
00234 }
00235 if (strncmp (token, process_name, process_name_length))
00236 {
00237 continue;
00238 }
00239 token = strtok (NULL, " \r\n:\t\b,;");
00240 if (NULL == token)
00241 {
00242 break;
00243 }
00244 timeout = atof (token);
00245 token = strtok (NULL, " \r\n:\t\b,;");
00246 if (NULL == token)
00247 {
00248 break;
00249 }
00250 #if 0
00251 sem_key = strtol (token, NULL, 0);
00252 token = strtok (NULL, " \r\n:\t\b,;");
00253 if (NULL == token)
00254 {
00255 break;
00256 }
00257 num_sems = strtol (token, NULL, 0);
00258 token = strtok (NULL, " \r\n:\t\b,;");
00259 if (NULL == token)
00260 {
00261 break;
00262 }
00263 #endif
00264 id = strtol (token, NULL, 0);
00265 token = strtok (NULL, " \r\n:\t\b,;");
00266 if (NULL == token)
00267 {
00268 break;
00269 }
00270 #if 0
00271 create_sems = strtol (token, NULL, 0);
00272 #endif
00273 }
00274 inet_file_close (ifp);
00275 init (timeout, id);
00276 }
00277 #endif
00278
00279
00280
00281 void
00282 RCS_TIMER::zero_timer ()
00283 {
00284 num_sems = 0;
00285 #if USE_SEMS_FOR_TIMER
00286 sems = NULL;
00287 #endif
00288 id = 0;
00289 function = NULL;
00290 idle = 0.0;
00291 counts = 0;
00292 start_time = etime ();
00293 time_since_real_sleep = start_time;
00294 counts_per_real_sleep = 0;
00295 counts_since_real_sleep = 0;
00296 clk_tck_val = clk_tck ();
00297 timeout = clk_tck_val;
00298 }
00299
00300
00301
00302 void
00303 RCS_TIMER::init (double _timeout, int _id)
00304 {
00305 zero_timer ();
00306 id = _id;
00307 #if 0
00308 num_sems = _num_sems;
00309 int sem_key = _sem_key;
00310 int create_sems = _create_sems;
00311 if (num_sems > 0 && id >= 0 && id < num_sems)
00312 {
00313 sems =
00314 (RCS_SEMAPHORE **) DEBUG_MALLOC (sizeof (RCS_SEMAPHORE *) * num_sems);
00315 for (int i = 0; i < num_sems; i++)
00316 {
00317 sems[i] = new RCS_SEMAPHORE (sem_key + i, create_sems, -1);
00318 }
00319 sems[id]->post ();
00320 poller_pid = fork ();
00321 if (poller_pid == 0)
00322 {
00323 timer_poll (_timeout, sems[id]);
00324 }
00325 }
00326 else
00327 {
00328 num_sems = 0;
00329 }
00330 #endif
00331 set_timeout (_timeout);
00332
00333 }
00334
00335
00336
00337 RCS_TIMER::RCS_TIMER (double _timeout, RCS_TIMERFUNC _function, void *_arg)
00338 {
00339 zero_timer ();
00340 counts_per_real_sleep = 0;
00341 counts_since_real_sleep = 0;
00342
00343 if (_timeout < clk_tck_val)
00344 {
00345 counts_per_real_sleep = (int) (clk_tck_val / _timeout);
00346
00347 timeout = clk_tck_val;
00348 }
00349 else
00350 {
00351 timeout = _timeout;
00352 }
00353 function = _function;
00354 arg = _arg;
00355 last_time = etime ();
00356
00357 idle = 0.0;
00358 counts = 0;
00359 start_time = etime ();
00360 time_since_real_sleep = start_time;
00361 }
00362
00363
00364 void
00365 RCS_TIMER::sync ()
00366 {
00367 last_time = etime ();
00368
00369 }
00370
00371 int
00372 RCS_TIMER::wait ()
00373 {
00374 double interval;
00375 double numcycles;
00376 int missed = 0;
00377 double remaining = 0.0;
00378 double time_in = 0.0;
00379 double time_done = 0.0;
00380
00381 if (function != NULL)
00382 {
00383
00384 time_in = etime ();
00385
00386 if ((*function) (arg) == -1)
00387 {
00388 return -1;
00389 }
00390 time_done = etime ();
00391 }
00392 else
00393 {
00394
00395 time_in = etime ();
00396 }
00397
00398
00399
00400
00401
00402 interval = time_in - last_time;
00403 numcycles = interval / timeout;
00404
00405
00406 counts++;
00407 if (function != NULL)
00408 {
00409 missed = INT (numcycles - (clk_tck_val / timeout));
00410 idle += interval;
00411 last_time = time_done;
00412 }
00413 else
00414 {
00415 missed = INT (numcycles);
00416 remaining = timeout * (1.0 - FRAC (numcycles));
00417 idle += interval;
00418 #if 0
00419 if (counts_per_real_sleep > 0)
00420 {
00421 if (counts_since_real_sleep < counts_per_real_sleep)
00422 {
00423 counts_since_real_sleep++;
00424 if (sems != NULL && num_sems > 0)
00425 {
00426 for (i = id + 1; i < num_sems && !sem_posted; i++)
00427 {
00428 if (i != id && NULL != sems[i])
00429 {
00430 if (sems[i]->post () < 0)
00431 {
00432 delete sems[i];
00433 sems[i] = NULL;
00434 if (i == num_sems - 1)
00435 {
00436 num_sems--;
00437 }
00438 }
00439 else
00440 {
00441 sem_posted = 1;
00442 }
00443 }
00444 }
00445 for (i = 0; i < id && !sem_posted; i++)
00446 {
00447 if (i != id && NULL != sems[i])
00448 {
00449 if (sems[i]->post () < 0)
00450 {
00451 delete sems[i];
00452 sems[i] = NULL;
00453 if (i == num_sems - 1)
00454 {
00455 num_sems--;
00456 }
00457 }
00458 else
00459 {
00460 sem_posted = 1;
00461 }
00462 }
00463 }
00464 if (NULL != sems[id] && sem_posted)
00465 {
00466 if (sems[id]->wait () < 0)
00467 {
00468 delete sems[id];
00469 sems[id] = NULL;
00470 return 0;
00471 }
00472 while (etime () - time_in < remaining)
00473 {
00474 if (sems[id]->wait () < 0)
00475 {
00476 delete sems[id];
00477 sems[id] = NULL;
00478 break;
00479 }
00480 }
00481 for (i = 0; i < num_sems; i++)
00482 {
00483 if (i != id && NULL != sems[i])
00484 {
00485 sems[i]->clear ();
00486 }
00487 }
00488 }
00489 return 0;
00490 }
00491 }
00492 counts_since_real_sleep = 0;
00493 time_since_real_sleep = etime ();
00494 esleep (clk_tck_val);
00495 last_time = etime ();
00496 return missed;
00497 }
00498 #endif
00499 }
00500 esleep (remaining);
00501 last_time = etime ();
00502 return missed;
00503 }
00504
00505 double
00506 RCS_TIMER::load ()
00507 {
00508 if (counts * timeout != 0.0)
00509 return idle / (counts * timeout);
00510 return -1.0;
00511 }
00512
00513 RCS_TIMER::~RCS_TIMER ()
00514 {
00515 #if 0
00516 if (poller_pid > 0)
00517 {
00518 kill (poller_pid, SIGINT);
00519 #ifdef SUN
00520 waitpid (poller_pid, NULL, 0);
00521 #endif
00522 poller_pid = 0;
00523 }
00524 if (NULL != sems)
00525 {
00526 for (int i = 0; i < num_sems; i++)
00527 {
00528 if (sems[i] != NULL)
00529 {
00530 delete sems[i];
00531 }
00532 sems[i] = NULL;
00533 }
00534 DEBUG_FREE (sems);
00535 }
00536 #endif
00537 }