Changeset 863
- Timestamp:
- 01/19/08 14:36:47 (16 years ago)
- Files:
-
- trunk/libffado/config.h.in (modified) (1 diff)
- trunk/libffado/src/libieee1394/CycleTimerHelper.cpp (modified) (14 diffs)
- trunk/libffado/src/libieee1394/CycleTimerHelper.h (modified) (4 diffs)
- trunk/libffado/src/libieee1394/ieee1394service.cpp (modified) (4 diffs)
- trunk/libffado/src/libieee1394/ieee1394service.h (modified) (1 diff)
- trunk/libffado/src/libutil/SystemTimeSource.cpp (modified) (3 diffs)
- trunk/libffado/tests/test-ieee1394service.cpp (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/libffado/config.h.in
r862 r863 42 42 #define DEBUG_IMPLEMENT_BACKLOG 0 43 43 44 #define IEEE1394SERVICE_USE_CYCLETIMER_DLL 0 44 #define IEEE1394SERVICE_USE_CYCLETIMER_DLL 1 45 #define IEEE1394SERVICE_CYCLETIMER_DLL_UPDATE_INTERVAL_USEC 50000 45 46 #define IEEE1394SERVICE_MAX_FIREWIRE_PORTS 16 46 47 trunk/libffado/src/libieee1394/CycleTimerHelper.cpp
r807 r863 28 28 #include "libutil/PosixThread.h" 29 29 30 #define DLL_BANDWIDTH (0. 01)30 #define DLL_BANDWIDTH (0.1) 31 31 #define DLL_PI (3.141592653589793238) 32 32 #define DLL_SQRT2 (1.414213562373095049) … … 35 35 #define DLL_COEFF_C (DLL_OMEGA * DLL_OMEGA) 36 36 37 #define OFFSET_AVERAGE_COEFF 0.01 37 38 /* 38 39 #define ENTER_CRITICAL_SECTION { \ … … 63 64 , m_next_time_ticks ( 0 ) 64 65 , m_first_run ( true ) 66 , m_sleep_until ( 0 ) 65 67 , m_Thread ( NULL ) 66 68 , m_realtime ( false ) … … 81 83 , m_next_time_ticks ( 0 ) 82 84 , m_first_run ( true ) 85 , m_sleep_until ( 0 ) 83 86 , m_Thread ( NULL ) 84 87 , m_realtime ( rt ) … … 143 146 } 144 147 148 #if IEEE1394SERVICE_USE_CYCLETIMER_DLL 145 149 float 146 150 CycleTimerHelper::getRate() … … 158 162 } 159 163 160 #if IEEE1394SERVICE_USE_CYCLETIMER_DLL161 162 164 bool 163 165 CycleTimerHelper::Execute() 164 166 { 165 167 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Execute %p...\n", this); 168 if (!m_first_run) { 169 // wait for the next update period 170 ffado_microsecs_t now = m_TimeSource.getCurrentTimeAsUsecs(); 171 int sleep_time = m_sleep_until - now; 172 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "(%p) Sleep until %lld/%f (now: %lld, diff=%d) ...\n", 173 this, m_sleep_until, m_next_time_usecs, now, sleep_time); 174 m_TimeSource.SleepUsecAbsolute(m_sleep_until); 175 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " (%p) back...\n", this); 176 } 177 166 178 uint32_t cycle_timer; 167 179 uint64_t local_time; … … 173 185 cycle_timer, local_time); 174 186 175 double usecs_late;176 187 if (m_first_run) { 177 usecs_late = 0.0;188 m_sleep_until = local_time + m_usecs_per_update; 178 189 m_dll_e2 = m_ticks_per_update; 179 190 m_current_time_usecs = local_time; … … 188 199 m_first_run = false; 189 200 } else { 190 191 double diff = m_next_time_usecs - m_current_time_usecs; 192 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " usecs: local: %11llu current: %f next: %f, diff: %f\n", 193 local_time, m_current_time_usecs, m_next_time_usecs, diff); 194 201 m_sleep_until += m_usecs_per_update; 195 202 uint64_t cycle_timer_ticks = CYCLE_TIMER_TO_TICKS(cycle_timer); 196 usecs_late = ((double)local_time) - (m_next_time_usecs); 197 198 // we update the x-axis values 203 double usecs_late = ((double)local_time) - (m_next_time_usecs); 204 205 // update the x-axis values 206 double diff_ticks = diffTicks(cycle_timer_ticks, (int64_t)m_next_time_ticks); 207 m_current_time_ticks = m_next_time_ticks; 208 // do the calculation in 'tick space' 209 int64_t tmp = (uint64_t)(DLL_COEFF_B * diff_ticks); 210 if(m_dll_e2 > 0) { 211 tmp = addTicks(tmp, (uint64_t)m_dll_e2); 212 } else { 213 tmp = substractTicks(tmp, (uint64_t)(-m_dll_e2)); 214 } 215 if(tmp < 0) { 216 debugWarning("negative slope: %lld!\n", tmp); 217 } 218 m_next_time_ticks = addTicks((uint64_t)m_current_time_ticks, tmp); 219 220 // it should be ok to not do this in tick space since it's value 221 // is approx equal to the rate, being 24.576 ticks/usec 222 m_dll_e2 += DLL_COEFF_C * diff_ticks; 223 224 // update the y-axis values 199 225 m_current_time_usecs = m_next_time_usecs; 200 m_next_time_usecs = (local_time - usecs_late) + m_usecs_per_update; 226 m_next_time_usecs = local_time + m_usecs_per_update; 227 201 228 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " usecs: current: %f next: %f usecs_late=%f\n", 202 229 m_current_time_usecs, m_next_time_usecs, usecs_late); 203 204 // and the y-axis values205 double diff_ticks = diffTicks(cycle_timer_ticks, (int64_t)m_next_time_ticks);206 m_current_time_ticks = m_next_time_ticks;207 m_next_time_ticks = addTicks((uint64_t)m_current_time_ticks,208 (uint64_t)((DLL_COEFF_B * diff_ticks) + m_dll_e2));209 m_dll_e2 += DLL_COEFF_C * diff_ticks;210 230 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " ticks: current: %f next: %f diff=%f\n", 211 231 m_current_time_ticks, m_next_time_ticks, diff_ticks); … … 215 235 } 216 236 217 // track the average wakeup delay218 m_avg_wakeup_delay += 0.01 * usecs_late;219 220 237 // FIXME: priority inversion! 221 238 ENTER_CRITICAL_SECTION; 222 m_current_vars.ticks = m_current_time_ticks;223 m_current_vars.usecs = m_current_time_usecs;239 m_current_vars.ticks = (uint64_t)(m_current_time_ticks);// + m_average_offset_ticks); 240 m_current_vars.usecs = (uint64_t)m_current_time_usecs; 224 241 m_current_vars.rate = getRate(); 225 242 EXIT_CRITICAL_SECTION; 226 243 227 // wait for the next update period228 int64_t time_to_sleep = (int64_t)m_next_time_usecs - m_Parent.getCurrentTimeAsUsecs();229 time_to_sleep -= (int64_t)m_avg_wakeup_delay;230 //int64_t time_to_sleep = m_usecs_per_update;231 if (time_to_sleep > 0) {232 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " sleeping %lld usecs (avg delay: %f)\n", time_to_sleep, m_avg_wakeup_delay);233 usleep(time_to_sleep);234 }235 244 return true; 236 245 } … … 254 263 EXIT_CRITICAL_SECTION; 255 264 256 doubletime_diff = now - my_vars.usecs;257 double y_step_in_ticks = time_diff* my_vars.rate;265 int64_t time_diff = now - my_vars.usecs; 266 double y_step_in_ticks = ((double)time_diff) * my_vars.rate; 258 267 int64_t y_step_in_ticks_int = (int64_t)y_step_in_ticks; 259 uint64_t offset_in_ticks_int = (uint64_t)my_vars.ticks;268 uint64_t offset_in_ticks_int = my_vars.ticks; 260 269 261 270 if (y_step_in_ticks_int > 0) { … … 277 286 CycleTimerHelper::getCycleTimer() 278 287 { 279 return TICKS_TO_CYCLE_TIMER(getCycleTimerTicks()); 288 uint64_t now = m_Parent.getCurrentTimeAsUsecs(); 289 return getCycleTimer(now); 280 290 } 281 291 … … 283 293 CycleTimerHelper::getCycleTimer(uint64_t now) 284 294 { 285 return TICKS_TO_CYCLE_TIMER(getCycleTimerTicks(now)); 295 uint32_t ticks = getCycleTimerTicks(now); 296 uint32_t result = TICKS_TO_CYCLE_TIMER(ticks); 297 #ifdef DEBUG 298 if(CYCLE_TIMER_TO_TICKS(result) != ticks) { 299 debugWarning("Bad ctr conversion"); 300 } 301 #endif 302 return result; 286 303 } 287 304 288 305 #else 306 307 float 308 CycleTimerHelper::getRate() 309 { 310 return getNominalRate(); 311 } 312 313 float 314 CycleTimerHelper::getNominalRate() 315 { 316 float rate = ((double)TICKS_PER_SECOND) / 1000000.0; 317 return rate; 318 } 289 319 290 320 bool … … 309 339 CycleTimerHelper::getCycleTimerTicks(uint64_t now) 310 340 { 341 debugWarning("not implemented!\n"); 311 342 return getCycleTimerTicks(); 312 343 } … … 327 358 CycleTimerHelper::getCycleTimer(uint64_t now) 328 359 { 360 debugWarning("not implemented!\n"); 329 361 return getCycleTimer(); 330 362 } trunk/libffado/src/libieee1394/CycleTimerHelper.h
r752 r863 21 21 * 22 22 */ 23 24 #include "libutil/Thread.h" 25 #include "cycletimer.h" 23 #ifndef __CYCLETIMERHELPER_H__ 24 #define __CYCLETIMERHELPER_H__ 26 25 27 26 /** … … 50 49 * different clock domains to operate together. 51 50 */ 52 #ifndef __CYCLETIMERTHREAD_H__ 53 #define __CYCLETIMERTHREAD_H__ 51 52 #include "libutil/Thread.h" 53 #include "libutil/SystemTimeSource.h" 54 #include "cycletimer.h" 54 55 55 56 #include "debugmodule/debugmodule.h" 56 57 57 58 class Ieee1394Service; 58 namespace Util {59 class TimeSource;60 class Thread;61 }62 59 63 60 class CycleTimerHelper : public Util::RunnableInterface … … 105 102 private: 106 103 Ieee1394Service &m_Parent; 104 Util::SystemTimeSource m_TimeSource; 107 105 // parameters 108 106 uint32_t m_ticks_per_update; … … 119 117 double m_next_time_ticks; 120 118 bool m_first_run; 119 ffado_microsecs_t m_sleep_until; 121 120 122 121 // cached vars used for computation 123 122 struct compute_vars { 124 doubleusecs;125 doubleticks;123 uint64_t usecs; 124 uint64_t ticks; 126 125 double rate; 127 126 }; trunk/libffado/src/libieee1394/ieee1394service.cpp
r807 r863 53 53 , m_base_priority ( 0 ) 54 54 , m_pIsoManager( new IsoHandlerManager( *this ) ) 55 , m_pCTRHelper ( new CycleTimerHelper( *this, 10000) )55 , m_pCTRHelper ( new CycleTimerHelper( *this, IEEE1394SERVICE_CYCLETIMER_DLL_UPDATE_INTERVAL_USEC ) ) 56 56 , m_have_new_ctr_read ( false ) 57 57 , m_pTimeSource ( new Util::SystemTimeSource() ) … … 77 77 , m_base_priority ( prio ) 78 78 , m_pIsoManager( new IsoHandlerManager( *this, rt, prio + IEEE1394SERVICE_ISOMANAGER_PRIO_INCREASE ) ) 79 , m_pCTRHelper ( new CycleTimerHelper( *this, 1000, rt, prio + IEEE1394SERVICE_CYCLETIMER_HELPER_PRIO_INCREASE ) ) 79 , m_pCTRHelper ( new CycleTimerHelper( *this, IEEE1394SERVICE_CYCLETIMER_DLL_UPDATE_INTERVAL_USEC, 80 rt, prio + IEEE1394SERVICE_CYCLETIMER_HELPER_PRIO_INCREASE ) ) 80 81 , m_have_new_ctr_read ( false ) 81 82 , m_pTimeSource ( new Util::SystemTimeSource() ) … … 318 319 } 319 320 321 /** 322 * Returns the current value of the cycle timer (in ticks) 323 * for a specific time instant (usecs since epoch) 324 * @return the current value of the cycle timer (in ticks) 325 */ 326 327 uint32_t 328 Ieee1394Service::getCycleTimerTicks(uint64_t t) { 329 return m_pCTRHelper->getCycleTimerTicks(t); 330 } 331 332 /** 333 * Returns the current value of the cycle timer (as is) 334 * for a specific time instant (usecs since epoch) 335 * @return the current value of the cycle timer (as is) 336 */ 337 uint32_t 338 Ieee1394Service::getCycleTimer(uint64_t t) { 339 return m_pCTRHelper->getCycleTimer(t); 340 } 341 320 342 bool 321 343 Ieee1394Service::readCycleTimerReg(uint32_t *cycle_timer, uint64_t *local_time) … … 1065 1087 Ieee1394Service::show() 1066 1088 { 1089 uint32_t cycle_timer; 1090 uint64_t local_time; 1091 if(!readCycleTimerReg(&cycle_timer, &local_time)) { 1092 debugWarning("Could not read cycle timer register\n"); 1093 } 1094 uint64_t ctr = CYCLE_TIMER_TO_TICKS( cycle_timer ); 1095 1067 1096 debugOutput( DEBUG_LEVEL_VERBOSE, "Port: %d\n", getPort() ); 1068 1097 debugOutput( DEBUG_LEVEL_VERBOSE, " Name: %s\n", getPortName().c_str() ); 1098 debugOutput( DEBUG_LEVEL_VERBOSE, " Time: %011llu (%03us %04ucy %04uticks)\n", 1099 ctr, 1100 (unsigned int)TICKS_TO_SECS( ctr ), 1101 (unsigned int)TICKS_TO_CYCLES( ctr ), 1102 (unsigned int)TICKS_TO_OFFSET( ctr ) ); 1069 1103 debugOutputShort( DEBUG_LEVEL_NORMAL, "Iso handler info:\n"); 1070 1104 if (m_pIsoManager) m_pIsoManager->dumpInfo(); trunk/libffado/src/libieee1394/ieee1394service.h
r752 r863 115 115 */ 116 116 uint32_t getCycleTimer(); 117 118 /** 119 * @brief get the cycle timer value for a specific time instant (in ticks) 120 * 121 * @note Uses the most appropriate method for getting the cycle timer 122 * which is not necessarily a direct read (could be DLL) 123 */ 124 uint32_t getCycleTimerTicks(uint64_t t); 125 126 /** 127 * @brief get the cycle timer value for a specific time instant (in CTR format) 128 * 129 * @note Uses the most appropriate method for getting the cycle timer 130 * which is not necessarily a direct read (could be DLL) 131 */ 132 uint32_t getCycleTimer(uint64_t t); 117 133 118 134 /** trunk/libffado/src/libutil/SystemTimeSource.cpp
r787 r863 25 25 #include "Time.h" 26 26 27 // needed for clock_nanosleep 28 #ifndef _GNU_SOURCE 29 #define _GNU_SOURCE 30 #endif 31 32 #include <time.h> 33 27 34 namespace Util { 28 35 … … 37 44 void 38 45 SystemTimeSource::SleepUsecRelative(ffado_microsecs_t usecs) { 39 usleep(usecs); 46 //usleep(usecs); 47 struct timespec ts; 48 ts.tv_sec = usecs / (1000000LL); 49 ts.tv_nsec = (usecs % (1000000LL)) * 1000LL; 50 clock_nanosleep(CLOCK_REALTIME, 0, &ts, NULL); 40 51 } 41 52 42 53 void 43 SystemTimeSource::SleepUsecAbsolute(ffado_microsecs_t wake_at) { 44 // FIXME: not implemented yet 54 SystemTimeSource::SleepUsecAbsolute(ffado_microsecs_t wake_at_usec) { 55 struct timespec ts; 56 ts.tv_sec = wake_at_usec / (1000000LL); 57 ts.tv_nsec = (wake_at_usec % (1000000LL)) * 1000LL; 58 clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &ts, NULL); 45 59 } 46 60 … … 50 64 // return tv.tv_sec * 1000000ULL + tv.tv_usec; 51 65 struct timespec ts; 52 clock_gettime(CLOCK_ MONOTONIC, &ts);66 clock_gettime(CLOCK_REALTIME, &ts); 53 67 return (ffado_microsecs_t)(ts.tv_sec * 1000000LL + ts.tv_nsec / 1000LL); 54 68 } trunk/libffado/tests/test-ieee1394service.cpp
r862 r863 47 47 48 48 49 #define NB_THREADS 350 #define THREAD_RT true51 #define THREAD_PRIO 9052 #define THREAD_SLEEP_US 10049 #define NB_THREADS 1 50 #define THREAD_RT true 51 #define THREAD_PRIO 51 52 #define THREAD_SLEEP_US 2000 53 53 54 54 using namespace Util; … … 56 56 DECLARE_GLOBAL_DEBUG_MODULE; 57 57 58 #define DIFF_CONSIDERED_LARGE 30720 59 int PORT_TO_USE = 0; 58 #define DIFF_CONSIDERED_LARGE (3027/2) 59 int PORT_TO_USE = 1; 60 61 int max_diff=-99999; 62 int min_diff= 99999; 60 63 61 64 int run=1; … … 130 133 131 134 ctr = CYCLE_TIMER_TO_TICKS( cycle_timer ); 132 ctr_dll = m_service->getCycleTimerTicks( );135 ctr_dll = m_service->getCycleTimerTicks(local_time); 133 136 134 137 if(err) { … … 149 152 int64_t diff = diffTicks(ctr, ctr_dll); 150 153 uint64_t abs_diff; 154 155 // not 100% thread safe, but will do 156 if (diff > max_diff) max_diff = diff; 157 if (diff < min_diff) min_diff = diff; 151 158 152 159 if (diff < 0) { … … 255 262 256 263 m_service = new Ieee1394Service(); 257 m_service->setVerboseLevel(DEBUG_LEVEL_VERBOSE 264 m_service->setVerboseLevel(DEBUG_LEVEL_VERBOSE); 258 265 m_service->initialize(PORT_TO_USE); 259 m_service->setThreadParameters(true, 20);266 m_service->setThreadParameters(true, 60); 260 267 261 268 MyFunctor *test_busreset=new MyFunctor(); … … 315 322 while(run) { 316 323 i++; 317 debugOutput(DEBUG_LEVEL_NORMAL, "%08d: alive...\n", i); 324 debugOutput(DEBUG_LEVEL_NORMAL, "%08d: alive, (max: %6d, min: %6d)\n", i, max_diff, min_diff); 325 m_service->show(); 318 326 sleep(5); 319 327 }