Fawkes API Fawkes Development Version
wait.cpp
1
2/***************************************************************************
3 * wait.cpp - TimeWait tool
4 *
5 * Created: Thu Nov 29 17:30:37 2007
6 * Copyright 2007 Tim Niemueller [www.niemueller.de]
7 *
8 ****************************************************************************/
9
10/* This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version. A runtime exception applies to
14 * this software (see LICENSE.GPL_WRE file mentioned below for details).
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Library General Public License for more details.
20 *
21 * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22 */
23
24#include <utils/time/clock.h>
25#include <utils/time/time.h>
26#include <utils/time/wait.h>
27
28#include <cstdlib>
29#include <unistd.h>
30
31namespace fawkes {
32
33/** @class TimeWait <utils/time/wait.h>
34 * Time wait utility.
35 * This class allows for guaranteed waiting for a specified amout of time. It can
36 * either be used to suspend the current thread for at least the given time (static
37 * methods) or it can be used to reach a desired minimum loop time. For this instantiate
38 * the class and call mark_start() at the beginning of the loop and wait() at the end.
39 * wait() will then suspend the thread as long as needed to have the desired minimum
40 * loop time. The TimeWait utility will use the current clock time. Thus it may wait
41 * for a given amount of say simulated time.
42 * @author Tim Niemueller
43 */
44
45/** Constructor.
46 * @param clock clock to use
47 * @param desired_loop_time_usec desired minimum loop time in microseconds
48 */
49TimeWait::TimeWait(Clock *clock, long int desired_loop_time_usec)
50{
51 desired_loop_time_ = desired_loop_time_usec;
52 clock_ = clock;
53 until_ = new Time();
54 until_systime_ = new Time();
55 now_ = new Time();
56}
57
58/** Destructor. */
60{
61 delete until_;
62 delete until_systime_;
63 delete now_;
64}
65
66/** Mark start of loop. */
67void
69{
70 clock_->get_time(until_);
71 *until_ += desired_loop_time_;
72 clock_->get_systime(until_systime_);
73 *until_systime_ += desired_loop_time_;
74}
75
76/** Wait until minimum loop time has been reached. */
77void
79{
80 clock_->get_time(now_);
81 // we want to release run status at least shortly
82 usleep(0);
83
84 long int remaining_usec = (*until_ - *now_).in_usec();
85 while (remaining_usec > 0) {
86 usleep(remaining_usec);
87 clock_->get_time(now_);
88 remaining_usec = (*until_ - *now_).in_usec();
89 }
90}
91
92/** Wait until minimum loop time has been reached in real time.
93 * This uses the system time and not an external time source if defined.
94 */
95void
97{
98 clock_->get_systime(now_);
99 // we want to release run status at least shortly
100 usleep(0);
101
102 long int remaining_usec = (*until_systime_ - *now_).in_usec();
103 while (remaining_usec > 0) {
104 usleep(remaining_usec);
105 clock_->get_systime(now_);
106 remaining_usec = (*until_systime_ - *now_).in_usec();
107 }
108}
109
110/** Wait at least usec microseconds.
111 * Think of this as an uninterruptible usleep(). This method will not return before
112 * *at least* usec microseconds have passed. It may be longer but never less.
113 * Time is tracked in system time scale (real time).
114 * @param usec number of microseconds to wait at least
115 */
116void
118{
119 if (usec < 0)
120 return;
121 struct timeval start, now;
122 long int remaining_usec = usec;
123 gettimeofday(&start, NULL);
124 do {
125 usleep(remaining_usec);
126 gettimeofday(&now, NULL);
127 } while ((remaining_usec = usec - time_diff_usec(now, start)) > 0);
128}
129
130/** Wait at least usec microseconds.
131 * Think of this as an uninterruptible usleep(). This method will not return before
132 * *at least* usec microseconds have passed. It may be longer but never less.
133 * Time is tracked in the current Clock time scale. This may be simulated time
134 * or real time. It is assumed that the (simulated time) is at worst slower, but never
135 * faster than real time. Thus 1 microsecond real time is at least 1 microsecond clock time.
136 * @param usec number of microseconds to wait at least
137 */
138void
139TimeWait::wait(long int usec)
140{
141 if (usec < 0)
142 return;
143 Clock * clock = Clock::instance();
144 struct timeval start, now;
145 long int remaining_usec = usec;
146 clock->get_time(&start);
147 do {
148 usleep(remaining_usec);
149 clock->get_time(&now);
150 } while ((remaining_usec = usec - time_diff_usec(now, start)) > 0);
151}
152
153} // end namespace fawkes
This is supposed to be the central clock in Fawkes.
Definition: clock.h:35
void get_time(struct timeval *tv) const
Returns the time of the selected time source.
Definition: clock.cpp:161
static Clock * instance()
Clock initializer.
Definition: clock.cpp:63
void get_systime(struct timeval *tv) const
Returns the system time.
Definition: clock.cpp:215
TimeWait(Clock *clock, long int desired_loop_time_usec)
Constructor.
Definition: wait.cpp:49
void mark_start()
Mark start of loop.
Definition: wait.cpp:68
void wait_systime()
Wait until minimum loop time has been reached in real time.
Definition: wait.cpp:96
void wait()
Wait until minimum loop time has been reached.
Definition: wait.cpp:78
~TimeWait()
Destructor.
Definition: wait.cpp:59
A class for handling time.
Definition: time.h:93
Fawkes library namespace.
long int time_diff_usec(const timeval &a, const timeval &b)
Get difference between two time structs in microseconds.
Definition: time.h:85