Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * wait.cpp - TimeWait tool 00004 * 00005 * Created: Thu Nov 29 17:30:37 2007 00006 * Copyright 2007 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #include <utils/time/wait.h> 00025 #include <utils/time/time.h> 00026 #include <utils/time/clock.h> 00027 00028 #include <unistd.h> 00029 #include <cstdlib> 00030 00031 namespace fawkes { 00032 00033 /** @class TimeWait <utils/time/wait.h> 00034 * Time wait utility. 00035 * This class allows for guaranteed waiting for a specified amout of time. It can 00036 * either be used to suspend the current thread for at least the given time (static 00037 * methods) or it can be used to reach a desired minimum loop time. For this instantiate 00038 * the class and call set_start() at the beginning of the loop and wait() at the end. 00039 * wait() will then suspend the thread as long as needed to have the desired minimum 00040 * loop time. The TimeWait utility will use the current clock time. Thus it may wait 00041 * for a given amount of say simulated time. 00042 * @author Tim Niemueller 00043 */ 00044 00045 /** Constructor. 00046 * @param clock clock to use 00047 * @param desired_loop_time_usec desired minimum loop time in microseconds 00048 */ 00049 TimeWait::TimeWait(Clock *clock, long int desired_loop_time_usec) 00050 { 00051 __desired_loop_time = desired_loop_time_usec; 00052 __clock = clock; 00053 __until = new Time(); 00054 __until_systime = new Time(); 00055 __now = new Time(); 00056 } 00057 00058 00059 /** Destructor. */ 00060 TimeWait::~TimeWait() 00061 { 00062 delete __until; 00063 delete __until_systime; 00064 delete __now; 00065 } 00066 00067 00068 /** Mark start of loop. */ 00069 void 00070 TimeWait::mark_start() 00071 { 00072 __clock->get_time(__until); 00073 *__until += __desired_loop_time; 00074 __clock->get_systime(__until_systime); 00075 *__until_systime += __desired_loop_time; 00076 } 00077 00078 00079 /** Wait until minimum loop time has been reached. */ 00080 void 00081 TimeWait::wait() 00082 { 00083 __clock->get_time(__now); 00084 // we want to release run status at least shortly 00085 usleep(0); 00086 00087 long int remaining_usec = (*__until - *__now).in_usec(); 00088 while ( remaining_usec > 0 ) { 00089 usleep(remaining_usec); 00090 __clock->get_time(__now); 00091 remaining_usec = (*__until - *__now).in_usec(); 00092 } 00093 } 00094 00095 00096 /** Wait until minimum loop time has been reached in real time. 00097 * This uses the system time and not an external time source if defined. 00098 */ 00099 void 00100 TimeWait::wait_systime() 00101 { 00102 __clock->get_systime(__now); 00103 // we want to release run status at least shortly 00104 usleep(0); 00105 00106 long int remaining_usec = (*__until_systime - *__now).in_usec(); 00107 while ( remaining_usec > 0 ) { 00108 usleep(remaining_usec); 00109 __clock->get_systime(__now); 00110 remaining_usec = (*__until_systime - *__now).in_usec(); 00111 } 00112 } 00113 00114 00115 /** Wait at least usec microseconds. 00116 * Think of this as an uninterruptible usleep(). This method will not return before 00117 * *at least* usec microseconds have passed. It may be longer but never less. 00118 * Time is tracked in system time scale (real time). 00119 * @param usec number of microseconds to wait at least 00120 */ 00121 void 00122 TimeWait::wait_systime(long int usec) 00123 { 00124 if ( usec < 0 ) return; 00125 struct timeval start, now; 00126 long int remaining_usec = usec; 00127 gettimeofday(&start, NULL); 00128 do { 00129 usleep(remaining_usec); 00130 gettimeofday(&now, NULL); 00131 } while ((remaining_usec = usec - time_diff_usec(now, start)) > 0); 00132 } 00133 00134 /** Wait at least usec microseconds. 00135 * Think of this as an uninterruptible usleep(). This method will not return before 00136 * *at least* usec microseconds have passed. It may be longer but never less. 00137 * Time is tracked in the current Clock time scale. This may be simulated time 00138 * or real time. It is assumed that the (simulated time) is at worst slower, but never 00139 * faster than real time. Thus 1 microsecond real time is at least 1 microsecond clock time. 00140 * @param usec number of microseconds to wait at least 00141 */ 00142 void 00143 TimeWait::wait(long int usec) 00144 { 00145 if ( usec < 0 ) return; 00146 Clock *clock = Clock::instance(); 00147 struct timeval start, now; 00148 long int remaining_usec = usec; 00149 clock->get_time(&start); 00150 do { 00151 usleep(remaining_usec); 00152 clock->get_time(&now); 00153 } while ((remaining_usec = usec - time_diff_usec(now, start)) > 0); 00154 } 00155 00156 } // end namespace fawkes