GraphLab: Distributed Graph-Parallel API  2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
timer.cpp
1 /**
2  * Copyright (c) 2009 Carnegie Mellon University.
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing,
12  * software distributed under the License is distributed on an "AS
13  * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
14  * express or implied. See the License for the specific language
15  * governing permissions and limitations under the License.
16  *
17  * For more about this software visit:
18  *
19  * http://www.graphlab.ml.cmu.edu
20  *
21  */
22 
23 
24 #include <iostream>
25 #include <signal.h>
26 #include <sys/time.h>
27 
28 #include <graphlab/parallel/pthread_tools.hpp>
29 #include <graphlab/util/timer.hpp>
30 
31 std::ostream& operator<<(std::ostream& out, const graphlab::timer& t) {
32  return out << t.current_time();
33 }
34 
35 namespace graphlab {
36  void alarm_wakeup(int i);
37 
38 
39  class hundredms_timer {
40  public:
41  hundredms_timer() {
42  stop = false;
43  tout_val.it_interval.tv_sec = 0;
44  tout_val.it_interval.tv_usec = 0;
45  tout_val.it_value.tv_sec = 0;
46  tout_val.it_value.tv_usec = 50000;
47  signal(SIGALRM,alarm_wakeup); /* set the Alarm signal capture */
48  setitimer(ITIMER_REAL, &tout_val,0);
49  ti.start();
50  }
51  size_t ctr;
52  timer ti;
53  struct itimerval tout_val;
54  bool stop;
55 
56  ~hundredms_timer() {
57  stop = true;
58  signal(SIGALRM, SIG_IGN);
59  }
60  };
61 
62  hundredms_timer hmstimer;
63 
64 
65  void alarm_wakeup(int i) {
66  if (hmstimer.stop) return;
67  signal(SIGALRM,alarm_wakeup);
68  // compute the desired time till the next 100ms tick by using a real timer call
69  double realtime = hmstimer.ti.current_time() ;
70  // round down
71  hmstimer.ctr = (size_t)(realtime * 10);
72  setitimer(ITIMER_REAL, &(hmstimer.tout_val), 0);
73  }
74 
75  /**
76  * Precision of deciseconds
77  */
79  return float(hmstimer.ctr) / 10;
80  }
81 
82  /**
83  * Precision of deciseconds
84  */
86  return hmstimer.ctr * 100;
87  }
88 
89 
90  void timer::sleep(size_t sleeplen) {
91  struct timespec timeout;
92  timeout.tv_sec = sleeplen;
93  timeout.tv_nsec = 0;
94  while (nanosleep(&timeout, &timeout) == -1);
95  }
96 
97 
98  /**
99  Sleeps for sleeplen milliseconds.
100  */
101  void timer::sleep_ms(size_t sleeplen) {
102  struct timespec timeout;
103  timeout.tv_sec = sleeplen / 1000;
104  timeout.tv_nsec = (sleeplen % 1000) * 1000000;
105  while (nanosleep(&timeout, &timeout) == -1);
106  }
107 
108 
109 
110 
111 static unsigned long long rtdsc_ticks_per_sec = 0;
112 static mutex rtdsc_ticks_per_sec_mutex;
113 
114 unsigned long long estimate_ticks_per_second() {
115  if (rtdsc_ticks_per_sec == 0) {
116  rtdsc_ticks_per_sec_mutex.lock();
117  if (rtdsc_ticks_per_sec == 0) {
118  unsigned long long tstart = rdtsc();
120  unsigned long long tend = rdtsc();
121  rtdsc_ticks_per_sec = tend - tstart;
122  }
123  rtdsc_ticks_per_sec_mutex.unlock();
124  }
125  return rtdsc_ticks_per_sec;
126 }
127 
128 }
129