source: branches/alilink/TEMPLATES/arb_sleep.h

Last change on this file was 16768, checked in by westram, 7 years ago
File size: 3.4 KB
Line 
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
30enum TimeUnit { USEC = 1, MS = 1000, SEC = 1000*MS };
31
32inline 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)
66inline 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
77class ARB_inc_sleep {
78    int      curr_wait, max_wait, inc;
79    TimeUnit unit;
80
81    void slowdown() { curr_wait = std::min(max_wait, curr_wait+inc); }
82public:
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
103class ARB_timestamp {
104    // timer which can be asked how much time passed since it was initialized
105    timeval t1;
106
107public:
108    ARB_timestamp() { update(); }
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
120class ARB_timeout {
121    // short timeout
122    ARB_timestamp start;
123    long          amount_usec;
124public:
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
Note: See TracBrowser for help on using the repository browser.