Changeset 1016

Show
Ignore:
Timestamp:
04/24/08 05:13:02 (13 years ago)
Author:
ppalmers
Message:

- move lock to improve timing of ctr read. grabbing locks can take some time (esp. on non-rt kernels). we can read the data before locking anyway.
- add some debugging to track the quality of the CTR DLL updates
- relax the filter coeffs

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/src/libieee1394/CycleTimerHelper.cpp

    r1002 r1016  
    3535// the high-bandwidth coefficients are used 
    3636// to speed up inital tracking 
    37 #define DLL_BANDWIDTH_HIGH (0.2
     37#define DLL_BANDWIDTH_HIGH (0.1
    3838#define DLL_OMEGA_HIGH     (2.0*DLL_PI*DLL_BANDWIDTH_HIGH) 
    3939#define DLL_COEFF_B_HIGH   (DLL_SQRT2 * DLL_OMEGA_HIGH) 
     
    4242// the low-bandwidth coefficients are used once we have a 
    4343// good estimate of the internal parameters 
    44 #define DLL_BANDWIDTH (0.01) 
     44#define DLL_BANDWIDTH (0.1) 
    4545#define DLL_OMEGA     (2.0*DLL_PI*DLL_BANDWIDTH) 
    4646#define DLL_COEFF_B   (DLL_SQRT2 * DLL_OMEGA) 
    4747#define DLL_COEFF_C   (DLL_OMEGA * DLL_OMEGA) 
    4848 
    49 // is 5 sec 
     49// is 1 sec 
    5050#define UPDATES_WITH_HIGH_BANDWIDTH \ 
    51          (5000000 / IEEE1394SERVICE_CYCLETIMER_DLL_UPDATE_INTERVAL_USEC) 
     51         (1000000 / IEEE1394SERVICE_CYCLETIMER_DLL_UPDATE_INTERVAL_USEC) 
    5252 
    5353IMPL_DEBUG_MODULE( CycleTimerHelper, CycleTimerHelper, DEBUG_LEVEL_NORMAL ); 
     
    352352    } 
    353353 
    354     // grab the lock after sleeping, otherwise we can't be interrupted by 
    355     // the busreset thread (lower prio) 
    356     pthread_mutex_lock(&mb_update_lock); 
    357  
    358354    uint32_t cycle_timer; 
    359355    uint64_t local_time; 
    360356    int64_t usecs_late; 
    361     int ntries=2
     357    int ntries=4
    362358    uint64_t cycle_timer_ticks; 
    363359    double diff_ticks; 
     
    370366        if(!readCycleTimerWithRetry(&cycle_timer, &local_time, 10)) { 
    371367            debugError("Could not read cycle timer register\n"); 
    372             pthread_mutex_unlock(&mb_update_lock); 
    373368            return false; 
    374369        } 
     
    380375        if(diff_ticks < -((double)TICKS_PER_HALFCYCLE)) { 
    381376            debugOutput(DEBUG_LEVEL_VERBOSE,  
    382                         "(%p) have to retry CTR read, diff unrealistic: diff: %f, max: %f\n",  
    383                         this, diff_ticks, -((double)TICKS_PER_HALFCYCLE)); 
     377                        "(%p) have to retry CTR read, diff unrealistic: diff: %f, max: %f (try: %d)\n",  
     378                        this, diff_ticks, -((double)TICKS_PER_HALFCYCLE), ntries); 
    384379        } 
    385380 
    386381    } while( diff_ticks < -((double)TICKS_PER_HALFCYCLE)  
    387382             && --ntries && !m_first_run && !m_unhandled_busreset); 
     383 
     384    // grab the lock after sleeping, otherwise we can't be interrupted by 
     385    // the busreset thread (lower prio) 
     386    // also grab it after reading the CTR register such that the jitter between 
     387    // wakeup and read is as small as possible 
     388    pthread_mutex_lock(&mb_update_lock); 
     389 
     390    // // simulate a random scheduling delay between (0-10ms) 
     391    // ffado_microsecs_t tmp = m_TimeSource.SleepUsecRandom(10000); 
     392    // debugOutput( DEBUG_LEVEL_VERBOSE, " (%p) random sleep of %llu usecs...\n", this, tmp); 
    388393 
    389394    if(m_unhandled_busreset) { 
     
    547552 
    548553    pthread_mutex_unlock(&mb_update_lock); 
     554 
     555#ifdef DEBUG 
     556    // do some verification 
     557    // we re-read a valid ctr timestamp 
     558    // then we use the attached system time to calculate 
     559    // the DLL generated timestamp and we check what the 
     560    // difference is 
     561 
     562    if(!readCycleTimerWithRetry(&cycle_timer, &local_time, 10)) { 
     563        debugError("Could not read cycle timer register (verify)\n"); 
     564        return true; // true since this is a check only 
     565    } 
     566    cycle_timer_ticks = CYCLE_TIMER_TO_TICKS(cycle_timer); 
     567 
     568    // only check when successful 
     569    int64_t time_diff = local_time - new_vars.usecs; 
     570    double y_step_in_ticks = ((double)time_diff) * new_vars.rate; 
     571    int64_t y_step_in_ticks_int = (int64_t)y_step_in_ticks; 
     572    uint64_t offset_in_ticks_int = new_vars.ticks; 
     573    uint32_t dll_time; 
     574    if (y_step_in_ticks_int > 0) { 
     575        dll_time = addTicks(offset_in_ticks_int, y_step_in_ticks_int); 
     576    } else { 
     577        dll_time = substractTicks(offset_in_ticks_int, -y_step_in_ticks_int); 
     578    } 
     579    int32_t ctr_diff = cycle_timer_ticks-dll_time; 
     580    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%p) CTR DIFF: HW %010llu - DLL %010lu = %010ld (%s)\n",  
     581                this, cycle_timer_ticks, dll_time, ctr_diff, (ctr_diff>0?"lag":"lead")); 
     582#endif 
     583 
    549584    return true; 
    550585}