Changeset 753
- Timestamp:
- 12/02/07 14:52:52 (16 years ago)
- Files:
-
- trunk/libffado/SConstruct (modified) (1 diff)
- trunk/libffado/src/libieee1394/CycleTimerHelper.cpp (modified) (8 diffs)
- trunk/libffado/src/libieee1394/ieee1394service.cpp (modified) (1 diff)
- trunk/libffado/src/libieee1394/IsoHandler.cpp (modified) (9 diffs)
- trunk/libffado/src/libieee1394/IsoHandler.h (modified) (5 diffs)
- trunk/libffado/src/libieee1394/IsoHandlerManager.cpp (modified) (17 diffs)
- trunk/libffado/src/libieee1394/IsoHandlerManager.h (modified) (7 diffs)
- trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp (modified) (3 diffs)
- trunk/libffado/src/libstreaming/generic/StreamProcessor.cpp (modified) (4 diffs)
- trunk/libffado/src/libstreaming/generic/StreamProcessor.h (modified) (1 diff)
- trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.cpp (modified) (1 diff)
- trunk/libffado/src/libstreaming/StreamProcessorManager.cpp (modified) (1 diff)
- trunk/libffado/src/libutil/TimestampedBuffer.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/libffado/SConstruct
r751 r753 230 230 231 231 env['PACKAGE'] = "libffado" 232 env['VERSION'] = "1.999. 8"232 env['VERSION'] = "1.999.9" 233 233 env['LIBVERSION'] = "1.0.0" 234 234 trunk/libffado/src/libieee1394/CycleTimerHelper.cpp
r752 r753 86 86 PTHREAD_CANCEL_DEFERRED); 87 87 if(!m_Thread) { 88 debugFatal("Could not create update thread\n");89 }90 if(!m_Thread) {91 88 debugFatal("No thread\n"); 92 89 return false; … … 142 139 CycleTimerHelper::Execute() 143 140 { 144 debugOutput( DEBUG_LEVEL_ VERY_VERBOSE, "Execute %p...\n", this);141 debugOutput( DEBUG_LEVEL_ULTRA_VERBOSE, "Execute %p...\n", this); 145 142 uint32_t cycle_timer; 146 143 uint64_t local_time; … … 149 146 return false; 150 147 } 151 debugOutput( DEBUG_LEVEL_ VERY_VERBOSE, " read : CTR: %11lu, local: %17llu\n",148 debugOutput( DEBUG_LEVEL_ULTRA_VERBOSE, " read : CTR: %11lu, local: %17llu\n", 152 149 cycle_timer, local_time); 153 150 … … 169 166 170 167 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", 172 169 local_time, m_current_time_usecs, m_next_time_usecs, diff); 173 170 … … 178 175 m_current_time_usecs = m_next_time_usecs; 179 176 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", 181 178 m_current_time_usecs, m_next_time_usecs, usecs_late); 182 179 … … 187 184 (uint64_t)((DLL_COEFF_B * diff_ticks) + m_dll_e2)); 188 185 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", 190 187 m_current_time_ticks, m_next_time_ticks, diff_ticks); 191 188 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", 193 190 local_time, m_dll_e2, getRate()); 194 191 } … … 209 206 //int64_t time_to_sleep = m_usecs_per_update; 210 207 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); 212 209 usleep(time_to_sleep); 213 210 } … … 241 238 retval = addTicks(offset_in_ticks_int, y_step_in_ticks_int); 242 239 } 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); 244 243 retval = substractTicks(offset_in_ticks_int, -y_step_in_ticks_int); 245 244 } trunk/libffado/src/libieee1394/ieee1394service.cpp
r752 r753 45 45 #define FFADO_MAX_FIREWIRE_PORTS 16 46 46 47 #define ISOMANAGER_PRIO_INCREASE 548 #define CYCLETIMER_HELPER_PRIO_INCREASE 647 #define ISOMANAGER_PRIO_INCREASE 10 48 #define CYCLETIMER_HELPER_PRIO_INCREASE 10 49 49 50 50 IMPL_DEBUG_MODULE( Ieee1394Service, Ieee1394Service, DEBUG_LEVEL_NORMAL ); trunk/libffado/src/libieee1394/IsoHandler.cpp
r750 r753 26 26 27 27 #include "libstreaming/generic/StreamProcessor.h" 28 #include "libutil/PosixThread.h" 28 29 29 30 #include <errno.h> … … 84 85 , m_dropped(0) 85 86 , m_Client(0) 87 , m_poll_timeout( 100 ) 88 , m_realtime ( false ) 89 , m_priority ( 0 ) 90 , m_Thread ( NULL ) 86 91 , m_State(E_Created) 87 92 { … … 97 102 , m_dropped(0) 98 103 , m_Client(0) 104 , m_poll_timeout( 100 ) 105 , m_realtime ( false ) 106 , m_priority ( 0 ) 107 , m_Thread ( NULL ) 99 108 , m_State(E_Created) 100 109 { … … 102 111 103 112 IsoHandler::~IsoHandler() { 104 113 if (m_Thread) { 114 m_Thread->Stop(); 115 delete m_Thread; 116 } 105 117 // Don't call until libraw1394's raw1394_new_handle() function has been 106 118 // fixed to correctly initialise the iso_packet_infos field. Bug is … … 116 128 } 117 129 118 bool IsoHandler::iterate() { 130 bool 131 IsoHandler::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 143 bool 144 IsoHandler::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 180 bool 181 IsoHandler::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 197 bool 198 IsoHandler::iterate() { 119 199 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; 130 205 } else { 131 return false;206 return true; 132 207 } 133 208 } … … 166 241 } 167 242 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 168 256 // update the internal state 169 257 m_State=E_Initialized; … … 190 278 { 191 279 debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 280 m_poll_fd.events = POLLIN; 192 281 m_State = E_Running; 193 282 return true; … … 204 293 return false; 205 294 } 295 296 m_poll_fd.events = 0; 206 297 207 298 // this is put here to try and avoid the … … 251 342 { 252 343 setDebugLevel(l); 344 if(m_Thread) m_Thread->setVerboseLevel(l); 253 345 } 254 346 trunk/libffado/src/libieee1394/IsoHandler.h
r750 r753 28 28 #include "IsoHandlerManager.h" 29 29 30 enum raw1394_iso_disposition ; 30 #include "libutil/Thread.h" 31 32 enum raw1394_iso_disposition; 31 33 32 34 namespace Streaming { … … 43 45 */ 44 46 45 class IsoHandler 47 class IsoHandler : public Util::RunnableInterface 46 48 { 47 49 public: … … 52 54 IsoHandler(IsoHandlerManager& manager); 53 55 IsoHandler(IsoHandlerManager& manager, unsigned int buf_packets, unsigned int max_packet_size, int irq); 54 55 56 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); 56 63 57 64 virtual bool init(); … … 82 89 83 90 virtual enum EHandlerType getType() = 0; 84 85 int getFileDescriptor() { return raw1394_get_fd(m_handle);};86 91 87 92 virtual void dumpInfo(); … … 108 113 private: 109 114 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; 110 122 111 123 // the state machine trunk/libffado/src/libieee1394/IsoHandlerManager.cpp
r752 r753 28 28 29 29 #include "libutil/Atomic.h" 30 #include "libutil/PosixThread.h"31 30 32 31 #include <assert.h> 33 32 34 #define MINIMUM_INTERRUPTS_PER_PERIOD 4U 35 #define PACKETS_PER_INTERRUPT 4U 33 #define MINIMUM_INTERRUPTS_PER_PERIOD 8U 36 34 37 35 IMPL_DEBUG_MODULE( IsoHandlerManager, IsoHandlerManager, DEBUG_LEVEL_NORMAL ); … … 42 40 : m_State(E_Created) 43 41 , 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) 46 43 {} 47 44 … … 49 46 : m_State(E_Created) 50 47 , 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) 53 49 {} 54 50 … … 63 59 m_realtime = rt; 64 60 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; 74 69 } 75 70 … … 83 78 } 84 79 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; 110 81 return true; 111 82 } 112 83 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; 84 bool 85 IsoHandlerManager::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 104 bool 105 IsoHandlerManager::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; 229 122 } 230 123 … … 234 127 assert(handler); 235 128 handler->setVerboseLevel(getDebugLevel()); 236 237 129 m_IsoHandlers.push_back(handler); 238 requestShadowUpdate();239 240 // rebuild the fd map for poll()'ing.241 130 return true; 242 131 } … … 253 142 if ( *it == handler ) { 254 143 m_IsoHandlers.erase(it); 255 requestShadowUpdate();256 144 return true; 257 145 } … … 259 147 debugFatal("Could not find handler (%p)\n", handler); 260 148 return false; //not found 261 }262 263 void264 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 the273 // handler thread when it has accepted the new FD map274 // 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 shadow281 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 the285 // handler thread when it has accepted the new FD map286 // 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 bool294 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 bool315 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;333 149 } 334 150 … … 352 168 assert(stream); 353 169 170 IsoHandler* h = NULL; 171 354 172 // make sure the stream isn't already attached to a handler 355 173 for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); … … 434 252 //irq_interval=2; // HACK 435 253 // create the actual handler 436 IsoRecvHandler *h = new IsoRecvHandler(*this, buffers,254 h = new IsoRecvHandler(*this, buffers, 437 255 max_packet_size, irq_interval); 438 439 debugOutput( DEBUG_LEVEL_VERBOSE, " registering IsoRecvHandler\n");440 441 256 if(!h) { 442 257 debugFatal("Could not create IsoRecvHandler\n"); 443 258 return false; 444 259 } 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) { 469 263 // setup the optimal parameters for the raw1394 ISO buffering 470 264 unsigned int packets_per_period = stream->getPacketsPerPeriod(); … … 505 299 506 300 // create the actual handler 507 IsoXmitHandler *h = new IsoXmitHandler(*this, buffers,301 h = new IsoXmitHandler(*this, buffers, 508 302 max_packet_size, irq_interval); 509 303 … … 514 308 return false; 515 309 } 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 538 342 m_StreamProcessors.push_back(stream); 539 343 debugOutput( DEBUG_LEVEL_VERBOSE, " %d streams, %d handlers registered\n", … … 632 436 debugOutput( DEBUG_LEVEL_VERBOSE, " stopping handler %p for stream %p\n", *it, stream); 633 437 result = (*it)->disable(); 634 //requestShadowUpdate();635 438 if(!result) { 636 439 debugOutput( DEBUG_LEVEL_VERBOSE, " could not disable handler (%p)\n",*it); … … 692 495 debugOutput( DEBUG_LEVEL_VERBOSE, " starting handler %p for stream %p\n", *it, stream); 693 496 result = (*it)->enable(cycle); 694 requestShadowUpdate();695 497 if(!result) { 696 498 debugOutput( DEBUG_LEVEL_VERBOSE, " could not enable handler (%p)\n",*it); … … 714 516 715 517 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);721 518 722 519 for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); … … 730 527 } 731 528 } 732 requestShadowUpdate();733 529 734 530 if (retval) { … … 754 550 setDebugLevel(i); 755 551 // propagate the debug level 756 if(m_isoManagerThread) {757 m_isoManagerThread->setVerboseLevel(getDebugLevel());758 }759 552 for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); 760 553 it != m_IsoHandlers.end(); trunk/libffado/src/libieee1394/IsoHandlerManager.h
r752 r753 27 27 #include "debugmodule/debugmodule.h" 28 28 29 #include "libutil/Thread.h"30 31 29 #include <sys/poll.h> 32 30 #include <errno.h> … … 40 38 #define MAX_UPDATE_TRIES 10 41 39 class Ieee1394Service; 42 namespace Util {43 class PosixThread;44 }45 40 46 41 class IsoHandler; … … 66 61 67 62 */ 68 class IsoHandlerManager : public Util::RunnableInterface63 class IsoHandlerManager 69 64 { 70 65 friend class Streaming::StreamProcessorManager; … … 77 72 78 73 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()82 74 83 75 void setVerboseLevel(int l); ///< set the verbose level … … 115 107 116 108 Ieee1394Service& get1394Service() {return m_service;}; 117 // RunnableInterface interface118 public:119 bool Execute(); // note that this is called in we while(running) loop120 bool Init();121 122 // protects the operations on the lists123 // (FIXME: should be changed into a lock-free approach)124 pthread_mutex_t m_list_lock;125 109 126 110 // the state machine … … 135 119 enum eHandlerStates m_State; 136 120 const char *eHSToString(enum eHandlerStates); 137 private:138 /// iterate all child handlers139 bool iterate();140 121 141 122 private: … … 159 140 Streaming::StreamProcessorVector m_StreamProcessors; 160 141 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 175 143 bool m_realtime; 176 144 int m_priority; 177 Util::PosixThread *m_isoManagerThread;178 145 179 146 // debug stuff trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp
r750 r753 162 162 else 163 163 { 164 debugOutput ( DEBUG_LEVEL_VER Y_VERBOSE,164 debugOutput ( DEBUG_LEVEL_VERBOSE, 165 165 "Insufficient frames (NP): N=%02d, CY=%04u, TC=%04u, CUT=%04d\n", 166 166 fc, cycle, transmit_at_cycle, cycles_until_transmit ); 167 167 // there is still time left to send the packet 168 168 // 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. 170 185 } 171 186 } … … 205 220 // we are not that late and can still try to transmit the packet 206 221 m_dbc += fillDataPacketHeader(packet, length, m_last_timestamp); 207 return eCRV_Packet;222 return (fc < (signed)(2*m_syt_interval) ? eCRV_Defer : eCRV_Packet); 208 223 } 209 224 else // definitely too late … … 216 231 // it's time send the packet 217 232 m_dbc += fillDataPacketHeader(packet, length, m_last_timestamp); 218 return eCRV_Packet;233 return (fc < (signed)(2*m_syt_interval) ? eCRV_Defer : eCRV_Packet); 219 234 } 220 235 else trunk/libffado/src/libstreaming/generic/StreamProcessor.cpp
r750 r753 236 236 if (dropped_cycles < 0) debugWarning("(%p) dropped < 1 (%d)\n", this, dropped_cycles); 237 237 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); 239 240 m_dropped += dropped_cycles; 240 241 } … … 444 445 445 446 #ifdef DEBUG 446 if(cycle_diff < 0 ) {447 if(cycle_diff < 0 && (m_state == ePS_Running || m_state == ePS_DryRunning)) { 447 448 debugWarning("Requesting packet for cycle %04d which is in the past (now=%04dcy)\n", 448 449 cycle, now_cycles); … … 541 542 goto send_empty_packet; 542 543 } 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; 544 550 } else if (result == eCRV_XRun) { // pick up the possible xruns 545 551 debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to header xrun\n"); … … 563 569 } 564 570 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 change571 //if (!updateState()) { // we are allowed to change the state directly572 //debugError("Could not update state!\n");573 //return RAW1394_ISO_ERROR;574 //}575 //}576 // 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; 579 585 } else { 580 586 debugError("Invalid return value: %d\n", result); trunk/libffado/src/libstreaming/generic/StreamProcessor.h
r750 r753 202 202 eCRV_XRun, 203 203 eCRV_Again, 204 eCRV_Defer, 204 205 }; 205 206 // to be implemented by the children trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.cpp
r750 r753 309 309 310 310 // 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) { 312 312 //FIXME: not sure which is best for the MOTU 313 313 // int64_t ts_frame = addTicks(ts, (unsigned int)(i * ticks_per_frame)); trunk/libffado/src/libstreaming/StreamProcessorManager.cpp
r750 r753 40 40 // time to a later time instant also causes the xmit buffer fill to be 41 41 // lower on average. 42 #define FFADO_SIGNAL_DELAY_TICKS 3072*442 #define FFADO_SIGNAL_DELAY_TICKS (3072*1) 43 43 44 44 namespace Streaming { trunk/libffado/src/libutil/TimestampedBuffer.cpp
r748 r753 1012 1012 ENTER_CRITICAL_SECTION; 1013 1013 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; 1016 1016 1017 1017 EXIT_CRITICAL_SECTION; 1018 1018 1019 1019 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); 1023 1023 1024 1024 if(timestamp >= m_wrap_at) {