ARB
arb_sleep.h
Go to the documentation of this file.
1 // =========================================================== //
2 // //
3 // File : arb_sleep.h //
4 // Purpose : //
5 // //
6 // Coded by Ralf Westram (coder@reallysoft.de) in May 2013 //
7 // Institute of Microbiology (Technical University Munich) //
8 // http://www.arb-home.de/ //
9 // //
10 // =========================================================== //
11 
12 #ifndef ARB_SLEEP_H
13 #define ARB_SLEEP_H
14 
15 #ifndef _UNISTD_H
16 #include <unistd.h>
17 #endif
18 #ifndef _GLIBCXX_ALGORITHM
19 #include <algorithm>
20 #endif
21 #ifndef _TIME_H
22 #include <time.h>
23 #endif
24 #ifndef _SYS_TIME_H
25 #include <sys/time.h>
26 #endif
27 
28 // #define TRACE_SLEEP
29 
30 enum TimeUnit { USEC = 1, MS = 1000, SEC = 1000*MS };
31 
32 inline void ARB_sleep(int amount, TimeUnit tu) {
33  arb_assert(amount>=0);
34  arb_assert(amount<1000*1000); // use different TimeUnit
35 
36  struct timespec t;
37  switch (tu) {
38  case USEC:
39  t.tv_sec = 0;
40  t.tv_nsec = amount*1000;
41  break;
42  case MS:
43  t.tv_sec = amount/MS;
44  t.tv_nsec = (amount-t.tv_sec*MS)*MS*1000;
45  break;
46  case SEC:
47  t.tv_sec = amount;
48  t.tv_nsec = 0;
49  break;
50  }
51 
52  arb_assert(t.tv_sec>=0);
53  arb_assert(t.tv_nsec>=0 && t.tv_nsec<=999999999);
54 
55  while (1) {
56  struct timespec remain;
57 
58  int res = nanosleep(&t, &remain);
59  if (res == 0) break;
60  // nanosleep has been interrupted by signal -> call again
61  t = remain;
62  }
63 }
64 
65 #if defined(TRACE_SLEEP)
66 inline const char *timeUnitAbbr(TimeUnit tu) {
67  switch (tu) {
68  case USEC: return "usec";
69  case MS: return "ms";
70  case SEC: return "s";
71  }
72  arb_assert(0);
73  return "";
74 }
75 #endif
76 
78  int curr_wait, max_wait, inc;
79  TimeUnit unit;
80 
81  void slowdown() { curr_wait = std::min(max_wait, curr_wait+inc); }
82 public:
83  ARB_inc_sleep(int min_amount, int max_amount, TimeUnit tu, int increment)
84  : curr_wait(min_amount),
85  max_wait(max_amount),
86  inc(increment),
87  unit(tu)
88  {
89  arb_assert(curr_wait>0);
90  arb_assert(max_amount>=curr_wait);
91  arb_assert(increment>0);
92  }
93 
94  void sleep() {
95 #if defined(TRACE_SLEEP)
96  fprintf(stderr, "pid %i waits %i %s\n", getpid(), curr_wait, timeUnitAbbr(unit));
97 #endif
98  ARB_sleep(curr_wait, unit);
99  slowdown();
100  }
101 };
102 
104  // timer which can be asked how much time passed since it was initialized
105  timeval t1;
106 
107 public:
109  void update() { gettimeofday(&t1, NULp); }
110 
111  long usec_since() const {
112  timeval t2;
113  gettimeofday(&t2, NULp);
114  return (t2.tv_sec - t1.tv_sec) * SEC + (t2.tv_usec - t1.tv_usec);
115  }
116  long ms_since() const { return usec_since()/MS; }
117  long sec_since() const { return usec_since()/SEC; }
118 };
119 
120 class ARB_timeout {
121  // short timeout
122  ARB_timestamp start;
123  long amount_usec;
124 public:
125  ARB_timeout(int amount, TimeUnit tu)
126  : amount_usec(amount*tu)
127  {}
128  bool passed() const {
129  return start.usec_since()>=amount_usec;
130  }
131 };
132 
133 
134 #else
135 #error arb_sleep.h included twice
136 #endif // ARB_SLEEP_H
#define arb_assert(cond)
Definition: arb_assert.h:245
long ms_since() const
Definition: arb_sleep.h:116
void sleep()
Definition: arb_sleep.h:94
long usec_since() const
Definition: arb_sleep.h:111
ARB_inc_sleep(int min_amount, int max_amount, TimeUnit tu, int increment)
Definition: arb_sleep.h:83
long sec_since() const
Definition: arb_sleep.h:117
void update()
Definition: arb_sleep.h:109
TimeUnit
Definition: arb_sleep.h:30
ARB_timeout(int amount, TimeUnit tu)
Definition: arb_sleep.h:125
Definition: arb_sleep.h:30
void ARB_sleep(int amount, TimeUnit tu)
Definition: arb_sleep.h:32
Definition: arb_sleep.h:30
#define NULp
Definition: cxxforward.h:97
bool passed() const
Definition: arb_sleep.h:128
#define min(a, b)
Definition: f2c.h:153
Definition: arb_sleep.h:30