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