Changeset 753 for trunk

Show
Ignore:
Timestamp:
12/02/07 14:52:52 (16 years ago)
Author:
ppalmers
Message:

have separate threads for every handler

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/SConstruct

    r751 r753  
    230230 
    231231env['PACKAGE'] = "libffado" 
    232 env['VERSION'] = "1.999.8
     232env['VERSION'] = "1.999.9
    233233env['LIBVERSION'] = "1.0.0" 
    234234 
  • trunk/libffado/src/libieee1394/CycleTimerHelper.cpp

    r752 r753  
    8686                                     PTHREAD_CANCEL_DEFERRED); 
    8787    if(!m_Thread) { 
    88         debugFatal("Could not create update thread\n"); 
    89     } 
    90     if(!m_Thread) { 
    9188        debugFatal("No thread\n"); 
    9289        return false; 
     
    142139CycleTimerHelper::Execute() 
    143140{ 
    144     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Execute %p...\n", this); 
     141    debugOutput( DEBUG_LEVEL_ULTRA_VERBOSE, "Execute %p...\n", this); 
    145142    uint32_t cycle_timer; 
    146143    uint64_t local_time; 
     
    149146        return false; 
    150147    } 
    151     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " read : CTR: %11lu, local: %17llu\n", 
     148    debugOutput( DEBUG_LEVEL_ULTRA_VERBOSE, " read : CTR: %11lu, local: %17llu\n", 
    152149                    cycle_timer, local_time); 
    153150 
     
    169166 
    170167        double diff = m_next_time_usecs - m_current_time_usecs; 
    171         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " usecs: local: %11llu current: %f next: %f, diff: %f\n", 
     168        debugOutput( DEBUG_LEVEL_ULTRA_VERBOSE, " usecs: local: %11llu current: %f next: %f, diff: %f\n", 
    172169                    local_time, m_current_time_usecs, m_next_time_usecs, diff); 
    173170 
     
    178175        m_current_time_usecs = m_next_time_usecs; 
    179176        m_next_time_usecs = (local_time - usecs_late) + m_usecs_per_update; 
    180         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " usecs: current: %f next: %f usecs_late=%f\n", 
     177        debugOutput( DEBUG_LEVEL_ULTRA_VERBOSE, " usecs: current: %f next: %f usecs_late=%f\n", 
    181178                    m_current_time_usecs, m_next_time_usecs, usecs_late); 
    182179 
     
    187184                                     (uint64_t)((DLL_COEFF_B * diff_ticks) + m_dll_e2)); 
    188185        m_dll_e2 += DLL_COEFF_C * diff_ticks; 
    189         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " ticks: current: %f next: %f diff=%f\n", 
     186        debugOutput( DEBUG_LEVEL_ULTRA_VERBOSE, " ticks: current: %f next: %f diff=%f\n", 
    190187                    m_current_time_ticks, m_next_time_ticks, diff_ticks); 
    191188 
    192         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " state: local: %11llu, dll_e2: %f, rate: %f\n", 
     189        debugOutput( DEBUG_LEVEL_ULTRA_VERBOSE, " state: local: %11llu, dll_e2: %f, rate: %f\n", 
    193190                    local_time, m_dll_e2, getRate()); 
    194191    } 
     
    209206    //int64_t time_to_sleep = m_usecs_per_update; 
    210207    if (time_to_sleep > 0) { 
    211         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " sleeping %lld usecs (avg delay: %f)\n", time_to_sleep, m_avg_wakeup_delay); 
     208        debugOutput( DEBUG_LEVEL_ULTRA_VERBOSE, " sleeping %lld usecs (avg delay: %f)\n", time_to_sleep, m_avg_wakeup_delay); 
    212209        usleep(time_to_sleep); 
    213210    } 
     
    241238        retval = addTicks(offset_in_ticks_int, y_step_in_ticks_int); 
    242239    } else { 
    243         debugWarning("y_step_in_ticks_int <= 0: %lld\n", y_step_in_ticks_int); 
     240        // this can happen if the update thread was woken up earlier than it should have been 
     241        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "y_step_in_ticks_int <= 0: %lld, time_diff: %f, rate: %f\n",  
     242                     y_step_in_ticks_int, time_diff, my_vars.rate); 
    244243        retval = substractTicks(offset_in_ticks_int, -y_step_in_ticks_int); 
    245244    } 
  • trunk/libffado/src/libieee1394/ieee1394service.cpp

    r752 r753  
    4545#define FFADO_MAX_FIREWIRE_PORTS 16 
    4646 
    47 #define ISOMANAGER_PRIO_INCREASE         5 
    48 #define CYCLETIMER_HELPER_PRIO_INCREASE  6 
     47#define ISOMANAGER_PRIO_INCREASE         10 
     48#define CYCLETIMER_HELPER_PRIO_INCREASE  10 
    4949 
    5050IMPL_DEBUG_MODULE( Ieee1394Service, Ieee1394Service, DEBUG_LEVEL_NORMAL ); 
  • trunk/libffado/src/libieee1394/IsoHandler.cpp

    r750 r753  
    2626 
    2727#include "libstreaming/generic/StreamProcessor.h" 
     28#include "libutil/PosixThread.h" 
    2829 
    2930#include <errno.h> 
     
    8485   , m_dropped(0) 
    8586   , m_Client(0) 
     87   , m_poll_timeout( 100 ) 
     88   , m_realtime ( false ) 
     89   , m_priority ( 0 ) 
     90   , m_Thread ( NULL ) 
    8691   , m_State(E_Created) 
    8792{ 
     
    97102   , m_dropped(0) 
    98103   , m_Client(0) 
     104   , m_poll_timeout( 100 ) 
     105   , m_realtime ( false ) 
     106   , m_priority ( 0 ) 
     107   , m_Thread ( NULL ) 
    99108   , m_State(E_Created) 
    100109{ 
     
    102111 
    103112IsoHandler::~IsoHandler() { 
    104  
     113    if (m_Thread) { 
     114        m_Thread->Stop(); 
     115        delete m_Thread; 
     116    } 
    105117// Don't call until libraw1394's raw1394_new_handle() function has been 
    106118// fixed to correctly initialise the iso_packet_infos field.  Bug is 
     
    116128} 
    117129 
    118 bool IsoHandler::iterate() { 
     130bool 
     131IsoHandler::Init() { 
     132    debugOutput( DEBUG_LEVEL_VERBOSE, "%p: Init thread...\n", this); 
     133    m_poll_fd.fd = getFileDescriptor(); 
     134    m_poll_fd.revents = 0; 
     135    if (isEnabled()) { 
     136        m_poll_fd.events = POLLIN; 
     137    } else { 
     138        m_poll_fd.events = 0; 
     139    } 
     140    return true; 
     141
     142 
     143bool 
     144IsoHandler::Execute() { 
     145    int err; 
     146 
     147    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "%p: Execute thread...\n", this); 
     148    // bypass if not running 
     149    if (m_State != E_Running) { 
     150        debugOutput( DEBUG_LEVEL_VERBOSE, "%p: not polling since not running...\n", this); 
     151        usleep(m_poll_timeout * 1000); 
     152        debugOutput( DEBUG_LEVEL_VERBOSE, "%p: done sleeping...\n", this); 
     153        return true; 
     154    } 
     155 
     156    err = poll(&m_poll_fd, 1, m_poll_timeout); 
     157    if (err == -1) { 
     158        if (errno == EINTR) { 
     159            return true; 
     160        } 
     161        debugFatal("%p, poll error: %s\n", this, strerror (errno)); 
     162        return false; 
     163    } 
     164 
     165    if (m_poll_fd.revents & POLLERR) { 
     166        debugWarning("error on fd for %p\n", this); 
     167    } 
     168 
     169    if (m_poll_fd.revents & POLLHUP) { 
     170        debugWarning("hangup on fd for %p\n",this); 
     171    } 
     172 
     173    if(m_poll_fd.revents & (POLLIN)) { 
     174        iterate(); 
     175    } 
     176 
     177    return true; 
     178
     179 
     180bool 
     181IsoHandler::setThreadParameters(bool rt, int priority) { 
     182    debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) (rt=%d, prio=%d)...\n", this, rt, priority); 
     183    if (priority > 98) priority = 98; // cap the priority 
     184    m_realtime = rt; 
     185    m_priority = priority; 
     186 
     187    if (m_Thread) { 
     188        if (m_realtime) { 
     189            m_Thread->AcquireRealTime(m_priority); 
     190        } else { 
     191            m_Thread->DropRealTime(); 
     192        } 
     193    } 
     194    return true; 
     195
     196 
     197bool 
     198IsoHandler::iterate() { 
    119199    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "IsoHandler (%p) iterate...\n",this); 
    120  
    121     if(m_handle) { 
    122         if(raw1394_loop_iterate(m_handle)) { 
    123             debugOutput( DEBUG_LEVEL_VERBOSE, 
    124                  "IsoHandler (%p): Failed to iterate handler: %s\n", 
    125                  this,strerror(errno)); 
    126             return false; 
    127         } else { 
    128             return true; 
    129         } 
     200    if(raw1394_loop_iterate(m_handle)) { 
     201        debugOutput( DEBUG_LEVEL_VERBOSE, 
     202                     "IsoHandler (%p): Failed to iterate handler: %s\n", 
     203                     this,strerror(errno)); 
     204        return false; 
    130205    } else { 
    131         return false; 
     206        return true; 
    132207    } 
    133208} 
     
    166241    } 
    167242 
     243    // create a thread to iterate ourselves 
     244    debugOutput( DEBUG_LEVEL_VERBOSE, "Start thread for %p...\n", this); 
     245    m_Thread = new Util::PosixThread(this, m_realtime, m_priority,  
     246                                     PTHREAD_CANCEL_DEFERRED); 
     247    if(!m_Thread) { 
     248        debugFatal("No thread\n"); 
     249        return false; 
     250    } 
     251    if (m_Thread->Start() != 0) { 
     252        debugFatal("Could not start update thread\n"); 
     253        return false; 
     254    } 
     255 
    168256    // update the internal state 
    169257    m_State=E_Initialized; 
     
    190278{ 
    191279    debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 
     280    m_poll_fd.events = POLLIN; 
    192281    m_State = E_Running; 
    193282    return true; 
     
    204293        return false; 
    205294    } 
     295 
     296    m_poll_fd.events = 0; 
    206297 
    207298    // this is put here to try and avoid the 
     
    251342{ 
    252343    setDebugLevel(l); 
     344    if(m_Thread) m_Thread->setVerboseLevel(l); 
    253345} 
    254346 
  • trunk/libffado/src/libieee1394/IsoHandler.h

    r750 r753  
    2828#include "IsoHandlerManager.h" 
    2929 
    30 enum raw1394_iso_disposition ; 
     30#include "libutil/Thread.h" 
     31 
     32enum raw1394_iso_disposition; 
    3133 
    3234namespace Streaming { 
     
    4345*/ 
    4446 
    45 class IsoHandler 
     47class IsoHandler : public Util::RunnableInterface 
    4648{ 
    4749public: 
     
    5254    IsoHandler(IsoHandlerManager& manager); 
    5355    IsoHandler(IsoHandlerManager& manager, unsigned int buf_packets, unsigned int max_packet_size, int irq); 
    54  
    5556    virtual ~IsoHandler(); 
     57 
     58    // runnable interface 
     59    virtual bool Init(); 
     60    virtual bool Execute(); 
     61    int getFileDescriptor() { return raw1394_get_fd(m_handle);}; 
     62    bool setThreadParameters(bool rt, int priority); 
    5663 
    5764    virtual bool init(); 
     
    8289 
    8390    virtual enum EHandlerType getType() = 0; 
    84  
    85     int getFileDescriptor() { return raw1394_get_fd(m_handle);}; 
    8691 
    8792    virtual void dumpInfo(); 
     
    108113    private: 
    109114        static int busreset_handler(raw1394handle_t handle, unsigned int generation); 
     115 
     116        struct pollfd   m_poll_fd; 
     117        int             m_poll_timeout; 
     118        // threading 
     119        bool            m_realtime; 
     120        int             m_priority; 
     121        Util::Thread *  m_Thread; 
    110122 
    111123    // the state machine 
  • trunk/libffado/src/libieee1394/IsoHandlerManager.cpp

    r752 r753  
    2828 
    2929#include "libutil/Atomic.h" 
    30 #include "libutil/PosixThread.h" 
    3130 
    3231#include <assert.h> 
    3332 
    34 #define MINIMUM_INTERRUPTS_PER_PERIOD  4U 
    35 #define PACKETS_PER_INTERRUPT          4U 
     33#define MINIMUM_INTERRUPTS_PER_PERIOD  8U 
    3634 
    3735IMPL_DEBUG_MODULE( IsoHandlerManager, IsoHandlerManager, DEBUG_LEVEL_NORMAL ); 
     
    4240   : m_State(E_Created) 
    4341   , m_service( service ) 
    44    , m_poll_timeout(100), m_poll_nfds_shadow(0) 
    45    , m_realtime(false), m_priority(0), m_isoManagerThread ( NULL ) 
     42   , m_realtime(false), m_priority(0) 
    4643{} 
    4744 
     
    4946   : m_State(E_Created) 
    5047   , m_service( service ) 
    51    , m_poll_timeout(100), m_poll_nfds_shadow(0) 
    52    , m_realtime(run_rt), m_priority(rt_prio), m_isoManagerThread ( NULL ) 
     48   , m_realtime(run_rt), m_priority(rt_prio) 
    5349{} 
    5450 
     
    6359    m_realtime = rt; 
    6460    m_priority = priority; 
    65  
    66     if (m_isoManagerThread) { 
    67         if (rt) { 
    68             m_isoManagerThread->AcquireRealTime(m_priority); 
    69         } else { 
    70             m_isoManagerThread->DropRealTime(); 
    71         } 
    72     } 
    73     return true; 
     61    bool result = true; 
     62    for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); 
     63        it != m_IsoHandlers.end(); 
     64        ++it ) 
     65    { 
     66        result &= (*it)->setThreadParameters(m_realtime, m_priority); 
     67    } 
     68    return result; 
    7469} 
    7570 
     
    8378    } 
    8479 
    85     // the tread that performs the actual packet transfer 
    86     // needs high priority 
    87     if (m_priority > 98) m_priority = 98; 
    88     m_isoManagerThread = new Util::PosixThread( 
    89         this, 
    90         m_realtime, m_priority, 
    91         PTHREAD_CANCEL_DEFERRED); 
    92  
    93     if(!m_isoManagerThread) { 
    94         debugFatal("Could not create iso manager thread\n"); 
    95         return false; 
    96     } 
    97     // propagate the debug level 
    98     m_isoManagerThread->setVerboseLevel(getDebugLevel()); 
    99  
    100     debugOutput( DEBUG_LEVEL_VERBOSE, "Starting ISO iterator thread...\n"); 
    101     // note: libraw1394 doesn't like it if you poll() and/or iterate() before 
    102     //       starting the streams. this is prevented by the isEnabled() on a handler 
    103     // start the iso runner thread 
    104     if (m_isoManagerThread->Start() == 0) { 
    105         m_State=E_Running; 
    106         requestShadowUpdate(); 
    107     } else { 
    108         m_State=E_Error; 
    109     } 
     80    m_State=E_Running; 
    11081    return true; 
    11182} 
    11283 
    113 bool IsoHandlerManager::Init() 
    114 
    115     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 
    116     return true; 
    117 
    118  
    119 /** 
    120  * the IsoHandlerManager thread execute function iterates the handlers. 
    121  * 
    122  * This means that once the thread is running, streams are 
    123  * transmitted and received (if present on the bus). Make sure 
    124  * that the clients are registered & ready before starting the 
    125  * thread! 
    126  * 
    127  * The register and unregister functions are thread unsafe, so 
    128  * should not be used when the thread is running. 
    129  * 
    130  * @return false if the handlers could not be iterated. 
    131  */ 
    132 bool IsoHandlerManager::Execute() 
    133 
    134     if(!iterate()) { 
    135         debugFatal("Could not iterate the isoManager\n"); 
    136         return false; 
    137     } 
    138     return true; 
    139 
    140  
    141 /** 
    142  * Update the shadow variables. Should only be called from 
    143  * the iso handler iteration thread 
    144  */ 
    145 void 
    146 IsoHandlerManager::updateShadowVars() 
    147 
    148     debugOutput( DEBUG_LEVEL_VERBOSE, "updating shadow vars...\n"); 
    149     unsigned int i; 
    150     m_poll_nfds_shadow = m_IsoHandlers.size(); 
    151     if(m_poll_nfds_shadow > FFADO_MAX_ISO_HANDLERS_PER_PORT) { 
    152         debugWarning("Too much ISO Handlers in manager...\n"); 
    153         m_poll_nfds_shadow = FFADO_MAX_ISO_HANDLERS_PER_PORT; 
    154     } 
    155     for (i = 0; i < m_poll_nfds_shadow; i++) { 
    156         IsoHandler *h = m_IsoHandlers.at(i); 
    157         assert(h); 
    158         m_IsoHandler_map_shadow[i] = h; 
    159  
    160         m_poll_fds_shadow[i].fd = h->getFileDescriptor(); 
    161         m_poll_fds_shadow[i].revents = 0; 
    162         if (h->isEnabled()) { 
    163             m_poll_fds_shadow[i].events = POLLIN; 
    164         } else { 
    165             m_poll_fds_shadow[i].events = 0; 
    166         } 
    167     } 
    168     debugOutput( DEBUG_LEVEL_VERBOSE, " updated shadow vars...\n"); 
    169 
    170  
    171 /** 
    172  * Poll the handlers managed by this manager, and iterate them 
    173  * when ready 
    174  * 
    175  * @return true when successful 
    176  */ 
    177 bool IsoHandlerManager::iterate() 
    178 
    179     int err; 
    180     unsigned int i; 
    181  
    182     // update the shadow variables if requested 
    183     if(m_request_fdmap_update) { 
    184         updateShadowVars(); 
    185         ZERO_ATOMIC((SInt32*)&m_request_fdmap_update); 
    186     } 
    187  
    188     // bypass if no handlers are registered 
    189     if (m_poll_nfds_shadow == 0) { 
    190         usleep(m_poll_timeout * 1000); 
    191         return true; 
    192     } 
    193  
    194     // Use a shadow map of the fd's such that the poll call is not in a critical section 
    195  
    196     err = poll (m_poll_fds_shadow, m_poll_nfds_shadow, m_poll_timeout); 
    197  
    198     if (err == -1) { 
    199         if (errno == EINTR) { 
    200             return true; 
    201         } 
    202         debugFatal("poll error: %s\n", strerror (errno)); 
    203         return false; 
    204     } 
    205  
    206 //     #ifdef DEBUG 
    207 //     for (i = 0; i < m_poll_nfds_shadow; i++) { 
    208 //         IsoHandler *s = m_IsoHandler_map_shadow[i]; 
    209 //         assert(s); 
    210 //         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "post poll: (%d) handler %p: enabled? %d, events: %08X, revents: %08X\n",  
    211 //             i, s, s->isEnabled(), m_poll_fds_shadow[i].events, m_poll_fds_shadow[i].revents); 
    212 //     } 
    213 //     #endif 
    214  
    215     for (i = 0; i < m_poll_nfds_shadow; i++) { 
    216         if (m_poll_fds_shadow[i].revents & POLLERR) { 
    217             debugWarning("error on fd for %d\n",i); 
    218         } 
    219  
    220         if (m_poll_fds_shadow[i].revents & POLLHUP) { 
    221             debugWarning("hangup on fd for %d\n",i); 
    222         } 
    223  
    224         if(m_poll_fds_shadow[i].revents & (POLLIN)) { 
    225             m_IsoHandler_map_shadow[i]->iterate(); 
    226         } 
    227     } 
    228     return true; 
     84bool 
     85IsoHandlerManager::disable(IsoHandler *h) { 
     86    bool result; 
     87    int i=0; 
     88    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Disable on IsoHandler %p\n", h); 
     89    for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); 
     90        it != m_IsoHandlers.end(); 
     91        ++it ) 
     92    { 
     93        if ((*it) == h) { 
     94            result = h->disable(); 
     95            debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " disabled\n"); 
     96            return result; 
     97        } 
     98        i++; 
     99    } 
     100    debugError("Handler not found\n"); 
     101    return false; 
     102
     103 
     104bool 
     105IsoHandlerManager::enable(IsoHandler *h) { 
     106    bool result; 
     107    int i=0; 
     108    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Enable on IsoHandler %p\n", h); 
     109    for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); 
     110        it != m_IsoHandlers.end(); 
     111        ++it ) 
     112    { 
     113        if ((*it) == h) { 
     114            result = h->enable(); 
     115            debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " enabled\n"); 
     116            return result; 
     117        } 
     118        i++; 
     119    } 
     120    debugError("Handler not found\n"); 
     121    return false; 
    229122} 
    230123 
     
    234127    assert(handler); 
    235128    handler->setVerboseLevel(getDebugLevel()); 
    236  
    237129    m_IsoHandlers.push_back(handler); 
    238     requestShadowUpdate(); 
    239  
    240     // rebuild the fd map for poll()'ing. 
    241130    return true; 
    242131} 
     
    253142        if ( *it == handler ) { 
    254143            m_IsoHandlers.erase(it); 
    255             requestShadowUpdate(); 
    256144            return true; 
    257145        } 
     
    259147    debugFatal("Could not find handler (%p)\n", handler); 
    260148    return false; //not found 
    261 } 
    262  
    263 void 
    264 IsoHandlerManager::requestShadowUpdate() { 
    265     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 
    266  
    267     if (m_isoManagerThread == NULL) { 
    268         debugOutput( DEBUG_LEVEL_VERBOSE, "No thread running, so no shadow variables needed.\n"); 
    269         return; 
    270     } 
    271  
    272     // the m_request_fdmap_update variable is zeroed by the 
    273     // handler thread when it has accepted the new FD map 
    274     // and copied it over to it's shadow variables. 
    275     while(m_request_fdmap_update && m_isoManagerThread) { 
    276         usleep(1000); 
    277     } 
    278  
    279     debugOutput(DEBUG_LEVEL_VERBOSE, " requesting update of shadow variables...\n"); 
    280     // request that the handler thread updates it's FD shadow 
    281     INC_ATOMIC((SInt32*)&m_request_fdmap_update); 
    282  
    283     debugOutput(DEBUG_LEVEL_VERBOSE, " waiting for update of shadow variables to complete...\n"); 
    284     // the m_request_fdmap_update variable is zeroed by the 
    285     // handler thread when it has accepted the new FD map 
    286     // and copied it over to it's shadow variables. 
    287     while(m_request_fdmap_update && m_isoManagerThread) { 
    288         usleep(1000); 
    289     } 
    290     debugOutput(DEBUG_LEVEL_VERBOSE, " shadow variables updated...\n"); 
    291 } 
    292  
    293 bool 
    294 IsoHandlerManager::disable(IsoHandler *h) { 
    295     bool result; 
    296     int i=0; 
    297     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Disable on IsoHandler %p\n", h); 
    298     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); 
    299         it != m_IsoHandlers.end(); 
    300         ++it ) 
    301     { 
    302         if ((*it) == h) { 
    303             result = h->disable(); 
    304             requestShadowUpdate(); 
    305             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " disabled\n"); 
    306             return result; 
    307         } 
    308         i++; 
    309     } 
    310     debugError("Handler not found\n"); 
    311     return false; 
    312 } 
    313  
    314 bool 
    315 IsoHandlerManager::enable(IsoHandler *h) { 
    316     bool result; 
    317     int i=0; 
    318     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Enable on IsoHandler %p\n", h); 
    319     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); 
    320         it != m_IsoHandlers.end(); 
    321         ++it ) 
    322     { 
    323         if ((*it) == h) { 
    324             result = h->enable(); 
    325             requestShadowUpdate(); 
    326             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " enabled\n"); 
    327             return result; 
    328         } 
    329         i++; 
    330     } 
    331     debugError("Handler not found\n"); 
    332     return false; 
    333149} 
    334150 
     
    352168    assert(stream); 
    353169 
     170    IsoHandler* h = NULL; 
     171 
    354172    // make sure the stream isn't already attached to a handler 
    355173    for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); 
     
    434252        //irq_interval=2; // HACK 
    435253        // create the actual handler 
    436         IsoRecvHandler *h = new IsoRecvHandler(*this, buffers, 
     254        h = new IsoRecvHandler(*this, buffers, 
    437255                                               max_packet_size, irq_interval); 
    438  
    439         debugOutput( DEBUG_LEVEL_VERBOSE, " registering IsoRecvHandler\n"); 
    440  
    441256        if(!h) { 
    442257            debugFatal("Could not create IsoRecvHandler\n"); 
    443258            return false; 
    444259        } 
    445  
    446         h->setVerboseLevel(getDebugLevel()); 
    447  
    448         // init the handler 
    449         if(!h->init()) { 
    450             debugFatal("Could not initialize receive handler\n"); 
    451             return false; 
    452         } 
    453  
    454         // register the stream with the handler 
    455         if(!h->registerStream(stream)) { 
    456             debugFatal("Could not register receive stream with handler\n"); 
    457             return false; 
    458         } 
    459  
    460         // register the handler with the manager 
    461         if(!registerHandler(h)) { 
    462             debugFatal("Could not register receive handler with manager\n"); 
    463             return false; 
    464         } 
    465         debugOutput( DEBUG_LEVEL_VERBOSE, " registered stream (%p) with handler (%p)\n",stream,h); 
    466     } 
    467  
    468     if (stream->getType()==StreamProcessor::ePT_Transmit) { 
     260        debugOutput( DEBUG_LEVEL_VERBOSE, " registering IsoRecvHandler\n"); 
     261 
     262    } else if (stream->getType()==StreamProcessor::ePT_Transmit) { 
    469263        // setup the optimal parameters for the raw1394 ISO buffering 
    470264        unsigned int packets_per_period = stream->getPacketsPerPeriod(); 
     
    505299 
    506300        // create the actual handler 
    507         IsoXmitHandler *h = new IsoXmitHandler(*this, buffers, 
     301        h = new IsoXmitHandler(*this, buffers, 
    508302                                               max_packet_size, irq_interval); 
    509303 
     
    514308            return false; 
    515309        } 
    516  
    517         h->setVerboseLevel(getDebugLevel()); 
    518  
    519         // init the handler 
    520         if(!h->init()) { 
    521             debugFatal("Could not initialize transmit handler\n"); 
    522             return false; 
    523         } 
    524  
    525         // register the stream with the handler 
    526         if(!h->registerStream(stream)) { 
    527             debugFatal("Could not register transmit stream with handler\n"); 
    528             return false; 
    529         } 
    530  
    531         // register the handler with the manager 
    532         if(!registerHandler(h)) { 
    533             debugFatal("Could not register transmit handler with manager\n"); 
    534             return false; 
    535         } 
    536         debugOutput( DEBUG_LEVEL_VERBOSE, " registered stream (%p) with handler (%p)\n",stream,h); 
    537     } 
     310    } else { 
     311        debugFatal("Bad stream type\n"); 
     312        return false; 
     313    } 
     314 
     315    h->setVerboseLevel(getDebugLevel()); 
     316 
     317    // init the handler 
     318    if(!h->init()) { 
     319        debugFatal("Could not initialize receive handler\n"); 
     320        return false; 
     321    } 
     322 
     323    // set the handler's thread parameters 
     324    if(!h->setThreadParameters(m_realtime, m_priority)) { 
     325        debugFatal("Could not set handler thread parameters\n"); 
     326        return false; 
     327    } 
     328 
     329    // register the stream with the handler 
     330    if(!h->registerStream(stream)) { 
     331        debugFatal("Could not register receive stream with handler\n"); 
     332        return false; 
     333    } 
     334 
     335    // register the handler with the manager 
     336    if(!registerHandler(h)) { 
     337        debugFatal("Could not register receive handler with manager\n"); 
     338        return false; 
     339    } 
     340    debugOutput( DEBUG_LEVEL_VERBOSE, " registered stream (%p) with handler (%p)\n", stream, h); 
     341 
    538342    m_StreamProcessors.push_back(stream); 
    539343    debugOutput( DEBUG_LEVEL_VERBOSE, " %d streams, %d handlers registered\n", 
     
    632436            debugOutput( DEBUG_LEVEL_VERBOSE, " stopping handler %p for stream %p\n", *it, stream); 
    633437            result = (*it)->disable(); 
    634             //requestShadowUpdate(); 
    635438            if(!result) { 
    636439                debugOutput( DEBUG_LEVEL_VERBOSE, " could not disable handler (%p)\n",*it); 
     
    692495            debugOutput( DEBUG_LEVEL_VERBOSE, " starting handler %p for stream %p\n", *it, stream); 
    693496            result = (*it)->enable(cycle); 
    694             requestShadowUpdate(); 
    695497            if(!result) { 
    696498                debugOutput( DEBUG_LEVEL_VERBOSE, " could not enable handler (%p)\n",*it); 
     
    714516 
    715517    bool retval=true; 
    716     debugOutput( DEBUG_LEVEL_VERBOSE, "Stopping ISO iterator thread...\n"); 
    717  
    718     m_isoManagerThread->Stop(); 
    719     m_isoManagerThread = NULL; 
    720     ZERO_ATOMIC((SInt32*)&m_request_fdmap_update); 
    721518 
    722519    for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); 
     
    730527        } 
    731528    } 
    732     requestShadowUpdate(); 
    733529 
    734530    if (retval) { 
     
    754550    setDebugLevel(i); 
    755551    // propagate the debug level 
    756     if(m_isoManagerThread) { 
    757         m_isoManagerThread->setVerboseLevel(getDebugLevel()); 
    758     } 
    759552    for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); 
    760553          it != m_IsoHandlers.end(); 
  • trunk/libffado/src/libieee1394/IsoHandlerManager.h

    r752 r753  
    2727#include "debugmodule/debugmodule.h" 
    2828 
    29 #include "libutil/Thread.h" 
    30  
    3129#include <sys/poll.h> 
    3230#include <errno.h> 
     
    4038#define MAX_UPDATE_TRIES 10 
    4139class Ieee1394Service; 
    42 namespace Util { 
    43     class PosixThread; 
    44 } 
    4540 
    4641class IsoHandler; 
     
    6661 
    6762*/ 
    68 class IsoHandlerManager : public Util::RunnableInterface 
     63class IsoHandlerManager 
    6964{ 
    7065    friend class Streaming::StreamProcessorManager; 
     
    7772 
    7873        bool setThreadParameters(bool rt, int priority); 
    79  
    80         void setPollTimeout(int t) {m_poll_timeout=t;}; ///< set the timeout used for poll() 
    81         int getPollTimeout() {return m_poll_timeout;};  ///< get the timeout used for poll() 
    8274 
    8375        void setVerboseLevel(int l); ///< set the verbose level 
     
    115107 
    116108        Ieee1394Service& get1394Service() {return m_service;}; 
    117     // RunnableInterface interface 
    118     public: 
    119         bool Execute(); // note that this is called in we while(running) loop 
    120         bool Init(); 
    121          
    122         // protects the operations on the lists  
    123         // (FIXME: should be changed into a lock-free approach) 
    124         pthread_mutex_t m_list_lock; 
    125109 
    126110    // the state machine 
     
    135119        enum eHandlerStates m_State; 
    136120        const char *eHSToString(enum eHandlerStates); 
    137     private: 
    138         /// iterate all child handlers 
    139         bool iterate(); 
    140121 
    141122    private: 
     
    159140        Streaming::StreamProcessorVector m_StreamProcessors; 
    160141 
    161         // poll stuff 
    162         int m_poll_timeout; 
    163         // FD map sync requested 
    164         int32_t m_request_fdmap_update; 
    165         void updateShadowVars(); 
    166  
    167         // shadow variables 
    168         struct pollfd m_poll_fds_shadow[FFADO_MAX_ISO_HANDLERS_PER_PORT]; 
    169         IsoHandler *m_IsoHandler_map_shadow[FFADO_MAX_ISO_HANDLERS_PER_PORT]; 
    170         unsigned int m_poll_nfds_shadow; 
    171  
    172         void requestShadowUpdate(); 
    173  
    174         // threading 
     142        // thread params for the handler threads 
    175143        bool m_realtime; 
    176144        int m_priority; 
    177         Util::PosixThread *m_isoManagerThread; 
    178145 
    179146        // debug stuff 
  • trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp

    r750 r753  
    162162        else 
    163163        { 
    164             debugOutput ( DEBUG_LEVEL_VERY_VERBOSE, 
     164            debugOutput ( DEBUG_LEVEL_VERBOSE, 
    165165                        "Insufficient frames (NP): N=%02d, CY=%04u, TC=%04u, CUT=%04d\n", 
    166166                        fc, cycle, transmit_at_cycle, cycles_until_transmit ); 
    167167            // there is still time left to send the packet 
    168168            // we want the system to give this packet another go at a later time instant 
    169             return eCRV_Again; 
     169            return eCRV_Again; // note that the raw1394 again system doesn't work as expected 
     170 
     171            // we could wait here for a certain time before trying again. However, this 
     172            // is not going to work since we then block the iterator thread, hence also  
     173            // the receiving code, meaning that we are not processing received packets, 
     174            // and hence there is no progression in the number of frames available. 
     175 
     176            // for example: 
     177            // usleep(125); // one cycle 
     178            // goto try_block_of_frames; 
     179 
     180            // or more advanced, calculate how many cycles we are ahead of 'now' and 
     181            // base the sleep on that. 
     182 
     183            // note that this requires that there is one thread for each IsoHandler, 
     184            // otherwise we're in the deadlock described above. 
    170185        } 
    171186    } 
     
    205220                // we are not that late and can still try to transmit the packet 
    206221                m_dbc += fillDataPacketHeader(packet, length, m_last_timestamp); 
    207                 return eCRV_Packet
     222                return (fc < (signed)(2*m_syt_interval) ? eCRV_Defer : eCRV_Packet)
    208223            } 
    209224            else   // definitely too late 
     
    216231            // it's time send the packet 
    217232            m_dbc += fillDataPacketHeader(packet, length, m_last_timestamp); 
    218             return eCRV_Packet
     233            return (fc < (signed)(2*m_syt_interval) ? eCRV_Defer : eCRV_Packet)
    219234        } 
    220235        else 
  • trunk/libffado/src/libstreaming/generic/StreamProcessor.cpp

    r750 r753  
    236236        if (dropped_cycles < 0) debugWarning("(%p) dropped < 1 (%d)\n", this, dropped_cycles); 
    237237        if (dropped_cycles > 0) { 
    238             debugWarning("(%p) dropped %d packets on cycle %u\n", this, dropped_cycles, cycle); 
     238            debugWarning("(%p) dropped %d packets on cycle %u, 'dropped'=%u, cycle=%d, m_last_cycle=%d\n", 
     239                this, dropped_cycles, cycle, dropped, cycle, m_last_cycle); 
    239240            m_dropped += dropped_cycles; 
    240241        } 
     
    444445 
    445446    #ifdef DEBUG 
    446     if(cycle_diff < 0) { 
     447    if(cycle_diff < 0 && (m_state == ePS_Running || m_state == ePS_DryRunning)) { 
    447448        debugWarning("Requesting packet for cycle %04d which is in the past (now=%04dcy)\n", 
    448449            cycle, now_cycles); 
     
    541542                goto send_empty_packet; 
    542543            } 
    543             return RAW1394_ISO_OK; 
     544            // skip queueing packets if we detect that there are not enough frames 
     545            // available 
     546            if(result2 == eCRV_Defer) 
     547                return RAW1394_ISO_DEFER; 
     548            else 
     549                return RAW1394_ISO_OK; 
    544550        } else if (result == eCRV_XRun) { // pick up the possible xruns 
    545551            debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to header xrun\n"); 
     
    563569            } 
    564570            goto send_empty_packet; 
    565 //         } else if (result == eCRV_Again) { 
    566 //             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "have to retry cycle %d\n", cycle); 
    567 //             if(m_state != m_next_state) { 
    568 //                 debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state from %s to %s\n", 
    569 //                                                 ePSToString(m_state), ePSToString(m_next_state)); 
    570 //                 // execute the requested change 
    571 //                 if (!updateState()) { // we are allowed to change the state directly 
    572 //                     debugError("Could not update state!\n"); 
    573 //                     return RAW1394_ISO_ERROR; 
    574 //                 } 
    575 //             } 
    576             // force some delay 
    577 //             usleep(125); 
    578 //             return RAW1394_ISO_AGAIN; 
     571        } else if (result == eCRV_Again) { 
     572            debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "have to retry cycle %d\n", cycle); 
     573            if(m_state != m_next_state) { 
     574                debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state from %s to %s\n", 
     575                                                ePSToString(m_state), ePSToString(m_next_state)); 
     576                // execute the requested change 
     577                if (!updateState()) { // we are allowed to change the state directly 
     578                    debugError("Could not update state!\n"); 
     579                    return RAW1394_ISO_ERROR; 
     580                } 
     581            } 
     582            //force some delay 
     583            usleep(125); 
     584            return RAW1394_ISO_AGAIN; 
    579585        } else { 
    580586            debugError("Invalid return value: %d\n", result); 
  • trunk/libffado/src/libstreaming/generic/StreamProcessor.h

    r750 r753  
    202202        eCRV_XRun, 
    203203        eCRV_Again, 
     204        eCRV_Defer, 
    204205    }; 
    205206    // to be implemented by the children 
  • trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.cpp

    r750 r753  
    309309 
    310310        // Set up each frames's SPH. 
    311         for (unsigned int i=0; i<n_events; i++, quadlet += dbs) { 
     311        for (unsigned int i=0; i < n_events; i++, quadlet += dbs) { 
    312312//FIXME: not sure which is best for the MOTU 
    313313//            int64_t ts_frame = addTicks(ts, (unsigned int)(i * ticks_per_frame)); 
  • trunk/libffado/src/libstreaming/StreamProcessorManager.cpp

    r750 r753  
    4040// time to a later time instant also causes the xmit buffer fill to be 
    4141// lower on average. 
    42 #define FFADO_SIGNAL_DELAY_TICKS 3072*4 
     42#define FFADO_SIGNAL_DELAY_TICKS (3072*1) 
    4343 
    4444namespace Streaming { 
  • trunk/libffado/src/libutil/TimestampedBuffer.cpp

    r748 r753  
    10121012    ENTER_CRITICAL_SECTION; 
    10131013 
    1014     diff=m_buffer_next_tail_timestamp - m_buffer_tail_timestamp; 
    1015     timestamp=m_buffer_tail_timestamp; 
     1014    diff = m_buffer_next_tail_timestamp - m_buffer_tail_timestamp; 
     1015    timestamp = m_buffer_tail_timestamp; 
    10161016     
    10171017    EXIT_CRITICAL_SECTION; 
    10181018     
    10191019    if (diff < 0) diff += m_wrap_at; 
    1020     rate=(float)diff / (float)m_update_period; 
    1021  
    1022     timestamp-=(ffado_timestamp_t)((nframes) * rate); 
     1020    rate = (float)diff / (float)m_update_period; 
     1021 
     1022    timestamp -= (ffado_timestamp_t)((nframes) * rate); 
    10231023 
    10241024    if(timestamp >= m_wrap_at) {