diff -r 8678a3cf7fe7 -r 96c688ebcde7 drivers/win32/timers_win32.cpp --- a/drivers/win32/timers_win32.cpp Tue Sep 04 17:47:46 2007 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,241 +0,0 @@ -/* -This file is part of CanFestival, a library implementing CanOpen Stack. - -Copyright (C): Edouard TISSERANT and Francis DUPIN -Copyright (C) Win32 Port Leonid Tochinski - -See COPYING file for copyrights details. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - - - -#include -#include - -extern "C" -{ -#include "applicfg.h" -#include "can_driver.h" -#include "timer.h" -#include "timers_driver.h" -}; - -// --------------- Synchronization Object Implementation --------------- -class ccritical_section - { - public: - ccritical_section() - { - ::InitializeCriticalSection(&m_cs); - } - ~ccritical_section() - { - ::DeleteCriticalSection(&m_cs); - } - void enter() - { - ::EnterCriticalSection(&m_cs); - } - void leave() - { - ::LeaveCriticalSection(&m_cs); - } - private: - CRITICAL_SECTION m_cs; - }; - -static ccritical_section g_cs; - - -void EnterMutex(void) - { - g_cs.enter(); - } - -void LeaveMutex(void) - { - g_cs.leave(); - } -// --------------- Synchronization Object Implementation --------------- - - -// --------------- CAN Receive Thread Implementation --------------- - -void CreateReceiveTask(CAN_HANDLE fd0, TASK_HANDLE* Thread, void* ReceiveLoopPtr) - { - unsigned long thread_id = 0; - *Thread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReceiveLoopPtr, fd0, 0, &thread_id); - } - -void WaitReceiveTaskEnd(TASK_HANDLE Thread) - { - ::WaitForSingleObject(Thread, INFINITE); - ::CloseHandle(Thread); - //*Thread = NULL; - } -// --------------- CAN Receive Thread Implementation --------------- - - -// --------------- Timer Thread Implementation --------------- -class class_timers - { - public: - class_timers(); - ~class_timers(); - void start_timer_thread(); - void resume_timer_thread(); - void stop_timer_thread(); - void set_timer(TIMEVAL value); - TIMEVAL get_elapsed_time(); - private: - TIMEVAL get_timer() const; - static DWORD WINAPI timer_loop_thread_proc(void* arg); - private: - TIMEVAL m_last_occured_alarm_time; - volatile TIMEVAL m_last_alarm_set_time; - HANDLE m_timer_thread; - volatile bool m_continue_timer_loop; - bool m_use_hi_res_timer; - double m_counts_per_usec; - }; - -class_timers::class_timers() : m_last_occured_alarm_time(TIMEVAL_MAX), - m_last_alarm_set_time(TIMEVAL_MAX), - m_timer_thread(0), - m_continue_timer_loop(false), - m_use_hi_res_timer(false), - m_counts_per_usec(0.) - { - // initialize hi resolution timer - LARGE_INTEGER counts_per_sec = {0, 0}; - if (::QueryPerformanceFrequency(&counts_per_sec) && counts_per_sec.QuadPart > 0) - { - m_use_hi_res_timer = true; - m_counts_per_usec = counts_per_sec.QuadPart / 1000000.; - } - m_use_hi_res_timer = true; - } - -class_timers::~class_timers() - { - stop_timer_thread(); - } - -// time is in micro seconds -TIMEVAL class_timers::get_timer() const - { - if (m_use_hi_res_timer) - { - LARGE_INTEGER performance_count = {0, 0}; - ::QueryPerformanceCounter(&performance_count); - return (TIMEVAL)(performance_count.QuadPart / m_counts_per_usec); - } - // hi-res timer is unavailable - return 1000 * ::GetTickCount(); - } - -DWORD WINAPI class_timers::timer_loop_thread_proc(void* arg) - { - class_timers* This = reinterpret_cast(arg); - while (This->m_continue_timer_loop) - { - TIMEVAL cur_time = This->get_timer(); - if (cur_time >= This->m_last_alarm_set_time) - { - This->m_last_occured_alarm_time = cur_time; - This->m_last_alarm_set_time = TIMEVAL_MAX; - EnterMutex(); - TimeDispatch(); - LeaveMutex(); - } - else - { - ::Sleep(1); - } - } - return 0; - } - -void class_timers::start_timer_thread() - { - if (m_timer_thread == 0) - { - unsigned long thread_id = 0; - m_timer_thread = ::CreateThread(NULL, 0, &timer_loop_thread_proc, this, CREATE_SUSPENDED, &thread_id); - m_last_alarm_set_time = TIMEVAL_MAX; - m_last_occured_alarm_time = get_timer(); - } - } - -void class_timers::resume_timer_thread() - { - if (m_timer_thread) - { - m_continue_timer_loop = true; - ::ResumeThread(m_timer_thread); - } - } - -void class_timers::stop_timer_thread() - { - if (m_timer_thread) - { - m_continue_timer_loop = false; - ::WaitForSingleObject(m_timer_thread, INFINITE); - ::CloseHandle(m_timer_thread); - m_timer_thread = 0; - } - } - -void class_timers::set_timer(TIMEVAL value) - { - m_last_alarm_set_time = (value == TIMEVAL_MAX) ? TIMEVAL_MAX : get_timer() + value; - } - -// elapsed time since last occured alarm -TIMEVAL class_timers::get_elapsed_time() - { - return get_timer() - m_last_occured_alarm_time; - } - -// ---------------------------------------------------------- - -static class_timers s_timers; - -void StartTimerLoop(TimerCallback_t init_callback) - { - s_timers.start_timer_thread(); - // At first, TimeDispatch will call init_callback. - if (init_callback != NULL) - SetAlarm(NULL, 0, init_callback, (TIMEVAL)0, (TIMEVAL)0); - s_timers.resume_timer_thread(); - } - -void StopTimerLoop(void) - { - s_timers.stop_timer_thread(); - } - -void setTimer(TIMEVAL value) - { - s_timers.set_timer(value); - } - -TIMEVAL getElapsedTime(void) - { - return s_timers.get_elapsed_time(); - }