00001
00002
00003
00004
00005
00006
00007
00008 #include "RealtimeThread.h"
00009 #include <iostream>
00010 #include <sys/mman.h>
00011 #include <cstring>
00012
00013 #define MAX_SAFE_STACK (8*1024)
00014
00015
00016
00017 void stack_prefault(void)
00018 {
00019 unsigned char dummy[MAX_SAFE_STACK];
00020 memset(&dummy, 0, MAX_SAFE_STACK);
00021 return;
00022 }
00023
00024 namespace uvsim
00025 {
00026
00027 RealtimeThread::RealtimeThread(int priority, float freq)
00028 {
00029 m_stopRequested = false;
00030 m_priority = priority;
00031 m_waitNSec = 1.0/freq*m_nSecPerSec;
00032
00033
00034 if (m_priority > 0)
00035 {
00036 m_sched.sched_priority = m_priority;
00037 if (sched_setscheduler(0, SCHED_FIFO, &m_sched)==-1)
00038 {
00039 perror("sched_setscheduler failed");
00040 exit(-1);
00041 }
00042 else
00043 {
00044 std::cout << "Running as a realtime thread with priority: "<< m_priority << std::endl;
00045 }
00046 }
00047 else
00048 {
00049 std::cout << "Running as a non-realtime thread" << std::endl;
00050 }
00051
00052
00053 stack_prefault();
00054
00055 clock_gettime(CLOCK_MONOTONIC, &m_time);
00056
00057 m_time.tv_sec++;
00058 }
00059
00060 RealtimeThread::~RealtimeThread()
00061 {
00062 pthread_cancel(m_thread);
00063 }
00064
00065 void * RealtimeThread::thread_func(void *d)
00066 {
00067 ((RealtimeThread *) d)->run();
00068 }
00069
00070 void RealtimeThread::run()
00071 {
00072 while (!m_stopRequested)
00073 {
00074
00075 clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &m_time, NULL);
00076
00077
00078 loop();
00079
00080
00081 m_time.tv_nsec += m_waitNSec;
00082
00083 #ifdef DEBUG
00084 std::cout << "Realtime thread timestamp: " << m_time.tv_sec << " sec " << m_time.tv_nsec << " nsec " << std::endl;
00085 #endif
00086
00087 while (m_time.tv_nsec >= m_nSecPerSec)
00088 {
00089 m_time.tv_nsec -= m_nSecPerSec;
00090 m_time.tv_sec++;
00091 }
00092 }
00093 }
00094
00095 int RealtimeThread::start()
00096 {
00097 m_stopRequested = false;
00098 return pthread_create(&m_thread, NULL, RealtimeThread::thread_func,
00099 (void*) this);
00100 }
00101 void RealtimeThread::stop()
00102 {
00103 m_stopRequested = true;
00104 }
00105
00106 int RealtimeThread::join()
00107 {
00108 return pthread_join(m_thread, NULL);
00109
00110 }
00111
00112 }