functions_win.cpp
Go to the documentation of this file.
1 
8 /*****************************************************************************
9 ** Includes
10 *****************************************************************************/
11 
12 #include <ecl/config/windows.hpp>
14 #include "../../include/ecl/time_lite/functions_win.hpp"
15 
16 /*****************************************************************************
17 ** Macros
18 *****************************************************************************/
19 
20 #if defined(ECL_HAS_WIN_TIMERS)
21 
22 /*****************************************************************************
23 ** Namespaces
24 *****************************************************************************/
25 
26 namespace ecl {
27 
28 /*****************************************************************************
29 ** Notes
30 *****************************************************************************/
31 
32 // This is defined by windows and looks like this:
33 //typedef union _LARGE_INTEGER {
34 // struct {
35 // DWORD LowPart;
36 // LONG HighPart;
37 // };
38 // LONGLONG QuadPart;
39 //} LARGE_INTEGER;
40 //typedef LARGE_INTEGER TimeStructure; /**< @brief The underlying type used to store time structures. **/
41 
42 /*****************************************************************************
43 ** Private functions
44 *****************************************************************************/
45 
46 static double cpu_frequency() {
47  static double frequency = 0.0;
48 
49  if ( frequency == 0.0 ) { // need to initialise
50  LARGE_INTEGER freq;
51  QueryPerformanceFrequency(&freq);
52  frequency = static_cast<double>(freq.QuadPart);
53  }
54  return frequency;
55 }
56 
57 /*****************************************************************************
58 ** Public functions
59 *****************************************************************************/
60 
61 TimeError epoch_time(TimeStructure &time) {
62  // Get time
63  LARGE_INTEGER stamp;
64  QueryPerformanceCounter(&stamp);
65  double t = static_cast<double>(stamp.QuadPart)/cpu_frequency();
66  time.tv_sec = static_cast<long>(t);
67  time.tv_nsec = ((t - static_cast<double>(time.tv_sec))*1000000000.0);
68  return TimeError(NoError);
69 }
70 
71 TimeError sleep_until(const TimeStructure &time) {
72  TimeStructure current_time, sleep_time;
73 
74  TimeError error = epoch_time(current_time);
75  if ( error.flag() != NoError ) { return error; }
76 
77  /*********************
78  ** current > time?
79  **********************/
80  if ( current_time.tv_sec > time.tv_sec ) {
81  return TimeError(NoError); // return immediately
82  } else if ( current_time.tv_sec == time.tv_sec ) {
83  if ( current_time.tv_nsec > time.tv_nsec ) {
84  return TimeError(NoError);
85  }
86  }
87  sleep_time.tv_sec = time.tv_sec - current_time.tv_sec;
88  if ( current_time.tv_nsec <= time.tv_nsec ) {
89  sleep_time.tv_nsec = time.tv_nsec - current_time.tv_nsec;
90  } else {
91  sleep_time.tv_sec -= 1;
92  sleep_time.tv_nsec = 1000000000L - current_time.tv_nsec + time.tv_nsec;
93  }
94  return ecl::sleep(sleep_time);
95 }
96 
97 TimeError sleep(const TimeStructure &time) {
98  HANDLE timer = NULL;
99  LARGE_INTEGER sleep_time;
100 
101  sleep_time.QuadPart = -
102  static_cast<ecl::uint64>(time.tv_sec)*10000000LL -
103  static_cast<ecl::uint64>(time.tv_nsec) / 100LL;
104 
105  if ( (timer = CreateWaitableTimer(NULL, TRUE, NULL)) == NULL ) {
106  return TimeError(UnknownError);
107  }
108  if (!SetWaitableTimer (timer, &sleep_time, 0, NULL, NULL, 0)) {
109  return TimeError(UnknownError);
110  }
111 
112  if (WaitForSingleObject (timer, INFINITE) != WAIT_OBJECT_0) {
113  return TimeError(UnknownError);
114  }
115  return TimeError(NoError);
116 }
117 
118 
119 } // namespace ecl
120 
121 #endif
UnknownError


ecl_time_lite
Author(s): Daniel Stonier
autogenerated on Mon Jun 10 2019 13:09:07