Changeset 1246

Show
Ignore:
Timestamp:
06/08/08 05:19:39 (12 years ago)
Author:
ppalmers
Message:

add dead handler detection

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/src/libieee1394/cycletimer.h

    r1090 r1246  
    4646#define CYCLE_TIMER_GET_CYCLES(x) ((((x) & 0x01FFF000UL) >> 12)) 
    4747#define CYCLE_TIMER_GET_OFFSET(x)  ((((x) & 0x00000FFFUL))) 
     48 
     49#define CYCLE_TIMER_SET_SECS(v, x)   (((v) & ~0xFE000000UL) | (((x) & 0x7F) << 25)) 
     50#define CYCLE_TIMER_SET_CYCLES(v, x) ((((v) & ~0x01FFF000UL) | (((x) & 0x1FFF) << 12))) 
     51#define CYCLE_TIMER_SET_OFFSET(v, x)  ((((v) & ~0x00000FFFUL) | ((x) & 0xFFF))) 
     52 
     53 
    4854#define CYCLE_TIMER_TO_TICKS(x) ((CYCLE_TIMER_GET_SECS(x)   * TICKS_PER_SECOND) +\ 
    4955                                   (CYCLE_TIMER_GET_CYCLES(x) * TICKS_PER_CYCLE ) +\ 
  • trunk/libffado/src/libieee1394/IsoHandler.cpp

    r1172 r1246  
    184184bool 
    185185IsoHandler::iterate() { 
    186     debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, "(%p, %s) Iterating ISO handler...\n", 
    187                 this, getTypeString()); 
     186    return iterate(m_manager.get1394Service().getCycleTimer()); 
     187
     188 
     189bool 
     190IsoHandler::iterate(uint32_t cycle_timer_now) { 
     191    debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, "(%p, %s) Iterating ISO handler at %08X...\n", 
     192                       this, getTypeString(), cycle_timer_now); 
     193    m_last_now = cycle_timer_now; 
    188194    if(m_State == E_Running) { 
    189195#if ISOHANDLER_FLUSH_BEFORE_ITERATE 
    190196        flush(); 
    191197#endif 
    192         m_last_now = m_manager.get1394Service().getCycleTimer(); 
    193198        if(raw1394_loop_iterate(m_handle)) { 
    194199            debugError( "IsoHandler (%p): Failed to iterate handler: %s\n", 
     
    294299    m_manager.requestShadowMapUpdate(); 
    295300    return 0; 
     301} 
     302 
     303/** 
     304 * Call this if you find out that this handler has died for some 
     305 * external reason. 
     306 */ 
     307void 
     308IsoHandler::notifyOfDeath() 
     309{ 
     310    // notify the client of the fact that we have died 
     311    m_Client->handlerDied(); 
    296312} 
    297313 
     
    717733    m_min_ahead = 7999; 
    718734#endif 
     735 
     736    // indicate that the first iterate() still has to occur. 
     737    m_last_now = 0xFFFFFFFF; 
     738 
    719739    m_State = E_Running; 
    720740    return true; 
  • trunk/libffado/src/libieee1394/IsoHandler.h

    r1038 r1246  
    8181 
    8282public: 
    83     // runnable interface 
     83 
     84    /** 
     85     * Iterate the handler, transporting ISO packets to the client(s) 
     86     * @return true if success 
     87     */ 
    8488    bool iterate(); 
     89 
     90    /** 
     91     * Iterate the handler, transporting ISO packets to the client(s) 
     92     * @param  ctr_now the CTR time at which the iterate call is done. 
     93     * @return true if success 
     94     */ 
     95    bool iterate(uint32_t ctr_now); 
    8596 
    8697    int getFileDescriptor() { return raw1394_get_fd(m_handle);}; 
     
    145156    int getLastCycle() {return m_last_cycle;}; 
    146157 
     158    /** 
     159     * @brief returns the CTR value saved at the last iterate() call 
     160     * @return CTR value saved at last iterate() call 
     161     */ 
     162    uint32_t getLastIterateTime() {return m_last_now;}; 
     163 
     164    void notifyOfDeath(); 
    147165private: 
    148166    IsoHandlerManager& m_manager; 
  • trunk/libffado/src/libieee1394/IsoHandlerManager.cpp

    r1234 r1246  
    2424#include "config.h" 
    2525#include "IsoHandlerManager.h" 
    26 #include "ieee1394service.h"  
     26#include "ieee1394service.h" 
     27#include "cycletimer.h" 
    2728#include "libstreaming/generic/StreamProcessor.h" 
    2829 
     
    223224                    // FIXME: what to do here? 
    224225                    debugWarning("Timeout while waiting for activity\n"); 
     226                    no_one_to_poll = false; // exit the loop to be able to detect failing handlers 
    225227                    break; 
    226228                case IsoTask::eAR_Activity: 
     
    237239    // the fd map everytime we run poll(). 
    238240    err = poll (m_poll_fds_shadow, m_poll_nfds_shadow, m_poll_timeout); 
     241    uint32_t ctr_at_poll_return = m_manager.get1394Service().getCycleTimer(); 
    239242 
    240243    if (err < 0) { 
     
    247250    } 
    248251 
     252    // find handlers that have died 
     253    uint64_t ctr_at_poll_return_ticks = CYCLE_TIMER_TO_TICKS(ctr_at_poll_return); 
     254    bool handler_died = false; 
     255    for (i = 0; i < m_poll_nfds_shadow; i++) { 
     256        // figure out if a handler has died 
     257        // all handlers in the poll() are active, so they should be iterated 
     258        // now and then. If they aren't, the handler has died. 
     259        uint32_t last_call = m_IsoHandler_map_shadow[i]->getLastIterateTime(); 
     260        if (last_call == 0xFFFFFFFF) { 
     261            // this was not iterated yet, so can't be dead 
     262            continue; 
     263        } 
     264 
     265        uint64_t last_call_ticks = CYCLE_TIMER_TO_TICKS(last_call); 
     266        // we use 4 seconds since that should not cause issues with startup 
     267        int64_t max_diff_ticks = TICKS_PER_SECOND * 4; 
     268        int64_t measured_diff_ticks = diffTicks(ctr_at_poll_return_ticks, last_call_ticks); 
     269 
     270        if(measured_diff_ticks > max_diff_ticks) { 
     271            debugFatal("(%p, %s) Handler died: now: %08lX, last: %08lX, diff: %lld (max: %lld)\n", 
     272                       this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"), 
     273                       ctr_at_poll_return, last_call, measured_diff_ticks, max_diff_ticks); 
     274            m_IsoHandler_map_shadow[i]->notifyOfDeath(); 
     275            handler_died = true; 
     276        } 
     277    } 
     278    if(handler_died) { 
     279        return false; // one or more handlers have died 
     280    } 
     281 
     282    // iterate the handlers 
    249283    for (i = 0; i < m_poll_nfds_shadow; i++) { 
    250284        #ifdef DEBUG 
     
    264298        // 2) the client can provide or accept packets (since we enabled polling) 
    265299        if(m_poll_fds_shadow[i].revents & (POLLIN)) { 
    266             m_IsoHandler_map_shadow[i]->iterate(); 
     300            m_IsoHandler_map_shadow[i]->iterate(ctr_at_poll_return); 
    267301        } else { 
    268302            // there might be some error condition 
     
    274308            } 
    275309        } 
    276  
    277 //         #ifdef DEBUG 
    278 //         // check if the handler is still alive 
    279 //         if(m_IsoHandler_map_shadow[i]->isDead()) { 
    280 //             debugError("Iso handler (%p, %s) is dead!\n", 
    281 //                        m_IsoHandler_map_shadow[i], 
    282 //                        m_IsoHandler_map_shadow[i]->getTypeString()); 
    283 //             return false; // shutdown the system 
    284 //         } 
    285 //         #endif 
    286  
    287310    } 
    288311    return true;