ALPSCore reference
check_schedule.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1998-2018 ALPS Collaboration. See COPYRIGHT.TXT
3  * All rights reserved. Use is subject to license terms. See LICENSE.TXT
4  * For use in publications, see ACKNOWLEDGE.TXT
5  */
6 
7 #pragma once
8 
9 #include <ctime>
10 
11 namespace alps {
12 
13  namespace detail {
15 
16  // (Note: We could use traits, but we don't)
17  template <typename CLOCK_T>
18  class generic_check_schedule {
19  public:
20  typedef CLOCK_T clock_type;
21  typedef typename clock_type::time_point_type time_point_type;
22  typedef typename clock_type::time_duration_type time_duration_type;
23 
24  private:
25  clock_type clock_;
26 
27  bool next_check_known_;
28  double start_fraction_;
29 
30  time_duration_type min_check_;
31  time_duration_type max_check_;
32 
33  time_point_type start_time_;
34  time_point_type last_check_time_;
35 
36  time_duration_type next_check_;
37 
38  public:
40 
44  generic_check_schedule(double tmin, double tmax)
45  : clock_(),
46  next_check_known_(false),
47  start_fraction_(),
48  min_check_(tmin),
49  max_check_(tmax),
50  start_time_(),
51  last_check_time_(),
52  next_check_()
53  { }
54 
56 
61  generic_check_schedule(double tmin, double tmax, const clock_type& clock)
62  : clock_(clock),
63  next_check_known_(false),
64  min_check_(tmin),
65  max_check_(tmax),
66  start_time_(),
67  last_check_time_(),
68  next_check_()
69  { }
70 
72  bool pending() const
73  {
74  if (!next_check_known_) return true;
75  time_point_type now = clock_.now_time();
76  return clock_.time_diff(now, last_check_time_) > next_check_;
77  }
78 
80  void update(double fraction)
81  {
82  time_point_type now = clock_.now_time();
83  // first check
84 
85  if (!next_check_known_)
86  {
87  start_time_ = now;
88  start_fraction_ = fraction;
89  next_check_known_=true;
90  }
91 
92  if (fraction > start_fraction_)
93  {
94  // estimate remaining time; propose to run 1/4 of that time
95  time_duration_type old_check = next_check_;
96  next_check_ = 0.25 * (1 - fraction)
97  * clock_.time_diff(now, start_time_) / (fraction - start_fraction_);
98 
99  if( next_check_ > 2*old_check ) next_check_ = 2 * old_check;
100  if( next_check_ < min_check_ ) next_check_ = min_check_;
101  if( next_check_ > max_check_ ) next_check_ = max_check_;
102  }
103  else
104  next_check_ = min_check_;
105 
106  last_check_time_ = now;
107  }
108  };
109 
110 
112  class posix_wall_clock {
113  public:
115  typedef std::time_t time_point_type;
116 
118  typedef double time_duration_type;
119 
121  static time_point_type now_time() { return std::time(0); }
122 
124  static time_duration_type time_diff(time_point_type t1, time_point_type t0)
125  {
126  return std::difftime(t1, t0);
127  }
128  };
129  } // detail::
130 
131  typedef detail::generic_check_schedule<detail::posix_wall_clock> check_schedule;
132 
133 } // namespace alps
detail::generic_check_schedule< detail::posix_wall_clock > check_schedule