Index: /trunk/libffado/src/libieee1394/CycleTimerHelper.cpp =================================================================== --- /trunk/libffado/src/libieee1394/CycleTimerHelper.cpp (revision 752) +++ /trunk/libffado/src/libieee1394/CycleTimerHelper.cpp (revision 753) @@ -86,7 +86,4 @@ PTHREAD_CANCEL_DEFERRED); if(!m_Thread) { - debugFatal("Could not create update thread\n"); - } - if(!m_Thread) { debugFatal("No thread\n"); return false; @@ -142,5 +139,5 @@ CycleTimerHelper::Execute() { - debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Execute %p...\n", this); + debugOutput( DEBUG_LEVEL_ULTRA_VERBOSE, "Execute %p...\n", this); uint32_t cycle_timer; uint64_t local_time; @@ -149,5 +146,5 @@ return false; } - debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " read : CTR: %11lu, local: %17llu\n", + debugOutput( DEBUG_LEVEL_ULTRA_VERBOSE, " read : CTR: %11lu, local: %17llu\n", cycle_timer, local_time); @@ -169,5 +166,5 @@ double diff = m_next_time_usecs - m_current_time_usecs; - debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " usecs: local: %11llu current: %f next: %f, diff: %f\n", + debugOutput( DEBUG_LEVEL_ULTRA_VERBOSE, " usecs: local: %11llu current: %f next: %f, diff: %f\n", local_time, m_current_time_usecs, m_next_time_usecs, diff); @@ -178,5 +175,5 @@ m_current_time_usecs = m_next_time_usecs; m_next_time_usecs = (local_time - usecs_late) + m_usecs_per_update; - debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " usecs: current: %f next: %f usecs_late=%f\n", + debugOutput( DEBUG_LEVEL_ULTRA_VERBOSE, " usecs: current: %f next: %f usecs_late=%f\n", m_current_time_usecs, m_next_time_usecs, usecs_late); @@ -187,8 +184,8 @@ (uint64_t)((DLL_COEFF_B * diff_ticks) + m_dll_e2)); m_dll_e2 += DLL_COEFF_C * diff_ticks; - debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " ticks: current: %f next: %f diff=%f\n", + debugOutput( DEBUG_LEVEL_ULTRA_VERBOSE, " ticks: current: %f next: %f diff=%f\n", m_current_time_ticks, m_next_time_ticks, diff_ticks); - debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " state: local: %11llu, dll_e2: %f, rate: %f\n", + debugOutput( DEBUG_LEVEL_ULTRA_VERBOSE, " state: local: %11llu, dll_e2: %f, rate: %f\n", local_time, m_dll_e2, getRate()); } @@ -209,5 +206,5 @@ //int64_t time_to_sleep = m_usecs_per_update; if (time_to_sleep > 0) { - debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " sleeping %lld usecs (avg delay: %f)\n", time_to_sleep, m_avg_wakeup_delay); + debugOutput( DEBUG_LEVEL_ULTRA_VERBOSE, " sleeping %lld usecs (avg delay: %f)\n", time_to_sleep, m_avg_wakeup_delay); usleep(time_to_sleep); } @@ -241,5 +238,7 @@ retval = addTicks(offset_in_ticks_int, y_step_in_ticks_int); } else { - debugWarning("y_step_in_ticks_int <= 0: %lld\n", y_step_in_ticks_int); + // this can happen if the update thread was woken up earlier than it should have been + debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "y_step_in_ticks_int <= 0: %lld, time_diff: %f, rate: %f\n", + y_step_in_ticks_int, time_diff, my_vars.rate); retval = substractTicks(offset_in_ticks_int, -y_step_in_ticks_int); } Index: /trunk/libffado/src/libieee1394/ieee1394service.cpp =================================================================== --- /trunk/libffado/src/libieee1394/ieee1394service.cpp (revision 752) +++ /trunk/libffado/src/libieee1394/ieee1394service.cpp (revision 753) @@ -45,6 +45,6 @@ #define FFADO_MAX_FIREWIRE_PORTS 16 -#define ISOMANAGER_PRIO_INCREASE 5 -#define CYCLETIMER_HELPER_PRIO_INCREASE 6 +#define ISOMANAGER_PRIO_INCREASE 10 +#define CYCLETIMER_HELPER_PRIO_INCREASE 10 IMPL_DEBUG_MODULE( Ieee1394Service, Ieee1394Service, DEBUG_LEVEL_NORMAL ); Index: /trunk/libffado/src/libieee1394/IsoHandlerManager.cpp =================================================================== --- /trunk/libffado/src/libieee1394/IsoHandlerManager.cpp (revision 752) +++ /trunk/libffado/src/libieee1394/IsoHandlerManager.cpp (revision 753) @@ -28,10 +28,8 @@ #include "libutil/Atomic.h" -#include "libutil/PosixThread.h" #include -#define MINIMUM_INTERRUPTS_PER_PERIOD 4U -#define PACKETS_PER_INTERRUPT 4U +#define MINIMUM_INTERRUPTS_PER_PERIOD 8U IMPL_DEBUG_MODULE( IsoHandlerManager, IsoHandlerManager, DEBUG_LEVEL_NORMAL ); @@ -42,6 +40,5 @@ : m_State(E_Created) , m_service( service ) - , m_poll_timeout(100), m_poll_nfds_shadow(0) - , m_realtime(false), m_priority(0), m_isoManagerThread ( NULL ) + , m_realtime(false), m_priority(0) {} @@ -49,6 +46,5 @@ : m_State(E_Created) , m_service( service ) - , m_poll_timeout(100), m_poll_nfds_shadow(0) - , m_realtime(run_rt), m_priority(rt_prio), m_isoManagerThread ( NULL ) + , m_realtime(run_rt), m_priority(rt_prio) {} @@ -63,13 +59,12 @@ m_realtime = rt; m_priority = priority; - - if (m_isoManagerThread) { - if (rt) { - m_isoManagerThread->AcquireRealTime(m_priority); - } else { - m_isoManagerThread->DropRealTime(); - } - } - return true; + bool result = true; + for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); + it != m_IsoHandlers.end(); + ++it ) + { + result &= (*it)->setThreadParameters(m_realtime, m_priority); + } + return result; } @@ -83,148 +78,46 @@ } - // the tread that performs the actual packet transfer - // needs high priority - if (m_priority > 98) m_priority = 98; - m_isoManagerThread = new Util::PosixThread( - this, - m_realtime, m_priority, - PTHREAD_CANCEL_DEFERRED); - - if(!m_isoManagerThread) { - debugFatal("Could not create iso manager thread\n"); - return false; - } - // propagate the debug level - m_isoManagerThread->setVerboseLevel(getDebugLevel()); - - debugOutput( DEBUG_LEVEL_VERBOSE, "Starting ISO iterator thread...\n"); - // note: libraw1394 doesn't like it if you poll() and/or iterate() before - // starting the streams. this is prevented by the isEnabled() on a handler - // start the iso runner thread - if (m_isoManagerThread->Start() == 0) { - m_State=E_Running; - requestShadowUpdate(); - } else { - m_State=E_Error; - } + m_State=E_Running; return true; } -bool IsoHandlerManager::Init() -{ - debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); - return true; -} - -/** - * the IsoHandlerManager thread execute function iterates the handlers. - * - * This means that once the thread is running, streams are - * transmitted and received (if present on the bus). Make sure - * that the clients are registered & ready before starting the - * thread! - * - * The register and unregister functions are thread unsafe, so - * should not be used when the thread is running. - * - * @return false if the handlers could not be iterated. - */ -bool IsoHandlerManager::Execute() -{ - if(!iterate()) { - debugFatal("Could not iterate the isoManager\n"); - return false; - } - return true; -} - -/** - * Update the shadow variables. Should only be called from - * the iso handler iteration thread - */ -void -IsoHandlerManager::updateShadowVars() -{ - debugOutput( DEBUG_LEVEL_VERBOSE, "updating shadow vars...\n"); - unsigned int i; - m_poll_nfds_shadow = m_IsoHandlers.size(); - if(m_poll_nfds_shadow > FFADO_MAX_ISO_HANDLERS_PER_PORT) { - debugWarning("Too much ISO Handlers in manager...\n"); - m_poll_nfds_shadow = FFADO_MAX_ISO_HANDLERS_PER_PORT; - } - for (i = 0; i < m_poll_nfds_shadow; i++) { - IsoHandler *h = m_IsoHandlers.at(i); - assert(h); - m_IsoHandler_map_shadow[i] = h; - - m_poll_fds_shadow[i].fd = h->getFileDescriptor(); - m_poll_fds_shadow[i].revents = 0; - if (h->isEnabled()) { - m_poll_fds_shadow[i].events = POLLIN; - } else { - m_poll_fds_shadow[i].events = 0; - } - } - debugOutput( DEBUG_LEVEL_VERBOSE, " updated shadow vars...\n"); -} - -/** - * Poll the handlers managed by this manager, and iterate them - * when ready - * - * @return true when successful - */ -bool IsoHandlerManager::iterate() -{ - int err; - unsigned int i; - - // update the shadow variables if requested - if(m_request_fdmap_update) { - updateShadowVars(); - ZERO_ATOMIC((SInt32*)&m_request_fdmap_update); - } - - // bypass if no handlers are registered - if (m_poll_nfds_shadow == 0) { - usleep(m_poll_timeout * 1000); - return true; - } - - // Use a shadow map of the fd's such that the poll call is not in a critical section - - err = poll (m_poll_fds_shadow, m_poll_nfds_shadow, m_poll_timeout); - - if (err == -1) { - if (errno == EINTR) { - return true; - } - debugFatal("poll error: %s\n", strerror (errno)); - return false; - } - -// #ifdef DEBUG -// for (i = 0; i < m_poll_nfds_shadow; i++) { -// IsoHandler *s = m_IsoHandler_map_shadow[i]; -// assert(s); -// debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "post poll: (%d) handler %p: enabled? %d, events: %08X, revents: %08X\n", -// i, s, s->isEnabled(), m_poll_fds_shadow[i].events, m_poll_fds_shadow[i].revents); -// } -// #endif - - for (i = 0; i < m_poll_nfds_shadow; i++) { - if (m_poll_fds_shadow[i].revents & POLLERR) { - debugWarning("error on fd for %d\n",i); - } - - if (m_poll_fds_shadow[i].revents & POLLHUP) { - debugWarning("hangup on fd for %d\n",i); - } - - if(m_poll_fds_shadow[i].revents & (POLLIN)) { - m_IsoHandler_map_shadow[i]->iterate(); - } - } - return true; +bool +IsoHandlerManager::disable(IsoHandler *h) { + bool result; + int i=0; + debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Disable on IsoHandler %p\n", h); + for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); + it != m_IsoHandlers.end(); + ++it ) + { + if ((*it) == h) { + result = h->disable(); + debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " disabled\n"); + return result; + } + i++; + } + debugError("Handler not found\n"); + return false; +} + +bool +IsoHandlerManager::enable(IsoHandler *h) { + bool result; + int i=0; + debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Enable on IsoHandler %p\n", h); + for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); + it != m_IsoHandlers.end(); + ++it ) + { + if ((*it) == h) { + result = h->enable(); + debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " enabled\n"); + return result; + } + i++; + } + debugError("Handler not found\n"); + return false; } @@ -234,9 +127,5 @@ assert(handler); handler->setVerboseLevel(getDebugLevel()); - m_IsoHandlers.push_back(handler); - requestShadowUpdate(); - - // rebuild the fd map for poll()'ing. return true; } @@ -253,5 +142,4 @@ if ( *it == handler ) { m_IsoHandlers.erase(it); - requestShadowUpdate(); return true; } @@ -259,76 +147,4 @@ debugFatal("Could not find handler (%p)\n", handler); return false; //not found -} - -void -IsoHandlerManager::requestShadowUpdate() { - debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); - - if (m_isoManagerThread == NULL) { - debugOutput( DEBUG_LEVEL_VERBOSE, "No thread running, so no shadow variables needed.\n"); - return; - } - - // the m_request_fdmap_update variable is zeroed by the - // handler thread when it has accepted the new FD map - // and copied it over to it's shadow variables. - while(m_request_fdmap_update && m_isoManagerThread) { - usleep(1000); - } - - debugOutput(DEBUG_LEVEL_VERBOSE, " requesting update of shadow variables...\n"); - // request that the handler thread updates it's FD shadow - INC_ATOMIC((SInt32*)&m_request_fdmap_update); - - debugOutput(DEBUG_LEVEL_VERBOSE, " waiting for update of shadow variables to complete...\n"); - // the m_request_fdmap_update variable is zeroed by the - // handler thread when it has accepted the new FD map - // and copied it over to it's shadow variables. - while(m_request_fdmap_update && m_isoManagerThread) { - usleep(1000); - } - debugOutput(DEBUG_LEVEL_VERBOSE, " shadow variables updated...\n"); -} - -bool -IsoHandlerManager::disable(IsoHandler *h) { - bool result; - int i=0; - debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Disable on IsoHandler %p\n", h); - for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); - it != m_IsoHandlers.end(); - ++it ) - { - if ((*it) == h) { - result = h->disable(); - requestShadowUpdate(); - debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " disabled\n"); - return result; - } - i++; - } - debugError("Handler not found\n"); - return false; -} - -bool -IsoHandlerManager::enable(IsoHandler *h) { - bool result; - int i=0; - debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Enable on IsoHandler %p\n", h); - for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); - it != m_IsoHandlers.end(); - ++it ) - { - if ((*it) == h) { - result = h->enable(); - requestShadowUpdate(); - debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " enabled\n"); - return result; - } - i++; - } - debugError("Handler not found\n"); - return false; } @@ -352,4 +168,6 @@ assert(stream); + IsoHandler* h = NULL; + // make sure the stream isn't already attached to a handler for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); @@ -434,37 +252,13 @@ //irq_interval=2; // HACK // create the actual handler - IsoRecvHandler *h = new IsoRecvHandler(*this, buffers, + h = new IsoRecvHandler(*this, buffers, max_packet_size, irq_interval); - - debugOutput( DEBUG_LEVEL_VERBOSE, " registering IsoRecvHandler\n"); - if(!h) { debugFatal("Could not create IsoRecvHandler\n"); return false; } - - h->setVerboseLevel(getDebugLevel()); - - // init the handler - if(!h->init()) { - debugFatal("Could not initialize receive handler\n"); - return false; - } - - // register the stream with the handler - if(!h->registerStream(stream)) { - debugFatal("Could not register receive stream with handler\n"); - return false; - } - - // register the handler with the manager - if(!registerHandler(h)) { - debugFatal("Could not register receive handler with manager\n"); - return false; - } - debugOutput( DEBUG_LEVEL_VERBOSE, " registered stream (%p) with handler (%p)\n",stream,h); - } - - if (stream->getType()==StreamProcessor::ePT_Transmit) { + debugOutput( DEBUG_LEVEL_VERBOSE, " registering IsoRecvHandler\n"); + + } else if (stream->getType()==StreamProcessor::ePT_Transmit) { // setup the optimal parameters for the raw1394 ISO buffering unsigned int packets_per_period = stream->getPacketsPerPeriod(); @@ -505,5 +299,5 @@ // create the actual handler - IsoXmitHandler *h = new IsoXmitHandler(*this, buffers, + h = new IsoXmitHandler(*this, buffers, max_packet_size, irq_interval); @@ -514,26 +308,36 @@ return false; } - - h->setVerboseLevel(getDebugLevel()); - - // init the handler - if(!h->init()) { - debugFatal("Could not initialize transmit handler\n"); - return false; - } - - // register the stream with the handler - if(!h->registerStream(stream)) { - debugFatal("Could not register transmit stream with handler\n"); - return false; - } - - // register the handler with the manager - if(!registerHandler(h)) { - debugFatal("Could not register transmit handler with manager\n"); - return false; - } - debugOutput( DEBUG_LEVEL_VERBOSE, " registered stream (%p) with handler (%p)\n",stream,h); - } + } else { + debugFatal("Bad stream type\n"); + return false; + } + + h->setVerboseLevel(getDebugLevel()); + + // init the handler + if(!h->init()) { + debugFatal("Could not initialize receive handler\n"); + return false; + } + + // set the handler's thread parameters + if(!h->setThreadParameters(m_realtime, m_priority)) { + debugFatal("Could not set handler thread parameters\n"); + return false; + } + + // register the stream with the handler + if(!h->registerStream(stream)) { + debugFatal("Could not register receive stream with handler\n"); + return false; + } + + // register the handler with the manager + if(!registerHandler(h)) { + debugFatal("Could not register receive handler with manager\n"); + return false; + } + debugOutput( DEBUG_LEVEL_VERBOSE, " registered stream (%p) with handler (%p)\n", stream, h); + m_StreamProcessors.push_back(stream); debugOutput( DEBUG_LEVEL_VERBOSE, " %d streams, %d handlers registered\n", @@ -632,5 +436,4 @@ debugOutput( DEBUG_LEVEL_VERBOSE, " stopping handler %p for stream %p\n", *it, stream); result = (*it)->disable(); - //requestShadowUpdate(); if(!result) { debugOutput( DEBUG_LEVEL_VERBOSE, " could not disable handler (%p)\n",*it); @@ -692,5 +495,4 @@ debugOutput( DEBUG_LEVEL_VERBOSE, " starting handler %p for stream %p\n", *it, stream); result = (*it)->enable(cycle); - requestShadowUpdate(); if(!result) { debugOutput( DEBUG_LEVEL_VERBOSE, " could not enable handler (%p)\n",*it); @@ -714,9 +516,4 @@ bool retval=true; - debugOutput( DEBUG_LEVEL_VERBOSE, "Stopping ISO iterator thread...\n"); - - m_isoManagerThread->Stop(); - m_isoManagerThread = NULL; - ZERO_ATOMIC((SInt32*)&m_request_fdmap_update); for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); @@ -730,5 +527,4 @@ } } - requestShadowUpdate(); if (retval) { @@ -754,7 +550,4 @@ setDebugLevel(i); // propagate the debug level - if(m_isoManagerThread) { - m_isoManagerThread->setVerboseLevel(getDebugLevel()); - } for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); it != m_IsoHandlers.end(); Index: /trunk/libffado/src/libieee1394/IsoHandlerManager.h =================================================================== --- /trunk/libffado/src/libieee1394/IsoHandlerManager.h (revision 752) +++ /trunk/libffado/src/libieee1394/IsoHandlerManager.h (revision 753) @@ -27,6 +27,4 @@ #include "debugmodule/debugmodule.h" -#include "libutil/Thread.h" - #include #include @@ -40,7 +38,4 @@ #define MAX_UPDATE_TRIES 10 class Ieee1394Service; -namespace Util { - class PosixThread; -} class IsoHandler; @@ -66,5 +61,5 @@ */ -class IsoHandlerManager : public Util::RunnableInterface +class IsoHandlerManager { friend class Streaming::StreamProcessorManager; @@ -77,7 +72,4 @@ bool setThreadParameters(bool rt, int priority); - - void setPollTimeout(int t) {m_poll_timeout=t;}; ///< set the timeout used for poll() - int getPollTimeout() {return m_poll_timeout;}; ///< get the timeout used for poll() void setVerboseLevel(int l); ///< set the verbose level @@ -115,12 +107,4 @@ Ieee1394Service& get1394Service() {return m_service;}; - // RunnableInterface interface - public: - bool Execute(); // note that this is called in we while(running) loop - bool Init(); - - // protects the operations on the lists - // (FIXME: should be changed into a lock-free approach) - pthread_mutex_t m_list_lock; // the state machine @@ -135,7 +119,4 @@ enum eHandlerStates m_State; const char *eHSToString(enum eHandlerStates); - private: - /// iterate all child handlers - bool iterate(); private: @@ -159,21 +140,7 @@ Streaming::StreamProcessorVector m_StreamProcessors; - // poll stuff - int m_poll_timeout; - // FD map sync requested - int32_t m_request_fdmap_update; - void updateShadowVars(); - - // shadow variables - struct pollfd m_poll_fds_shadow[FFADO_MAX_ISO_HANDLERS_PER_PORT]; - IsoHandler *m_IsoHandler_map_shadow[FFADO_MAX_ISO_HANDLERS_PER_PORT]; - unsigned int m_poll_nfds_shadow; - - void requestShadowUpdate(); - - // threading + // thread params for the handler threads bool m_realtime; int m_priority; - Util::PosixThread *m_isoManagerThread; // debug stuff Index: /trunk/libffado/src/libieee1394/IsoHandler.cpp =================================================================== --- /trunk/libffado/src/libieee1394/IsoHandler.cpp (revision 750) +++ /trunk/libffado/src/libieee1394/IsoHandler.cpp (revision 753) @@ -26,4 +26,5 @@ #include "libstreaming/generic/StreamProcessor.h" +#include "libutil/PosixThread.h" #include @@ -84,4 +85,8 @@ , m_dropped(0) , m_Client(0) + , m_poll_timeout( 100 ) + , m_realtime ( false ) + , m_priority ( 0 ) + , m_Thread ( NULL ) , m_State(E_Created) { @@ -97,4 +102,8 @@ , m_dropped(0) , m_Client(0) + , m_poll_timeout( 100 ) + , m_realtime ( false ) + , m_priority ( 0 ) + , m_Thread ( NULL ) , m_State(E_Created) { @@ -102,5 +111,8 @@ IsoHandler::~IsoHandler() { - + if (m_Thread) { + m_Thread->Stop(); + delete m_Thread; + } // Don't call until libraw1394's raw1394_new_handle() function has been // fixed to correctly initialise the iso_packet_infos field. Bug is @@ -116,18 +128,81 @@ } -bool IsoHandler::iterate() { +bool +IsoHandler::Init() { + debugOutput( DEBUG_LEVEL_VERBOSE, "%p: Init thread...\n", this); + m_poll_fd.fd = getFileDescriptor(); + m_poll_fd.revents = 0; + if (isEnabled()) { + m_poll_fd.events = POLLIN; + } else { + m_poll_fd.events = 0; + } + return true; +} + +bool +IsoHandler::Execute() { + int err; + + debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "%p: Execute thread...\n", this); + // bypass if not running + if (m_State != E_Running) { + debugOutput( DEBUG_LEVEL_VERBOSE, "%p: not polling since not running...\n", this); + usleep(m_poll_timeout * 1000); + debugOutput( DEBUG_LEVEL_VERBOSE, "%p: done sleeping...\n", this); + return true; + } + + err = poll(&m_poll_fd, 1, m_poll_timeout); + if (err == -1) { + if (errno == EINTR) { + return true; + } + debugFatal("%p, poll error: %s\n", this, strerror (errno)); + return false; + } + + if (m_poll_fd.revents & POLLERR) { + debugWarning("error on fd for %p\n", this); + } + + if (m_poll_fd.revents & POLLHUP) { + debugWarning("hangup on fd for %p\n",this); + } + + if(m_poll_fd.revents & (POLLIN)) { + iterate(); + } + + return true; +} + +bool +IsoHandler::setThreadParameters(bool rt, int priority) { + debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) (rt=%d, prio=%d)...\n", this, rt, priority); + if (priority > 98) priority = 98; // cap the priority + m_realtime = rt; + m_priority = priority; + + if (m_Thread) { + if (m_realtime) { + m_Thread->AcquireRealTime(m_priority); + } else { + m_Thread->DropRealTime(); + } + } + return true; +} + +bool +IsoHandler::iterate() { debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "IsoHandler (%p) iterate...\n",this); - - if(m_handle) { - if(raw1394_loop_iterate(m_handle)) { - debugOutput( DEBUG_LEVEL_VERBOSE, - "IsoHandler (%p): Failed to iterate handler: %s\n", - this,strerror(errno)); - return false; - } else { - return true; - } + if(raw1394_loop_iterate(m_handle)) { + debugOutput( DEBUG_LEVEL_VERBOSE, + "IsoHandler (%p): Failed to iterate handler: %s\n", + this,strerror(errno)); + return false; } else { - return false; + return true; } } @@ -166,4 +241,17 @@ } + // create a thread to iterate ourselves + debugOutput( DEBUG_LEVEL_VERBOSE, "Start thread for %p...\n", this); + m_Thread = new Util::PosixThread(this, m_realtime, m_priority, + PTHREAD_CANCEL_DEFERRED); + if(!m_Thread) { + debugFatal("No thread\n"); + return false; + } + if (m_Thread->Start() != 0) { + debugFatal("Could not start update thread\n"); + return false; + } + // update the internal state m_State=E_Initialized; @@ -190,4 +278,5 @@ { debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); + m_poll_fd.events = POLLIN; m_State = E_Running; return true; @@ -204,4 +293,6 @@ return false; } + + m_poll_fd.events = 0; // this is put here to try and avoid the @@ -251,4 +342,5 @@ { setDebugLevel(l); + if(m_Thread) m_Thread->setVerboseLevel(l); } Index: /trunk/libffado/src/libieee1394/IsoHandler.h =================================================================== --- /trunk/libffado/src/libieee1394/IsoHandler.h (revision 750) +++ /trunk/libffado/src/libieee1394/IsoHandler.h (revision 753) @@ -28,5 +28,7 @@ #include "IsoHandlerManager.h" -enum raw1394_iso_disposition ; +#include "libutil/Thread.h" + +enum raw1394_iso_disposition; namespace Streaming { @@ -43,5 +45,5 @@ */ -class IsoHandler +class IsoHandler : public Util::RunnableInterface { public: @@ -52,6 +54,11 @@ IsoHandler(IsoHandlerManager& manager); IsoHandler(IsoHandlerManager& manager, unsigned int buf_packets, unsigned int max_packet_size, int irq); - virtual ~IsoHandler(); + + // runnable interface + virtual bool Init(); + virtual bool Execute(); + int getFileDescriptor() { return raw1394_get_fd(m_handle);}; + bool setThreadParameters(bool rt, int priority); virtual bool init(); @@ -82,6 +89,4 @@ virtual enum EHandlerType getType() = 0; - - int getFileDescriptor() { return raw1394_get_fd(m_handle);}; virtual void dumpInfo(); @@ -108,4 +113,11 @@ private: static int busreset_handler(raw1394handle_t handle, unsigned int generation); + + struct pollfd m_poll_fd; + int m_poll_timeout; + // threading + bool m_realtime; + int m_priority; + Util::Thread * m_Thread; // the state machine Index: /trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.cpp =================================================================== --- /trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.cpp (revision 750) +++ /trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.cpp (revision 753) @@ -309,5 +309,5 @@ // Set up each frames's SPH. - for (unsigned int i=0; i 0) { - debugWarning("(%p) dropped %d packets on cycle %u\n", this, dropped_cycles, cycle); + debugWarning("(%p) dropped %d packets on cycle %u, 'dropped'=%u, cycle=%d, m_last_cycle=%d\n", + this, dropped_cycles, cycle, dropped, cycle, m_last_cycle); m_dropped += dropped_cycles; } @@ -444,5 +445,5 @@ #ifdef DEBUG - if(cycle_diff < 0) { + if(cycle_diff < 0 && (m_state == ePS_Running || m_state == ePS_DryRunning)) { debugWarning("Requesting packet for cycle %04d which is in the past (now=%04dcy)\n", cycle, now_cycles); @@ -541,5 +542,10 @@ goto send_empty_packet; } - return RAW1394_ISO_OK; + // skip queueing packets if we detect that there are not enough frames + // available + if(result2 == eCRV_Defer) + return RAW1394_ISO_DEFER; + else + return RAW1394_ISO_OK; } else if (result == eCRV_XRun) { // pick up the possible xruns debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to header xrun\n"); @@ -563,18 +569,18 @@ } goto send_empty_packet; -// } else if (result == eCRV_Again) { -// debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "have to retry cycle %d\n", cycle); -// if(m_state != m_next_state) { -// debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state from %s to %s\n", -// ePSToString(m_state), ePSToString(m_next_state)); -// // execute the requested change -// if (!updateState()) { // we are allowed to change the state directly -// debugError("Could not update state!\n"); -// return RAW1394_ISO_ERROR; -// } -// } - // force some delay -// usleep(125); -// return RAW1394_ISO_AGAIN; + } else if (result == eCRV_Again) { + debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "have to retry cycle %d\n", cycle); + if(m_state != m_next_state) { + debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state from %s to %s\n", + ePSToString(m_state), ePSToString(m_next_state)); + // execute the requested change + if (!updateState()) { // we are allowed to change the state directly + debugError("Could not update state!\n"); + return RAW1394_ISO_ERROR; + } + } + //force some delay + usleep(125); + return RAW1394_ISO_AGAIN; } else { debugError("Invalid return value: %d\n", result); Index: /trunk/libffado/src/libutil/TimestampedBuffer.cpp =================================================================== --- /trunk/libffado/src/libutil/TimestampedBuffer.cpp (revision 748) +++ /trunk/libffado/src/libutil/TimestampedBuffer.cpp (revision 753) @@ -1012,13 +1012,13 @@ ENTER_CRITICAL_SECTION; - diff=m_buffer_next_tail_timestamp - m_buffer_tail_timestamp; - timestamp=m_buffer_tail_timestamp; + diff = m_buffer_next_tail_timestamp - m_buffer_tail_timestamp; + timestamp = m_buffer_tail_timestamp; EXIT_CRITICAL_SECTION; if (diff < 0) diff += m_wrap_at; - rate=(float)diff / (float)m_update_period; - - timestamp-=(ffado_timestamp_t)((nframes) * rate); + rate = (float)diff / (float)m_update_period; + + timestamp -= (ffado_timestamp_t)((nframes) * rate); if(timestamp >= m_wrap_at) { Index: /trunk/libffado/SConstruct =================================================================== --- /trunk/libffado/SConstruct (revision 751) +++ /trunk/libffado/SConstruct (revision 753) @@ -230,5 +230,5 @@ env['PACKAGE'] = "libffado" -env['VERSION'] = "1.999.8" +env['VERSION'] = "1.999.9" env['LIBVERSION'] = "1.0.0"