diff -r 003cc3c63855 -r f49e5a6b7804 doc/doxygen/html/timers__win32_8cpp-source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/doxygen/html/timers__win32_8cpp-source.html Fri Jun 08 09:23:56 2007 +0200 @@ -0,0 +1,267 @@ + + +CanFestival: drivers/win32/timers_win32.cpp Source File + + + + +
+
+
+
+ +

timers_win32.cpp

Go to the documentation of this file.
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    }
+

Generated on Fri Jun 8 08:51:38 2007 for CanFestival by  + +doxygen 1.5.1
+ +