diff -r 6efc85c5493e -r 1c1e3599d66a doc/doxygen/html/timers__win32_8cpp-source.html --- a/doc/doxygen/html/timers__win32_8cpp-source.html Mon Feb 11 11:00:12 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,267 +0,0 @@ - -
-00001 /* -00002 This file is part of CanFestival, a library implementing CanOpen Stack. -00003 -00004 Copyright (C): Edouard TISSERANT and Francis DUPIN -00005 Copyright (C) Win32 Port Leonid Tochinski -00006 -00007 See COPYING file for copyrights details. -00008 -00009 This library is free software; you can redistribute it and/or -00010 modify it under the terms of the GNU Lesser General Public -00011 License as published by the Free Software Foundation; either -00012 version 2.1 of the License, or (at your option) any later version. -00013 -00014 This library is distributed in the hope that it will be useful, -00015 but WITHOUT ANY WARRANTY; without even the implied warranty of -00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -00017 Lesser General Public License for more details. -00018 -00019 You should have received a copy of the GNU Lesser General Public -00020 License along with this library; if not, write to the Free Software -00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -00022 */ -00023 -00024 -00025 -00026 #include <windows.h> -00027 #include <stdlib.h> -00028 -00029 extern "C" -00030 { -00031 #include "applicfg.h" -00032 #include "can_driver.h" -00033 #include "timer.h" -00034 #include "timers_driver.h" -00035 }; -00036 -00037 // --------------- Synchronization Object Implementation --------------- -00038 class ccritical_section -00039 { -00040 public: -00041 ccritical_section() -00042 { -00043 ::InitializeCriticalSection(&m_cs); -00044 } -00045 ~ccritical_section() -00046 { -00047 ::DeleteCriticalSection(&m_cs); -00048 } -00049 void enter() -00050 { -00051 ::EnterCriticalSection(&m_cs); -00052 } -00053 void leave() -00054 { -00055 ::LeaveCriticalSection(&m_cs); -00056 } -00057 private: -00058 CRITICAL_SECTION m_cs; -00059 }; -00060 -00061 static ccritical_section g_cs; -00062 -00063 -00064 void EnterMutex(void) -00065 { -00066 g_cs.enter(); -00067 } -00068 -00069 void LeaveMutex(void) -00070 { -00071 g_cs.leave(); -00072 } -00073 // --------------- Synchronization Object Implementation --------------- -00074 -00075 -00076 // --------------- CAN Receive Thread Implementation --------------- -00077 -00078 void CreateReceiveTask(CAN_HANDLE fd0, TASK_HANDLE* Thread, void* ReceiveLoopPtr) -00079 { -00080 unsigned long thread_id = 0; -00081 *Thread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReceiveLoopPtr, fd0, 0, &thread_id); -00082 } -00083 -00084 void WaitReceiveTaskEnd(TASK_HANDLE Thread) -00085 { -00086 ::WaitForSingleObject(Thread, INFINITE); -00087 ::CloseHandle(Thread); -00088 //*Thread = NULL; -00089 } -00090 // --------------- CAN Receive Thread Implementation --------------- -00091 -00092 -00093 // --------------- Timer Thread Implementation --------------- -00094 class class_timers -00095 { -00096 public: -00097 class_timers(); -00098 ~class_timers(); -00099 void start_timer_thread(); -00100 void resume_timer_thread(); -00101 void stop_timer_thread(); -00102 void set_timer(TIMEVAL value); -00103 TIMEVAL get_elapsed_time(); -00104 private: -00105 TIMEVAL get_timer() const; -00106 static DWORD WINAPI timer_loop_thread_proc(void* arg); -00107 private: -00108 TIMEVAL m_last_occured_alarm_time; -00109 volatile TIMEVAL m_last_alarm_set_time; -00110 HANDLE m_timer_thread; -00111 volatile bool m_continue_timer_loop; -00112 bool m_use_hi_res_timer; -00113 double m_counts_per_usec; -00114 }; -00115 -00116 class_timers::class_timers() : m_last_occured_alarm_time(TIMEVAL_MAX), -00117 m_last_alarm_set_time(TIMEVAL_MAX), -00118 m_timer_thread(0), -00119 m_continue_timer_loop(false), -00120 m_use_hi_res_timer(false), -00121 m_counts_per_usec(0.) -00122 { -00123 // initialize hi resolution timer -00124 LARGE_INTEGER counts_per_sec = {0, 0}; -00125 if (::QueryPerformanceFrequency(&counts_per_sec) && counts_per_sec.QuadPart > 0) -00126 { -00127 m_use_hi_res_timer = true; -00128 m_counts_per_usec = counts_per_sec.QuadPart / 1000000.; -00129 } -00130 m_use_hi_res_timer = true; -00131 } -00132 -00133 class_timers::~class_timers() -00134 { -00135 stop_timer_thread(); -00136 } -00137 -00138 // time is in micro seconds -00139 TIMEVAL class_timers::get_timer() const -00140 { -00141 if (m_use_hi_res_timer) -00142 { -00143 LARGE_INTEGER performance_count = {0, 0}; -00144 ::QueryPerformanceCounter(&performance_count); -00145 return (TIMEVAL)(performance_count.QuadPart / m_counts_per_usec); -00146 } -00147 // hi-res timer is unavailable -00148 return 1000 * ::GetTickCount(); -00149 } -00150 -00151 DWORD WINAPI class_timers::timer_loop_thread_proc(void* arg) -00152 { -00153 class_timers* This = reinterpret_cast<class_timers*>(arg); -00154 while (This->m_continue_timer_loop) -00155 { -00156 TIMEVAL cur_time = This->get_timer(); -00157 if (cur_time >= This->m_last_alarm_set_time) -00158 { -00159 This->m_last_occured_alarm_time = cur_time; -00160 This->m_last_alarm_set_time = TIMEVAL_MAX; -00161 EnterMutex(); -00162 TimeDispatch(); -00163 LeaveMutex(); -00164 } -00165 else -00166 { -00167 ::Sleep(1); -00168 } -00169 } -00170 return 0; -00171 } -00172 -00173 void class_timers::start_timer_thread() -00174 { -00175 if (m_timer_thread == 0) -00176 { -00177 unsigned long thread_id = 0; -00178 m_timer_thread = ::CreateThread(NULL, 0, &timer_loop_thread_proc, this, CREATE_SUSPENDED, &thread_id); -00179 m_last_alarm_set_time = TIMEVAL_MAX; -00180 m_last_occured_alarm_time = get_timer(); -00181 } -00182 } -00183 -00184 void class_timers::resume_timer_thread() -00185 { -00186 if (m_timer_thread) -00187 { -00188 m_continue_timer_loop = true; -00189 ::ResumeThread(m_timer_thread); -00190 } -00191 } -00192 -00193 void class_timers::stop_timer_thread() -00194 { -00195 if (m_timer_thread) -00196 { -00197 m_continue_timer_loop = false; -00198 ::WaitForSingleObject(m_timer_thread, INFINITE); -00199 ::CloseHandle(m_timer_thread); -00200 m_timer_thread = 0; -00201 } -00202 } -00203 -00204 void class_timers::set_timer(TIMEVAL value) -00205 { -00206 m_last_alarm_set_time = (value == TIMEVAL_MAX) ? TIMEVAL_MAX : get_timer() + value; -00207 } -00208 -00209 // elapsed time since last occured alarm -00210 TIMEVAL class_timers::get_elapsed_time() -00211 { -00212 return get_timer() - m_last_occured_alarm_time; -00213 } -00214 -00215 // ---------------------------------------------------------- -00216 -00217 static class_timers s_timers; -00218 -00219 void StartTimerLoop(TimerCallback_t init_callback) -00220 { -00221 s_timers.start_timer_thread(); -00222 // At first, TimeDispatch will call init_callback. -00223 if (init_callback != NULL) -00224 SetAlarm(NULL, 0, init_callback, (TIMEVAL)0, (TIMEVAL)0); -00225 s_timers.resume_timer_thread(); -00226 } -00227 -00228 void StopTimerLoop(void) -00229 { -00230 s_timers.stop_timer_thread(); -00231 } -00232 -00233 void setTimer(TIMEVAL value) -00234 { -00235 s_timers.set_timer(value); -00236 } -00237 -00238 TIMEVAL getElapsedTime(void) -00239 { -00240 return s_timers.get_elapsed_time(); -00241 } -