$search
00001 00008 /***************************************************************************** 00009 ** Includes 00010 *****************************************************************************/ 00011 00012 #include <ecl/config/windows.hpp> 00013 #include <ecl/config/portable_types.hpp> 00014 #include "../../include/ecl/time_lite/functions_win.hpp" 00015 00016 /***************************************************************************** 00017 ** Macros 00018 *****************************************************************************/ 00019 00020 #if defined(ECL_HAS_WIN_TIMERS) 00021 00022 /***************************************************************************** 00023 ** Namespaces 00024 *****************************************************************************/ 00025 00026 namespace ecl { 00027 00028 /***************************************************************************** 00029 ** Notes 00030 *****************************************************************************/ 00031 00032 // This is defined by windows and looks like this: 00033 //typedef union _LARGE_INTEGER { 00034 // struct { 00035 // DWORD LowPart; 00036 // LONG HighPart; 00037 // }; 00038 // LONGLONG QuadPart; 00039 //} LARGE_INTEGER; 00040 //typedef LARGE_INTEGER TimeStructure; /**< @brief The underlying type used to store time structures. **/ 00041 00042 /***************************************************************************** 00043 ** Private functions 00044 *****************************************************************************/ 00045 00046 static double cpu_frequency() { 00047 static double frequency = 0.0; 00048 00049 if ( frequency == 0.0 ) { // need to initialise 00050 LARGE_INTEGER freq; 00051 QueryPerformanceFrequency(&freq); 00052 frequency = static_cast<double>(freq.QuadPart); 00053 } 00054 return frequency; 00055 } 00056 00057 /***************************************************************************** 00058 ** Public functions 00059 *****************************************************************************/ 00060 00061 int dude() { int i = 3; return i; } 00062 TimeError epoch_time(TimeStructure &time) { 00063 // Get time 00064 LARGE_INTEGER stamp; 00065 QueryPerformanceCounter(&stamp); 00066 double t = static_cast<double>(stamp.QuadPart)/cpu_frequency(); 00067 time.tv_sec = static_cast<long>(t); 00068 time.tv_nsec = ((t - static_cast<double>(time.tv_sec))*1000000000.0); 00069 return TimeError(NoError); 00070 } 00071 00072 TimeError sleep_until(const TimeStructure &time) { 00073 TimeStructure current_time, sleep_time; 00074 00075 TimeError error = epoch_time(current_time); 00076 if ( error.flag() != NoError ) { return error; } 00077 00078 /********************* 00079 ** current > time? 00080 **********************/ 00081 if ( current_time.tv_sec > time.tv_sec ) { 00082 return TimeError(NoError); // return immediately 00083 } else if ( current_time.tv_sec == time.tv_sec ) { 00084 if ( current_time.tv_nsec > time.tv_nsec ) { 00085 return TimeError(NoError); 00086 } 00087 } 00088 sleep_time.tv_sec = time.tv_sec - current_time.tv_sec; 00089 if ( current_time.tv_nsec <= time.tv_nsec ) { 00090 sleep_time.tv_nsec = time.tv_nsec - current_time.tv_nsec; 00091 } else { 00092 sleep_time.tv_sec -= 1; 00093 sleep_time.tv_nsec = 1000000000L - current_time.tv_nsec + time.tv_nsec; 00094 } 00095 return ecl::sleep(sleep_time); 00096 } 00097 00098 TimeError sleep(const TimeStructure &time) { 00099 HANDLE timer = NULL; 00100 LARGE_INTEGER sleep_time; 00101 00102 sleep_time.QuadPart = - 00103 static_cast<ecl::uint64>(time.tv_sec)*10000000LL - 00104 static_cast<ecl::uint64>(time.tv_nsec) / 100LL; 00105 00106 if ( (timer = CreateWaitableTimer(NULL, TRUE, NULL)) == NULL ) { 00107 return TimeError(UnknownError); 00108 } 00109 if (!SetWaitableTimer (timer, &sleep_time, 0, NULL, NULL, 0)) { 00110 return TimeError(UnknownError); 00111 } 00112 00113 if (WaitForSingleObject (timer, INFINITE) != WAIT_OBJECT_0) { 00114 return TimeError(UnknownError); 00115 } 00116 return TimeError(NoError); 00117 } 00118 00119 00120 } // namespace ecl 00121 00122 #endif