|
MASA-Core
|
00001 /******************************************************************************* 00002 * 00003 * Copyright (c) 2010-2015 Edans Sandes 00004 * 00005 * This file is part of MASA-Core. 00006 * 00007 * MASA-Core is free software: you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation, either version 3 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * MASA-Core is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with MASA-Core. If not, see <http://www.gnu.org/licenses/>. 00019 * 00020 ******************************************************************************/ 00021 00022 #include "RecurrentTimer.hpp" 00023 00024 #include <stdio.h> 00025 #include <stdlib.h> 00026 00027 RecurrentTimer::RecurrentTimer(void (*routine)(float)) { 00028 this->routine = routine; 00029 this->active = false; 00030 00031 pthread_mutex_init(&mutex, NULL); 00032 pthread_cond_init(&condition, NULL); 00033 } 00034 00035 RecurrentTimer::~RecurrentTimer() { 00036 stop(); 00037 } 00038 00039 void RecurrentTimer::start(float interval) { 00040 if (this->active) { 00041 return; 00042 } 00043 00044 this->interval = (int)(interval*1000); 00045 if (this->interval < 1) { 00046 this->interval = 1; // minimum interval (1ms). 00047 } 00048 this->active = true; 00049 int rc = pthread_create(&thread, NULL, staticFunctionThread, (void *)this); 00050 if (rc){ 00051 fprintf(stderr, "setLogFile ERROR; return code from pthread_create() is %d\n", rc); 00052 exit(-1); 00053 } 00054 } 00055 00056 void RecurrentTimer::stop() { 00057 if (!this->active) { 00058 return; 00059 } 00060 pthread_mutex_lock(&mutex); 00061 this->active = false; 00062 pthread_cond_signal(&condition); 00063 pthread_mutex_unlock(&mutex); 00064 00065 pthread_join(thread, NULL); 00066 } 00067 00068 00069 void RecurrentTimer::executeLoop() { 00070 timeval start; 00071 gettimeofday(&start, NULL); 00072 routine(0.0f); 00073 while (active) { 00074 timeval event; 00075 gettimeofday(&event, NULL); 00076 00077 struct timespec time; 00078 time.tv_sec = event.tv_sec + (interval/1000); 00079 time.tv_nsec = event.tv_usec*1000 + (interval%1000)*1000000; 00080 if (time.tv_nsec >= 1000000000) { 00081 time.tv_nsec -= 1000000000; 00082 time.tv_sec++; 00083 } 00084 00085 pthread_mutex_lock(&mutex); 00086 pthread_cond_timedwait(&condition, &mutex, &time); 00087 pthread_mutex_unlock(&mutex); 00088 00089 routine(getElapsedTime(&event, &start)); 00090 } 00091 } 00092 00093 void *RecurrentTimer::staticFunctionThread(void *arg) { 00094 RecurrentTimer* timer = (RecurrentTimer*)arg; 00095 timer->executeLoop(); 00096 return NULL; 00097 } 00098 00099 void RecurrentTimer::logNow() { 00100 pthread_cond_signal(&condition); 00101 } 00102 00103 float RecurrentTimer::getElapsedTime(timeval *end_time, timeval *start_time) { 00104 timeval temp_diff; 00105 00106 temp_diff.tv_sec = end_time->tv_sec - start_time->tv_sec; 00107 temp_diff.tv_usec = end_time->tv_usec - start_time->tv_usec; 00108 00109 if (temp_diff.tv_usec < 0) { 00110 long long nsec = temp_diff.tv_usec/1000000; 00111 temp_diff.tv_usec += 1000000 * nsec; 00112 temp_diff.tv_sec -= nsec; 00113 } 00114 00115 return (1000000LL * temp_diff.tv_sec + temp_diff.tv_usec)/1000000.0f; 00116 }
1.7.6.1