21 #include "../include/tscope5/timer.h"
22 #include "../include/tscope5/timer_internal.h"
23 #include "../include/tscope5/system_internal.h"
28 #elif defined TS5_MACOSX
30 #include <sys/resource.h>
31 #include <sys/types.h>
33 #elif defined TS5_LINUX
36 #include <sys/resource.h>
65 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_priority(%d)\n", priority);
67 int oldval = _ts5_status.timer.priority;
72 h = GetCurrentProcess();
76 if (priority == TS5_HIGH_PRIORITY) {
77 priorityclass = HIGH_PRIORITY_CLASS;
79 else if (priority == TS5_ABOVE_NORMAL_PRIORITY) {
80 priorityclass = ABOVE_NORMAL_PRIORITY_CLASS;
82 else if (priority == TS5_NORMAL_PRIORITY) {
83 priorityclass = NORMAL_PRIORITY_CLASS;
85 else if (priority == TS5_BELOW_NORMAL_PRIORITY) {
86 priorityclass = BELOW_NORMAL_PRIORITY_CLASS;
88 else if (priority == TS5_LOW_PRIORITY) {
89 priorityclass = IDLE_PRIORITY_CLASS;
92 ts5_fatal(
"ts5_set_priority: unknown priority requested\n");
95 if (!SetPriorityClass(h, priorityclass)) {
96 ts5_fatal(
"ts5_set_priority: can't change program priority\n");
99 #elif defined TS5_MACOSX
100 if (geteuid() != 0) {
101 ts5_fatal(
"%s: %s, %s\n",
"ts5_set_priority",
"not running as root",
102 "can't change program priority");
105 int priorityclass = 0;
107 if (priority == TS5_HIGH_PRIORITY) {
110 else if (priority == TS5_ABOVE_NORMAL_PRIORITY) {
113 else if (priority == TS5_NORMAL_PRIORITY) {
116 else if (priority == TS5_BELOW_NORMAL_PRIORITY) {
119 else if (priority == TS5_LOW_PRIORITY) {
123 ts5_fatal(
"ts5_set_priority: unknown priority requested\n");
126 if (setpriority(PRIO_PGRP, 0, priorityclass)) {
127 ts5_fatal(
"ts5_set_priority: can't change program priority\n");
131 #elif defined TS5_LINUX
132 if (geteuid() != 0) {
133 ts5_fatal(
"%s: %s, %s\n",
"ts5_set_priority",
"not running as root",
134 "can't change program priority");
141 if (priority == TS5_HIGH_PRIORITY) {
144 else if (priority == TS5_ABOVE_NORMAL_PRIORITY) {
147 else if (priority == TS5_NORMAL_PRIORITY) {
150 else if (priority == TS5_BELOW_NORMAL_PRIORITY) {
153 else if (priority == TS5_LOW_PRIORITY) {
158 ts5_fatal(
"ts5_set_priority: unknown priority requested\n");
161 if (setpriority(PRIO_PGRP, 0, priorityclass)) {
162 ts5_fatal(
"ts5_set_priority: can't change program priority\n");
167 _ts5_status.timer.priority = priority;
181 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_priority()\n");
183 return _ts5_status.timer.priority;
211 ts5_log(TS5_LOGLEVEL_5,
"ts5_get_time()\n");
213 return al_get_time();
223 ts5_log(TS5_LOGLEVEL_5,
"ts5_wait(%f)\n", waittime);
226 double starttime = al_get_time();
228 if (waittime > 0.02) {
229 while (al_get_time() < starttime + waittime - 0.02) {
234 while (al_get_time() < starttime+waittime) {
246 ts5_log(TS5_LOGLEVEL_5,
"ts5_wait_until(%f)\n", deadline);
249 double starttime = al_get_time();
251 if (deadline - starttime > 0.02) {
252 while (al_get_time() < deadline - 0.02) {
257 while (al_get_time() < deadline) {
311 ts5_log(TS5_LOGLEVEL_3,
"ts5_hide_response_button(%d)\n", button);
313 TS5_TIMER_STATUS *timer = &_ts5_status.timer;
315 if (button<0 || button>timer->num_defined_buttons) {
316 ts5_fatal(
"%s: %s %d, %s %d\n",
"ts5_hide_response_button",
317 "button argument is", button,
318 "number of defined buttons is",
319 timer->num_defined_buttons);
329 if (timer->voicekey_is_response_device) {
331 for (i=0; i<timer->voicekey.num_buttons; i++) {
333 timer->voicekey.button_press_active[i] =
334 timer->voicekey.button_press_defined[i];
336 timer->voicekey.button_release_active[i] =
337 timer->voicekey.button_release_defined[i];
340 timer->voicekey.num_active_buttons =
341 timer->voicekey.num_defined_buttons;
344 if (timer->mouse_is_response_device) {
346 for (i=0; i<timer->mouse.num_buttons; i++) {
348 timer->mouse.button_press_active[i] =
349 timer->mouse.button_press_defined[i];
351 timer->mouse.button_release_active[i] =
352 timer->mouse.button_release_defined[i];
355 timer->mouse.num_active_buttons =
356 timer->mouse.num_defined_buttons;
359 if (timer->keyboard_is_response_device) {
361 for (i=0; i<timer->keyboard.num_buttons; i++) {
363 timer->keyboard.button_press_active[i] =
364 timer->keyboard.button_press_defined[i];
366 timer->keyboard.button_release_active[i] =
367 timer->keyboard.button_release_defined[i];
370 timer->keyboard.num_active_buttons =
371 timer->keyboard.num_defined_buttons;
374 if (timer->joystick_is_response_device) {
376 for (i=0; i<timer->num_joysticks; i++) {
378 for (j=0; j<timer->joystick[i].num_buttons; j++) {
380 timer->joystick[i].button_press_active[j] =
381 timer->joystick[i].button_press_defined[j];
383 timer->joystick[i].button_release_active[j] =
384 timer->joystick[i].button_release_defined[j];
386 timer->joystick[i].num_active_buttons =
387 timer->joystick[i].num_defined_buttons;
391 if (timer->cedrusbox_is_response_device) {
393 for (i=0; i<timer->num_cedrusboxes; i++) {
395 for (j=0; j<timer->cedrusbox[i].num_buttons; j++) {
397 timer->cedrusbox[i].button_press_active[j] =
398 timer->cedrusbox[i].button_press_defined[j];
400 timer->cedrusbox[i].button_release_active[j] =
401 timer->cedrusbox[i].button_release_defined[j];
403 timer->cedrusbox[i].num_active_buttons =
404 timer->cedrusbox[i].num_defined_buttons;
408 if (timer->parport_is_response_device) {
410 for (i=0; i<timer->num_parports; i++) {
412 for (j=0; j<timer->parport[i].num_buttons; j++) {
414 timer->parport[i].button_press_active[j] =
415 timer->parport[i].button_press_defined[j];
417 timer->parport[i].button_release_active[j] =
418 timer->parport[i].button_release_defined[j];
420 timer->parport[i].num_active_buttons =
421 timer->parport[i].num_defined_buttons;
425 timer->num_active_buttons =
426 timer->num_defined_buttons;
432 if (timer->voicekey_is_response_device) {
434 for (i=0; i<timer->voicekey.num_buttons; i++) {
436 if (button==timer->voicekey.button_press_active[i]) {
437 timer->voicekey.button_press_active[i] = 0;
440 else if (button==timer->voicekey.button_release_active[i]) {
441 timer->voicekey.button_release_active[i] = 0;
446 timer->voicekey.num_active_buttons--;
447 timer->num_active_buttons--;
453 if (timer->mouse_is_response_device) {
455 for (i=0; i<timer->mouse.num_buttons; i++) {
457 if (button==timer->mouse.button_press_active[i]) {
458 timer->mouse.button_press_active[i] = 0;
461 else if (button==timer->mouse.button_release_active[i]) {
462 timer->mouse.button_release_active[i] = 0;
467 timer->mouse.num_active_buttons--;
468 timer->num_active_buttons--;
474 if (timer->keyboard_is_response_device) {
476 for (i=0; i<timer->keyboard.num_buttons; i++) {
478 if (button==timer->keyboard.button_press_active[i]) {
479 timer->keyboard.button_press_active[i] = 0;
482 else if (button==timer->keyboard.button_release_active[i]) {
483 timer->keyboard.button_release_active[i] = 0;
488 timer->keyboard.num_active_buttons--;
489 timer->num_active_buttons--;
495 if (timer->joystick_is_response_device) {
497 for (i=0; i<timer->num_joysticks; i++) {
499 for (j=0; j<timer->joystick[i].num_buttons; j++) {
501 if (button==timer->joystick[i].button_press_active[j]) {
502 timer->joystick[i].button_press_active[j] = 0;
505 else if (button==timer->joystick[i].button_release_active[j]) {
506 timer->joystick[i].button_release_active[j] = 0;
511 timer->joystick[i].num_active_buttons--;
512 timer->num_active_buttons--;
519 if (timer->cedrusbox_is_response_device) {
521 for (i=0; i<timer->num_cedrusboxes; i++) {
523 for (j=0; j<timer->cedrusbox[i].num_buttons; j++) {
525 if (button==timer->cedrusbox[i].button_press_active[j]) {
526 timer->cedrusbox[i].button_press_active[j] = 0;
529 else if (button==timer->cedrusbox[i].button_release_active[j]){
530 timer->cedrusbox[i].button_release_active[j] = 0;
535 timer->cedrusbox[i].num_active_buttons--;
536 timer->num_active_buttons--;
543 if (timer->parport_is_response_device) {
545 for (i=0; i<timer->num_parports; i++) {
547 for (j=0; j<timer->parport[i].num_buttons; j++) {
549 if (button==timer->parport[i].button_press_active[j]) {
550 timer->parport[i].button_press_active[j] = 0;
553 else if (button==timer->parport[i].button_release_active[j]){
554 timer->parport[i].button_release_active[j] = 0;
559 timer->parport[i].num_active_buttons--;
560 timer->num_active_buttons--;
571 ts5_fatal(
"ts5_hide_response_button: response button %d not found\n", button);
574 if (timer->num_active_buttons<1) {
575 ts5_fatal(
"%s: %s\n",
"ts5_hide_response_button",
576 "there are no active response buttons left");
579 return timer->num_active_buttons;
589 ts5_log(TS5_LOGLEVEL_3,
"ts5_remove_response_buttons()\n");
591 TS5_TIMER_STATUS *timer = &_ts5_status.timer;
596 if (timer->voicekey_is_response_device) {
598 for (i=0; i<timer->voicekey.num_buttons; i++) {
600 timer->voicekey.button_press_defined[i] = 0;
601 timer->voicekey.button_press_active[i] = 0;
602 timer->voicekey.button_release_defined[i] = 0;
603 timer->voicekey.button_release_active[i] = 0;
606 timer->voicekey_is_response_device = 0;
610 if (timer->mouse_is_response_device) {
612 for (i=0; i<timer->mouse.num_buttons; i++) {
614 timer->mouse.button_press_defined[i] = 0;
615 timer->mouse.button_press_active[i] = 0;
616 timer->mouse.button_release_defined[i] = 0;
617 timer->mouse.button_release_active[i] = 0;
620 timer->mouse_is_response_device = 0;
624 if (timer->keyboard_is_response_device) {
626 for (i=0; i<timer->keyboard.num_buttons; i++) {
628 timer->keyboard.button_press_defined[i] = 0;
629 timer->keyboard.button_press_active[i] = 0;
630 timer->keyboard.button_release_defined[i] = 0;
631 timer->keyboard.button_release_active[i] = 0;
634 timer->keyboard_is_response_device = 0;
638 if (timer->joystick_is_response_device) {
640 for (i=0; i<timer->num_joysticks; i++) {
642 for (j=0; j<timer->joystick[i].num_buttons; j++) {
644 timer->joystick[i].button_press_defined[j] = 0;
645 timer->joystick[i].button_press_active[j] = 0;
646 timer->joystick[i].button_release_defined[j] = 0;
647 timer->joystick[i].button_release_active[j] = 0;
651 timer->joystick_is_response_device = 0;
655 if (timer->joystick_is_response_device) {
657 for (i=0; i<timer->num_joysticks; i++) {
659 for (j=0; j<timer->joystick[i].num_buttons; j++) {
661 timer->joystick[i].button_press_defined[j] = 0;
662 timer->joystick[i].button_press_active[j] = 0;
663 timer->joystick[i].button_release_defined[j] = 0;
664 timer->joystick[i].button_release_active[j] = 0;
668 timer->joystick_is_response_device = 0;
672 if (timer->cedrusbox_is_response_device) {
674 for (i=0; i<timer->num_cedrusboxes; i++) {
676 for (j=0; j<timer->cedrusbox[i].num_buttons; j++) {
678 timer->cedrusbox[i].button_press_defined[j] = 0;
679 timer->cedrusbox[i].button_press_active[j] = 0;
680 timer->cedrusbox[i].button_release_defined[j] = 0;
681 timer->cedrusbox[i].button_release_active[j] = 0;
684 timer->cedrusbox_is_response_device = 0;
687 timer->num_defined_buttons=0;
688 timer->num_active_buttons=0;
698 ts5_log(TS5_LOGLEVEL_5,
"ts5_flush_responses()\n");
700 al_flush_event_queue(_ts5_data.timer.response_queue);
720 ts5_log(TS5_LOGLEVEL_6,
"ts5_check_response(%p,%p)\n",
721 resptime, timing_error);
726 TS5_TIMER_STATUS *timer = &_ts5_status.timer;
728 if (!al_get_next_event(_ts5_data.timer.response_queue, &event)) {
730 if (resptime!=NULL) {
731 *resptime = al_get_time();
733 if (timing_error!=NULL) {
739 if (resptime!=NULL) {
740 *resptime =
event.any.timestamp;
743 if (timing_error!=NULL) {
750 if (timer->voicekey_is_response_device) {
752 if (timer->voicekey.num_active_buttons) {
754 if (event.type==TS5_EVENT_VOICEKEY_BUTTON_DOWN) {
755 resp = timer->voicekey
756 .button_press_active[
event.user.data2-1];
759 if (event.type==TS5_EVENT_VOICEKEY_BUTTON_UP) {
760 resp = timer->voicekey
761 .button_release_active[
event.user.data2-1];
764 if (resp && resptime!=NULL) {
765 *resptime = ((double)event.user.data3)/1000000.0;
772 if (timer->mouse_is_response_device) {
774 if (timer->mouse.num_active_buttons) {
776 if (event.type==ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) {
779 .button_press_active[
event.mouse.button-1];
782 if (event.type==ALLEGRO_EVENT_MOUSE_BUTTON_UP) {
784 .button_release_active[
event.mouse.button-1];
790 if (timer->keyboard_is_response_device) {
792 if (timer->keyboard.num_active_buttons) {
794 if (event.type==ALLEGRO_EVENT_KEY_DOWN) {
795 resp = timer->keyboard
796 .button_press_active[
event.keyboard.keycode-1];
799 if (event.type==ALLEGRO_EVENT_KEY_UP) {
800 resp = timer->keyboard
801 .button_release_active[
event.keyboard.keycode-1];
807 if (timer->joystick_is_response_device) {
809 for (i=0; i<timer->num_joysticks; i++) {
811 if (timer->joystick[i].num_active_buttons) {
813 if (event.type==ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN) {
815 ALLEGRO_JOYSTICK *stick = al_get_joystick(i);
817 if (event.joystick.id == stick) {
818 resp = timer->joystick[i]
819 .button_press_active[
event.joystick.button];
823 if (event.type==ALLEGRO_EVENT_JOYSTICK_BUTTON_UP) {
825 ALLEGRO_JOYSTICK *stick = al_get_joystick(i);
827 if (event.joystick.id == stick) {
828 resp = timer->joystick[i]
829 .button_release_active
830 [
event.joystick.button];
838 if (timer->cedrusbox_is_response_device) {
840 for (i=0; i<timer->num_cedrusboxes; i++) {
842 if (timer->cedrusbox[i].num_active_buttons) {
844 if (event.type==TS5_EVENT_CEDRUSBOX_BUTTON_DOWN) {
846 if (event.user.data1 == i) {
847 resp = timer->cedrusbox[i]
848 .button_press_active[
event.user.data2];
852 if (event.type==TS5_EVENT_CEDRUSBOX_BUTTON_UP) {
854 if (event.user.data1 == i) {
855 resp = timer->cedrusbox[i]
856 .button_release_active[
event.user.data2];
860 if (resp && timing_error!=NULL) {
861 *timing_error = ((double)event.user.data3)/1000000.0;
868 if (timer->parport_is_response_device) {
870 for (i=0; i<timer->num_parports; i++) {
872 if (timer->parport[i].num_active_buttons) {
874 if (event.type==TS5_EVENT_PARPORT_BUTTON_DOWN) {
876 if (event.user.data1 == i) {
877 resp = timer->parport[i]
878 .button_press_active[
event.user.data2-1];
882 if (event.type==TS5_EVENT_PARPORT_BUTTON_UP) {
884 if (event.user.data1 == i) {
885 resp = timer->parport[i]
886 .button_release_active[
event.user.data2-1];
890 if (resp && timing_error!=NULL) {
891 *timing_error = ((double)event.user.data3)/1000000.0;
915 ts5_log(TS5_LOGLEVEL_5,
"ts5_wait_for_response(%p,%p)\n",
916 resptime, timing_error);
944 ts5_log(TS5_LOGLEVEL_5,
"ts5_wait_for_response_timed(%p,%p,%f)\n",
945 resptime, timing_error, maxtime);
948 ts5_fatal(
"ts5_wait_for_response_timed: maxtime is negative (%f)\n",
952 int resp=0, deadline=0;
953 double starttime = al_get_time();
955 while (!resp && !deadline) {
959 if (al_get_time()-starttime>=maxtime) {
984 ts5_log(TS5_LOGLEVEL_5,
"ts5_wait_for_response_until(%p,%p,%f)\n",
985 resptime, timing_error, deadline);
987 if (deadline<al_get_time()) {
988 ts5_fatal(
"%s: %s (%f)\n",
"ts5_wait_for_response_until",
989 "response deadline is in the past",
990 deadline-al_get_time());
993 int resp=0, maxtime=0;
995 while (!resp && !maxtime) {
999 if (al_get_time()>=deadline) {
1052 ts5_log(TS5_LOGLEVEL_5,
"ts5_flush_triggers()\n");
1054 al_flush_event_queue(_ts5_data.timer.trigger_queue);
1072 ts5_log(TS5_LOGLEVEL_6,
"ts5_check_trigger(%p,%p)\n",
1073 trigtime, timing_error);
1076 ALLEGRO_EVENT event;
1078 TS5_TIMER_STATUS *timer = &_ts5_status.timer;
1080 if (trigtime!=NULL) {
1081 *trigtime = al_get_time();
1083 if (timing_error!=NULL) {
1084 *timing_error = 0.0;
1087 if (al_get_next_event(_ts5_data.timer.trigger_queue, &event)) {
1089 if(timer->cedrusbox_is_trigger_device) {
1092 for (i=0; i<timer->num_cedrusboxes; i++) {
1094 if (timer->cedrusbox[i].is_trigger_input_device) {
1096 if (event.type==TS5_EVENT_CEDRUSBOX_TRIGGER
1097 && event.user.data1 == i) {
1099 if (trigtime!=NULL) {
1100 *trigtime =
event.any.timestamp;
1103 if (timing_error!=NULL) {
1105 ((double)event.user.data3)/1000000.0;
1108 trigger =
event.user.data2;
1114 if(timer->parport_is_trigger_device) {
1117 for (i=0; i<timer->num_parports; i++) {
1119 if (timer->parport[i].is_trigger_input_device) {
1121 if (event.type==TS5_EVENT_PARPORT_TRIGGER
1122 && event.user.data1 == i) {
1124 if (trigtime!=NULL) {
1125 *trigtime =
event.any.timestamp;
1128 if (timing_error!=NULL) {
1130 ((double)event.user.data3)/1000000.0;
1133 trigger =
event.user.data2;
1139 if(timer->serialport_is_trigger_device) {
1142 for (i=0; i<timer->num_serialports; i++) {
1144 if (timer->serialport[i].is_trigger_input_device) {
1146 if (event.type==TS5_EVENT_SERIALPORT_TRIGGER
1147 && event.user.data1 == i) {
1149 if (trigtime!=NULL) {
1150 *trigtime =
event.any.timestamp;
1153 if (timing_error!=NULL) {
1155 ((double)event.user.data3)/1000000.0;
1158 trigger =
event.user.data2;
1182 ts5_log(TS5_LOGLEVEL_5,
"ts5_wait_for_trigger(%p,%p)\n",
1183 trigtime, timing_error);
1212 ts5_log(TS5_LOGLEVEL_5,
"ts5_wait_for_trigger_timed(%p,%p,%f)\n",
1213 trigtime, timing_error, maxtime);
1216 ts5_fatal(
"ts5_wait_for_trigger_timed: maxtime is negative (%f)\n",
1220 int trigger=0, deadline=0;
1221 double starttime = al_get_time();
1223 while (!trigger && !deadline) {
1227 if (al_get_time()-starttime>=maxtime) {
1252 ts5_log(TS5_LOGLEVEL_5,
"ts5_wait_for_trigger_until(%p,%p,%f)\n",
1253 trigtime, timing_error, deadline);
1255 if (deadline<al_get_time()) {
1256 ts5_fatal(
"%s: %s (%f)\n",
"ts5_wait_for_trigger_until",
1257 "trigger deadline is in the past",
1258 deadline-al_get_time());
1261 int trigger=0, maxtime=0;
1263 while (!trigger && !maxtime) {
1267 if (al_get_time()>=deadline) {
1285 ts5_log(TS5_LOGLEVEL_5,
"ts5_write_all_triggers(%s)\n", filename);
1288 fp = fopen(filename,
"a+");
1290 ts5_fatal(
"ts5_write_all_triggers: could not open output file %s\n",
1294 ALLEGRO_EVENT event;
1296 while (al_get_next_event(_ts5_data.timer.trigger_log, &event)) {
1298 fprintf(fp,
"%10.8f ", event.any.timestamp);
1300 double timing_error = ((double)event.user.data3)/1000000.0;
1301 fprintf(fp,
"%10.8f ", timing_error);
1303 if (event.type==TS5_EVENT_PARPORT_TRIGGER) {
1304 fprintf(fp,
"PARPORT ");
1306 else if (event.type==TS5_EVENT_SERIALPORT_TRIGGER) {
1307 fprintf(fp,
"SERIALPORT ");
1309 else if (event.type==TS5_EVENT_CEDRUSBOX_TRIGGER) {
1310 fprintf(fp,
"CEDRUSBOX ");
1313 fprintf(fp,
"UNKNOWN ");
1316 fprintf(fp,
"%d ", (
int)event.user.data1+1);
1317 fprintf(fp,
"%d ", (
int)event.user.data2);
void ts5_wait_until(double deadline)
Wait until a deadline.
int ts5_wait_for_response(double *resptime, double *timing_error)
Wait for a response.
void ts5_flush_responses()
Flush the response queue.
void ts5_flush_triggers()
Flush the trigger queue.
void ts5_wait(double waittime)
Wait for a number of seconds.
int ts5_get_priority()
Get the program's priority.
int ts5_wait_for_trigger_until(double *trigtime, double *timing_error, double deadline)
Wait for a trigger until a deadline.
void ts5_check_timer3(char *calling_function)
Do some checks at the start of each timer function.
void ts5_realtime_clock_nap()
Give up processor time to allow other processes to run.
void ts5_remove_response_buttons()
Completely removes the response button definition.
void ts5_check_timer4(char *calling_function)
Do some checks at the start of each timer function.
void ts5_log(const unsigned int level, const char *format,...)
Send info to a logging window.
int ts5_hide_response_button(int button)
Temporarily deactivates a response button.
void ts5_check_timer2(char *calling_function)
Do some checks at the start of each timer function.
int ts5_check_trigger(double *trigtime, double *timing_error)
Check for a trigger.
int ts5_wait_for_trigger(double *trigtime, double *timing_error)
Wait for a trigger.
int ts5_wait_for_response_until(double *resptime, double *timing_error, double deadline)
Wait for a response until a deadline.
int ts5_check_response(double *resptime, double *timing_error)
Check for a reponse.
void ts5_fatal(const char *format,...)
Exit safely with an error message.
int ts5_wait_for_response_timed(double *resptime, double *timing_error, double maxtime)
Wait for a response for a given time.
int ts5_wait_for_trigger_timed(double *trigtime, double *timing_error, double maxtime)
Wait for a trigger for a given time.
void ts5_write_all_triggers(char *filename)
Write all triggers to an output file.
int ts5_set_priority(int priority)
Set the program's priority.
double ts5_get_time()
Get the number of seconds since the program started.
void ts5_check_timer(char *calling_function)
Do some checks at the start of each timer function.