L4Re - L4 Runtime Environment
poll_timeout_kipclock
1 /*
2  * (c) 2012 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3  * economic rights: Technische Universit├Ąt Dresden (Germany)
4  * This file is part of TUD:OS and distributed under the terms of the
5  * GNU Lesser General Public License 2.1.
6  * Please see the COPYING-LGPL-2.1 file for details.
7  */
8 #pragma once
9 
10 #include <cassert>
11 #include <l4/sys/kip.h>
12 #include <l4/re/env.h>
13 
14 namespace L4 {
15 
16 /**
17  * \brief A polling timeout based on the L4Re clock.
18  *
19  * This class allows to conveniently add a timeout to a polling loop.
20  *
21  * The original
22  * ~~~{.cpp}
23  * while (device.read(State) & Busy)
24  * ;
25  * ~~~
26  *
27  * is converted to
28  *
29  * ~~~{.cpp}
30  * Poll_timeout_kipclock timeout(10000);
31  * while (timeout.test(device.read(State) & Busy))
32  * ;
33  * if (timeout.timed_out())
34  * printf("ERROR: Device does not respond.\n");
35  * ~~~
36  */
37 class Poll_timeout_kipclock
38 {
39 public:
40  /**
41  * \brief Initialise relative timeout in microseconds
42  * \param poll_time_us Polling timeout in microseconds.
43  */
44  Poll_timeout_kipclock(unsigned poll_time_us)
45  {
46  set(poll_time_us);
47  }
48 
49  /**
50  * \brief (Re-)Set relative timeout in microseconds
51  * \param poll_time_us Polling timeout in microseconds.
52  */
53  void set(unsigned poll_time_us)
54  {
55  _timeout = l4_kip_clock(l4re_kip()) + poll_time_us;
56  _last_check = true;
57  }
58 
59  /** \brief Test whether timeout has expired
60  * \param expression Optional expression.
61  *
62  * \retval false The timeout has expired or the given expression returned
63  * false.
64  * \retval true The timeout has not expired and the optionally given
65  * expression returns true.
66  */
67  bool test(bool expression = true)
68  {
69  if (!expression)
70  return false;
71 
72  return _last_check = l4_kip_clock(l4re_kip()) < _timeout;
73  }
74 
75  /**
76  * \brief Query whether timeout has expired
77  * \return Expiry state of timeout
78  */
79  bool timed_out() const { return !_last_check; }
80 
81 private:
82  l4_cpu_time_t _timeout;
83  bool _last_check;
84 };
85 }