00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
00074
00075
00076
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
00089 }
00090
00091
00092
00093
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
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
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
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
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
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 }