urg_time.c
Go to the documentation of this file.
1 
9 #include "urg_c/urg_time.h"
10 
11 // Portable time function borrowed from ros::Time
12 void urg_walltime(unsigned long *sec, unsigned long *nsec)
13  {
14 #ifndef WIN32
15 #if HAS_CLOCK_GETTIME
16  struct timespec start;
17  clock_gettime(CLOCK_REALTIME, &start);
18  *sec = start.tv_sec;
19  *nsec = start.tv_nsec;
20 #else
21  struct timeval timeofday;
22  gettimeofday(&timeofday,NULL);
23  sec = timeofday.tv_sec;
24  nsec = timeofday.tv_usec * 1000;
25 #endif
26 #else
27  // Win32 implementation
28  // unless I've missed something obvious, the only way to get high-precision
29  // time on Windows is via the QueryPerformanceCounter() call. However,
30  // this is somewhat problematic in Windows XP on some processors, especially
31  // AMD, because the Windows implementation can freak out when the CPU clocks
32  // down to save power. Time can jump or even go backwards. Microsoft has
33  // fixed this bug for most systems now, but it can still show up if you have
34  // not installed the latest CPU drivers (an oxymoron). They fixed all these
35  // problems in Windows Vista, and this API is by far the most accurate that
36  // I know of in Windows, so I'll use it here despite all these caveats
37  static LARGE_INTEGER cpu_freq, init_cpu_time;
38  static uint32_t start_sec = 0;
39  static uint32_t start_nsec = 0;
40  if ( ( start_sec == 0 ) && ( start_nsec == 0 ) )
41  {
42  QueryPerformanceFrequency(&cpu_freq);
43  if (cpu_freq.QuadPart == 0) {
44  throw NoHighPerformanceTimersException();
45  }
46  QueryPerformanceCounter(&init_cpu_time);
47  // compute an offset from the Epoch using the lower-performance timer API
48  FILETIME ft;
49  GetSystemTimeAsFileTime(&ft);
50  LARGE_INTEGER start_li;
51  start_li.LowPart = ft.dwLowDateTime;
52  start_li.HighPart = ft.dwHighDateTime;
53  // why did they choose 1601 as the time zero, instead of 1970?
54  // there were no outstanding hard rock bands in 1601.
55 #ifdef _MSC_VER
56  start_li.QuadPart -= 116444736000000000Ui64;
57 #else
58  start_li.QuadPart -= 116444736000000000ULL;
59 #endif
60  start_sec = (uint32_t)(start_li.QuadPart / 10000000); // 100-ns units. odd.
61  start_nsec = (start_li.LowPart % 10000000) * 100;
62  }
63  LARGE_INTEGER cur_time;
64  QueryPerformanceCounter(&cur_time);
65  LARGE_INTEGER delta_cpu_time;
66  delta_cpu_time.QuadPart = cur_time.QuadPart - init_cpu_time.QuadPart;
67  // todo: how to handle cpu clock drift. not sure it's a big deal for us.
68  // also, think about clock wraparound. seems extremely unlikey, but possible
69  double d_delta_cpu_time = delta_cpu_time.QuadPart / (double) cpu_freq.QuadPart;
70  uint32_t delta_sec = (uint32_t) floor(d_delta_cpu_time);
71  uint32_t delta_nsec = (uint32_t) boost::math::round((d_delta_cpu_time-delta_sec) * 1e9);
72 
73  int64_t sec_sum = (int64_t)start_sec + (int64_t)delta_sec;
74  int64_t nsec_sum = (int64_t)start_nsec + (int64_t)delta_nsec;
75 
76  // Throws an exception if we go out of 32-bit range
77  normalizeSecNSecUnsigned(sec_sum, nsec_sum);
78 
79  sec = sec_sum;
80  nsec = nsec_sum;
81 #endif
82  }
83 
84 void urg_get_walltime(unsigned long long *nsecs){
85  unsigned long sec;
86  unsigned long nsec;
87  urg_walltime(&sec, &nsec);
88  *nsecs = (unsigned long long)sec*1000000000ll + (unsigned long long)nsec;
89 }
void urg_walltime(unsigned long *sec, unsigned long *nsec)
URG ƒZƒ“ƒT—p‚̕⏕ŠÖ”
Definition: urg_time.c:12
void urg_get_walltime(unsigned long long *nsecs)
Definition: urg_time.c:84


urg_c
Author(s): Satofumi Kamimura , Katsumi Kimoto, Adrian Boeing
autogenerated on Thu Jun 6 2019 19:27:49