Tekkotsu Homepage | Demos | Overview | Downloads | Dev. Resources | Reference | Credits |
PollThread.ccGo to the documentation of this file.00001 #ifndef PLATFORM_APERIOS 00002 #include "PollThread.h" 00003 #include <stdio.h> 00004 #include <errno.h> 00005 #include <signal.h> 00006 00007 //better to put this here instead of the header 00008 using namespace std; 00009 00010 void PollThread::start() { 00011 initialPoll=true; 00012 startTime.Set(); 00013 Thread::start(); 00014 } 00015 00016 bool PollThread::poll() { 00017 unsigned int sleeptime=runloop(); 00018 if(sleeptime==-1U) 00019 return false; 00020 period.Set(static_cast<long>(sleeptime)); 00021 return true; 00022 } 00023 00024 void PollThread::interrupted() { 00025 if(!initialPoll) { 00026 if(period-startTime.Age()<1L) { 00027 delay=0L; 00028 } else { 00029 while(!(period-startTime.Age()<1L)) 00030 startTime-=period; 00031 startTime+=period; 00032 delay=period; 00033 } 00034 } 00035 } 00036 00037 void * PollThread::run() { 00038 timespec sleepSpec,remainSpec; 00039 TimeET age = startTime.Age(); 00040 if(age<delay) { 00041 sleepSpec=delay-age; 00042 while(nanosleep(&sleepSpec,&remainSpec)) { 00043 if(errno!=EINTR) { 00044 if(errno==EINVAL) 00045 std::cerr << "Invalid PollThread periodic sleep time, age=" << startTime.Age() << " period=" << period << ", delay=" << delay << " sleepSpec=" << sleepSpec.tv_sec << ' ' << sleepSpec.tv_nsec << std::endl; 00046 else 00047 perror("PollThread::run(): initial nanosleep"); 00048 break; 00049 } 00050 testCancel(); 00051 //interrupted() may have changed delay to indicate remaining sleep time 00052 age = startTime.Age(); 00053 if(delay<1L || delay<age) 00054 break; 00055 sleepSpec=delay-age; 00056 } 00057 } 00058 testCancel(); 00059 if(!poll()) 00060 return returnValue; 00061 initialPoll=false; 00062 bool wasInterrupted=true; // need to add delay instead of period for the first time, same as if an interrupt occurred 00063 for(;;) { 00064 bool noSleep=false; 00065 if(TimeET(0,0)<period) { 00066 if(trackPollTime) { 00067 if(wasInterrupted) { 00068 if(delay<0L || startTime.Age()<delay) {} 00069 else 00070 startTime+=delay; 00071 } else { 00072 if(startTime.Age()<period) {} 00073 else 00074 startTime+=period; 00075 } 00076 //the idea with this part is that if we get behind, (because of poll() taking longer than period) 00077 // then we want to quick poll again as fast as we can to catch up, but we don't want to backlog 00078 // such that we'll be quick-calling multiple times once we do catch up 00079 if(period<startTime.Age()) { 00080 noSleep=true; 00081 while(period<startTime.Age()) 00082 startTime+=period; 00083 startTime-=period; //back off one -- the amount we've overshot counts towards the next period 00084 } 00085 age = startTime.Age(); 00086 if(age<period) 00087 sleepSpec=period-age; 00088 else 00089 noSleep=true; 00090 } else { 00091 sleepSpec=period; 00092 startTime.Set(); 00093 } 00094 wasInterrupted=false; 00095 while(!noSleep && nanosleep(&sleepSpec,&remainSpec)) { 00096 wasInterrupted=true; 00097 if(errno!=EINTR) { 00098 if(errno==EINVAL) 00099 std::cerr << "Invalid PollThread periodic sleep time, age=" << startTime.Age() << " period=" << period << ", delay=" << delay << " sleepSpec=" << sleepSpec.tv_sec << ' ' << sleepSpec.tv_nsec << std::endl; 00100 else 00101 perror("PollThread::run(): periodic nanosleep"); 00102 break; 00103 } 00104 testCancel(); 00105 //interrupted() should have changed delay and/or period to indicate remaining sleep time 00106 age = startTime.Age(); 00107 if(delay<1L || delay<age) 00108 break; 00109 sleepSpec=delay-age; 00110 } 00111 } else { 00112 startTime.Set(); 00113 } 00114 testCancel(); 00115 if(!poll()) 00116 return returnValue; 00117 } 00118 // this return is just to satisfy warnings with silly compiler 00119 return returnValue; //never happens -- cancel or bad poll would exit 00120 } 00121 00122 //void PollThread::cancelled() { 00123 //signal handlers are global, not per-thread, so if we reset the handler, then the next interrupt will cause the program to end :( 00124 //signal(SIGALRM,SIG_DFL); 00125 //} 00126 00127 00128 00129 /*! @file 00130 * @brief 00131 * @author Ethan Tira-Thompson (ejt) (Creator) 00132 */ 00133 #endif |
Tekkotsu v5.1CVS |
Generated Mon May 9 04:58:49 2016 by Doxygen 1.6.3 |