root/trunk/libffado/src/libieee1394/IsoHandlerManager.cpp

Revision 1985, 70.2 kB (checked in by jwoithe, 10 years ago)

Fix double-free on exit under the new firewire stack. It seems that with the new kernel firewire stack, raw1394_destroy_handle() can take upwards of 20 milliseconds(!) to return. Therefore the IsoHandler?'s disable() call invoked by the IsoTask? (FW_ISORCV or FW_ISOXMT) may not have completed before the "jackd" thread calls ~IsoHandler?(). ~IsoHandler?() thus infers that the handler is still running and calls disable() itself. The practical upshot is that raw1394_destroy_handle() gets called on the same object twice, and a double-free results.

The fix I've implemented is a touch crude, but it appears to work. A mutex is introduced to track the progress of disable(), and this is checked by ~IsoHandler?() before the state of the handler is tested. Any in-progress disable() call is allowed to complete before ~IsoHandler?() tests the state. This prevents the second call of raw1394_destroy_handle() and therefore the double-free cannot occur.

Perhaps as a result of the delays caused by raw1394_destroy_handle(), it seems the handler list can be altered by other threads while updateShadowMapHelper() (called by the IsoTask? threads) is running. A crude test has been added to this function to prevent out-of-range exceptions in most cases.

None of this is particularly elegant but it should work around the double-free issue for the moment. The correct approach is to work out precisely why these concurrency issues are occuring and fix them. However, given that all this will be obsoleted by the in-kernel streaming work at some point in the future, it's arguable that the solution in this patch is sufficient in practice.

Line 
1 /*
2  * Copyright (C) 2005-2008 by Pieter Palmers
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB.
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) version 3 of the License.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 #include "config.h"
25
26 #include "IsoHandlerManager.h"
27 #include "ieee1394service.h"
28 #include "cycletimer.h"
29 #include "libstreaming/generic/StreamProcessor.h"
30
31 #include "libutil/Atomic.h"
32 #include "libutil/PosixThread.h"
33 #include "libutil/SystemTimeSource.h"
34 #include "libutil/Watchdog.h"
35 #include "libutil/Configuration.h"
36
37 #include <cstring>
38 #include <assert.h>
39
40 IMPL_DEBUG_MODULE( IsoHandlerManager, IsoHandlerManager, DEBUG_LEVEL_NORMAL );
41 IMPL_DEBUG_MODULE( IsoHandlerManager::IsoTask, IsoTask, DEBUG_LEVEL_NORMAL );
42 IMPL_DEBUG_MODULE( IsoHandlerManager::IsoHandler, IsoHandler, DEBUG_LEVEL_NORMAL );
43
44 using namespace Streaming;
45
46 // --- ISO Thread --- //
47
48 IsoHandlerManager::IsoTask::IsoTask(IsoHandlerManager& manager, enum IsoHandler::EHandlerType t)
49     : m_manager( manager )
50     , m_SyncIsoHandler ( NULL )
51     , m_handlerType( t )
52     , m_running( false )
53     , m_in_busreset( false )
54     , m_activity_wait_timeout_nsec (ISOHANDLERMANAGER_ISO_TASK_WAIT_TIMEOUT_USECS * 1000LL)
55 {
56 }
57
58 IsoHandlerManager::IsoTask::~IsoTask()
59 {
60     sem_destroy(&m_activity_semaphore);
61 }
62
63 bool
64 IsoHandlerManager::IsoTask::Init()
65 {
66     request_update = 0;
67
68     int i;
69     for (i=0; i < ISOHANDLERMANAGER_MAX_ISO_HANDLERS_PER_PORT; i++) {
70         m_IsoHandler_map_shadow[i] = NULL;
71         m_poll_fds_shadow[i].events = 0;
72     }
73     m_poll_nfds_shadow = 0;
74
75     #ifdef DEBUG
76     m_last_loop_entry = 0;
77     m_successive_short_loops = 0;
78     #endif
79
80     sem_init(&m_activity_semaphore, 0, 0);
81     m_running = true;
82     return true;
83 }
84
85 void
86 IsoHandlerManager::IsoTask::requestShadowMapUpdate()
87 {
88     debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) enter\n", this);
89     INC_ATOMIC(&request_update);
90
91     // get the thread going again
92     signalActivity();
93     debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) exit\n", this);
94 }
95
96 bool
97 IsoHandlerManager::IsoTask::handleBusReset()
98 {
99     bool retval = true;
100     if(!m_running) {
101         // nothing to do here
102         return true;
103     }
104     m_in_busreset = true;
105     requestShadowMapUpdate();
106
107     unsigned int i, max;
108     max = m_manager.m_IsoHandlers.size();
109     for (i = 0; i < max; i++) {
110         IsoHandler *h = m_manager.m_IsoHandlers.at(i);
111         assert(h);
112
113         // skip the handlers not intended for us
114         if(h->getType() != m_handlerType) continue;
115
116         if (!h->handleBusReset()) {
117             debugWarning("Failed to handle busreset on %p\n", h);
118             retval = false;
119         }
120     }
121
122     // re-enable processing
123     m_in_busreset = false;
124     requestShadowMapUpdate();
125     return retval;
126 }
127
128 // updates the internal stream map
129 // note that this should be executed with the guarantee that
130 // nobody will modify the parent data structures
131 void
132 IsoHandlerManager::IsoTask::updateShadowMapHelper()
133 {
134     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) updating shadow vars...\n", this);
135     // we are handling a busreset
136     if(m_in_busreset) {
137         m_poll_nfds_shadow = 0;
138         return;
139     }
140     unsigned int i, cnt, max;
141     max = m_manager.m_IsoHandlers.size();
142     m_SyncIsoHandler = NULL;
143     for (i = 0, cnt = 0; i < max; i++) {
144
145         // FIXME: This is a very crude guard against some other thread
146         // deleting handlers while this function is running.  While this
147         // didn't tend to happen with the old kernel firewire stack, delays
148         // in shutdown experienced in the new stack mean it can happen that
149         // a handler disappears during the running of this function.  This
150         // test should prevent "out of range" exceptions in most cases.
151         // However, it is racy: if the deletion happens between this
152         // conditional and the following at() call, an out of range
153         // condition can still happen.
154         if (i>=m_manager.m_IsoHandlers.size())
155             continue;
156
157         IsoHandler *h = m_manager.m_IsoHandlers.at(i);
158         assert(h);
159
160         // skip the handlers not intended for us
161         if(h->getType() != m_handlerType) continue;
162
163         // update the state of the handler
164         // FIXME: maybe this is not the best place to do this
165         // it might be better to eliminate the 'requestShadowMapUpdate'
166         // entirely and replace it with a mechanism that implements all
167         // actions on the m_manager.m_IsoHandlers in the loop
168         h->updateState();
169
170         // rebuild the map
171         if (h->isEnabled()) {
172             m_IsoHandler_map_shadow[cnt] = h;
173             m_poll_fds_shadow[cnt].fd = h->getFileDescriptor();
174             m_poll_fds_shadow[cnt].revents = 0;
175             m_poll_fds_shadow[cnt].events = POLLIN;
176             cnt++;
177             // FIXME: need a more generic approach here
178             if(   m_SyncIsoHandler == NULL
179                && h->getType() == IsoHandler::eHT_Transmit) {
180                 m_SyncIsoHandler = h;
181             }
182
183             debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) %s handler %p added\n",
184                                               this, h->getTypeString(), h);
185         } else {
186             debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) %s handler %p skipped (disabled)\n",
187                                               this, h->getTypeString(), h);
188         }
189         if(cnt > ISOHANDLERMANAGER_MAX_ISO_HANDLERS_PER_PORT) {
190             debugWarning("Too much ISO Handlers in thread...\n");
191             break;
192         }
193     }
194
195     // FIXME: need a more generic approach here
196     // if there are no active transmit handlers,
197     // use the first receive handler
198     if(   m_SyncIsoHandler == NULL
199        && m_poll_nfds_shadow) {
200         m_SyncIsoHandler = m_IsoHandler_map_shadow[0];
201     }
202     m_poll_nfds_shadow = cnt;
203     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) updated shadow vars...\n", this);
204 }
205
206 bool
207 IsoHandlerManager::IsoTask::Execute()
208 {
209     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE,
210                 "(%p, %s) Execute\n",
211                 this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"));
212     int err;
213     unsigned int i;
214     unsigned int m_poll_timeout = 10;
215
216     #ifdef DEBUG
217     uint64_t now = Util::SystemTimeSource::getCurrentTimeAsUsecs();
218     int diff = now - m_last_loop_entry;
219     if(diff < 100) {
220         debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE,
221                            "(%p, %s) short loop detected (%d usec), cnt: %d\n",
222                            this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"),
223                            diff, m_successive_short_loops);
224         m_successive_short_loops++;
225         if(m_successive_short_loops > 10000) {
226             debugError("Shutting down runaway thread\n");
227             m_running = false;
228             return false;
229         }
230     } else {
231         // reset the counter
232         m_successive_short_loops = 0;
233     }
234     m_last_loop_entry = now;
235     #endif
236
237     // if some other thread requested a shadow map update, do it
238     if(request_update) {
239         updateShadowMapHelper();
240         DEC_ATOMIC(&request_update); // ack the update
241         assert(request_update >= 0);
242     }
243
244     // bypass if no handlers are registered
245     if (m_poll_nfds_shadow == 0) {
246         debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE,
247                            "(%p, %s) bypass iterate since no handlers to poll\n",
248                            this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"));
249         usleep(m_poll_timeout * 1000);
250         return true;
251     }
252
253     // FIXME: what can happen is that poll() returns, but not all clients are
254     // ready. there might be some busy waiting behavior that still has to be solved.
255
256     // setup the poll here
257     // we should prevent a poll() where no events are specified, since that will only time-out
258     bool no_one_to_poll = true;
259     while(no_one_to_poll) {
260         for (i = 0; i < m_poll_nfds_shadow; i++) {
261             short events = 0;
262             IsoHandler *h = m_IsoHandler_map_shadow[i];
263             // we should only poll on a transmit handler
264             // that has a client that is ready to send
265             // something. Otherwise it will end up in
266             // busy wait looping since the packet function
267             // will defer processing (also avoids the
268             // AGAIN problem)
269             if (h->canIterateClient()) {
270                 events = POLLIN | POLLPRI;
271                 no_one_to_poll = false;
272             }
273             m_poll_fds_shadow[i].events = events;
274         }
275
276         if(no_one_to_poll) {
277             debugOutputExtreme(DEBUG_LEVEL_VERBOSE,
278                         "(%p, %s) No one to poll, waiting for something to happen\n",
279                         this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"));
280             // wait for something to happen
281             switch(waitForActivity()) {
282                 case IsoHandlerManager::IsoTask::eAR_Error:
283                     debugError("Error while waiting for activity\n");
284                     return false;
285                 case IsoHandlerManager::IsoTask::eAR_Interrupted:
286                     // FIXME: what to do here?
287                     debugWarning("Interrupted while waiting for activity\n");
288                     break;
289                 case IsoHandlerManager::IsoTask::eAR_Timeout:
290                     // FIXME: what to do here?
291                     debugWarning("Timeout while waiting for activity\n");
292                     no_one_to_poll = false; // exit the loop to be able to detect failing handlers
293                     break;
294                 case IsoHandlerManager::IsoTask::eAR_Activity:
295                     // do nothing
296                     debugOutputExtreme(DEBUG_LEVEL_VERBOSE,
297                                        "(%p, %s) something happened\n",
298                                        this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"));
299                     break;
300             }
301         }
302     }
303
304     // Use a shadow map of the fd's such that we don't have to update
305     // the fd map everytime we run poll().
306     err = poll (m_poll_fds_shadow, m_poll_nfds_shadow, m_poll_timeout);
307     uint32_t ctr_at_poll_return = m_manager.get1394Service().getCycleTimer();
308
309     if (err < 0) {
310         if (errno == EINTR) {
311             debugOutput(DEBUG_LEVEL_VERBOSE, "Ignoring poll return due to signal\n");
312             return true;
313         }
314         debugFatal("poll error: %s\n", strerror (errno));
315         m_running = false;
316         return false;
317     }
318
319     // find handlers that have died
320     uint64_t ctr_at_poll_return_ticks = CYCLE_TIMER_TO_TICKS(ctr_at_poll_return);
321     bool handler_died = false;
322     for (i = 0; i < m_poll_nfds_shadow; i++) {
323         // figure out if a handler has died
324
325         // this is the time of the last packet we saw in the iterate() handler
326         uint32_t last_packet_seen = m_IsoHandler_map_shadow[i]->getLastPacketTime();
327         if (last_packet_seen == 0xFFFFFFFF) {
328             // this was not iterated yet, so can't be dead
329             debugOutput(DEBUG_LEVEL_VERY_VERBOSE,
330                         "(%p, %s) handler %d didn't see any packets yet\n",
331                         this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"), i);
332             continue;
333         }
334
335         uint64_t last_packet_seen_ticks = CYCLE_TIMER_TO_TICKS(last_packet_seen);
336         // we use a relatively large value to distinguish between "death" and xrun
337         int64_t max_diff_ticks = TICKS_PER_SECOND * 2;
338         int64_t measured_diff_ticks = diffTicks(ctr_at_poll_return_ticks, last_packet_seen_ticks);
339
340         debugOutputExtreme(DEBUG_LEVEL_VERBOSE,
341                            "(%p, %s) check handler %d: diff = %"PRId64", max = %"PRId64", now: %08X, last: %08X\n",
342                            this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"),
343                            i, measured_diff_ticks, max_diff_ticks, ctr_at_poll_return, last_packet_seen);
344         if(measured_diff_ticks > max_diff_ticks) {
345             debugFatal("(%p, %s) Handler died: now: %08X, last: %08X, diff: %"PRId64" (max: %"PRId64")\n",
346                        this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"),
347                        ctr_at_poll_return, last_packet_seen, measured_diff_ticks, max_diff_ticks);
348             m_IsoHandler_map_shadow[i]->notifyOfDeath();
349             handler_died = true;
350         }
351     }
352
353     if(handler_died) {
354         m_running = false;
355         return false; // one or more handlers have died
356     }
357
358     // iterate the handlers
359     for (i = 0; i < m_poll_nfds_shadow; i++) {
360         #ifdef DEBUG
361         if(m_poll_fds_shadow[i].revents) {
362             debugOutputExtreme(DEBUG_LEVEL_VERBOSE,
363                         "(%p, %s) received events: %08X for (%d/%d, %p, %s)\n",
364                         this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"),
365                         m_poll_fds_shadow[i].revents,
366                         i, m_poll_nfds_shadow,
367                         m_IsoHandler_map_shadow[i],
368                         m_IsoHandler_map_shadow[i]->getTypeString());
369         }
370         #endif
371
372         // if we get here, it means two things:
373         // 1) the kernel can accept or provide packets (poll returned POLLIN)
374         // 2) the client can provide or accept packets (since we enabled polling)
375         if(m_poll_fds_shadow[i].revents & (POLLIN)) {
376             m_IsoHandler_map_shadow[i]->iterate(ctr_at_poll_return);
377         } else {
378             // there might be some error condition
379             if (m_poll_fds_shadow[i].revents & POLLERR) {
380                 debugWarning("(%p) error on fd for %d\n", this, i);
381             }
382             if (m_poll_fds_shadow[i].revents & POLLHUP) {
383                 debugWarning("(%p) hangup on fd for %d\n", this, i);
384             }
385         }
386     }
387     return true;
388 }
389
390 enum IsoHandlerManager::IsoTask::eActivityResult
391 IsoHandlerManager::IsoTask::waitForActivity()
392 {
393     debugOutputExtreme(DEBUG_LEVEL_VERBOSE,
394                        "(%p, %s) waiting for activity\n",
395                        this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"));
396     struct timespec ts;
397     int result;
398
399     if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
400         debugError("clock_gettime failed\n");
401         return eAR_Error;
402     }
403
404     ts.tv_nsec += m_activity_wait_timeout_nsec;
405     while(ts.tv_nsec >= 1000000000LL) {
406         ts.tv_sec += 1;
407         ts.tv_nsec -= 1000000000LL;
408     }
409
410     result = sem_timedwait(&m_activity_semaphore, &ts);
411
412     if(result != 0) {
413         if (errno == ETIMEDOUT) {
414             debugOutput(DEBUG_LEVEL_VERBOSE,
415                         "(%p) sem_timedwait() timed out (result=%d)\n",
416                         this, result);
417             return eAR_Timeout;
418         } else if (errno == EINTR) {
419             debugOutput(DEBUG_LEVEL_VERBOSE,
420                         "(%p) sem_timedwait() interrupted by signal (result=%d)\n",
421                         this, result);
422             return eAR_Interrupted;
423         } else if (errno == EINVAL) {
424             debugError("(%p) sem_timedwait error (result=%d errno=EINVAL)\n",
425                         this, result);
426             debugError("(%p) timeout_nsec=%lld ts.sec=%"PRId64" ts.nsec=%"PRId64"\n",
427                        this, m_activity_wait_timeout_nsec,
428                        (int64_t)ts.tv_sec, (int64_t)ts.tv_nsec);
429             return eAR_Error;
430         } else {
431             debugError("(%p) sem_timedwait error (result=%d errno=%d)\n",
432                         this, result, errno);
433             debugError("(%p) timeout_nsec=%lld ts.sec=%"PRId64" ts.nsec=%"PRId64"\n",
434                        this, m_activity_wait_timeout_nsec,
435                        (int64_t)ts.tv_sec, (int64_t)ts.tv_nsec);
436             return eAR_Error;
437         }
438     }
439
440     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE,
441                 "(%p, %s) got activity\n",
442                 this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"));
443     return eAR_Activity;
444 }
445
446 void
447 IsoHandlerManager::IsoTask::signalActivity()
448 {
449     // signal the activity cond var
450     sem_post(&m_activity_semaphore);
451     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE,
452                 "(%p, %s) activity\n",
453                 this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"));
454 }
455
456 void IsoHandlerManager::IsoTask::setVerboseLevel(int i) {
457     setDebugLevel(i);
458     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", i );
459 }
460
461 // -- the ISO handler manager -- //
462 IsoHandlerManager::IsoHandlerManager(Ieee1394Service& service)
463    : m_State(E_Created)
464    , m_service( service )
465    , m_realtime(false), m_priority(0)
466    , m_IsoThreadTransmit ( NULL )
467    , m_IsoTaskTransmit ( NULL )
468    , m_IsoThreadReceive ( NULL )
469    , m_IsoTaskReceive ( NULL )
470 {
471 }
472
473 IsoHandlerManager::IsoHandlerManager(Ieee1394Service& service, bool run_rt, int rt_prio)
474    : m_State(E_Created)
475    , m_service( service )
476    , m_realtime(run_rt), m_priority(rt_prio)
477    , m_IsoThreadTransmit ( NULL )
478    , m_IsoTaskTransmit ( NULL )
479    , m_IsoThreadReceive ( NULL )
480    , m_IsoTaskReceive ( NULL )
481    , m_MissedCyclesOK ( false )
482 {
483 }
484
485 IsoHandlerManager::~IsoHandlerManager()
486 {
487     stopHandlers();
488     pruneHandlers();
489     if(m_IsoHandlers.size() > 0) {
490         debugError("Still some handlers in use\n");
491     }
492     if (m_IsoThreadTransmit) {
493         m_IsoThreadTransmit->Stop();
494         delete m_IsoThreadTransmit;
495     }
496     if (m_IsoThreadReceive) {
497         m_IsoThreadReceive->Stop();
498         delete m_IsoThreadReceive;
499     }
500     if (m_IsoTaskTransmit) {
501         delete m_IsoTaskTransmit;
502     }
503     if (m_IsoTaskReceive) {
504         delete m_IsoTaskReceive;
505     }
506 }
507
508 bool
509 IsoHandlerManager::handleBusReset()
510 {
511     debugOutput( DEBUG_LEVEL_NORMAL, "bus reset...\n");
512     // A few things can happen on bus reset:
513     // 1) no devices added/removed => streams are still valid, but might have to be restarted
514     // 2) a device was removed => some streams become invalid
515     // 3) a device was added => same as 1, new device is ignored
516     if (!m_IsoTaskTransmit) {
517         debugError("No xmit task\n");
518         return false;
519     }
520     if (!m_IsoTaskReceive) {
521         debugError("No receive task\n");
522         return false;
523     }
524     if (!m_IsoTaskTransmit->handleBusReset()) {
525         debugWarning("could no handle busreset on xmit\n");
526     }
527     if (!m_IsoTaskReceive->handleBusReset()) {
528         debugWarning("could no handle busreset on recv\n");
529     }
530     return true;
531 }
532
533 void
534 IsoHandlerManager::requestShadowMapUpdate()
535 {
536     if(m_IsoTaskTransmit) m_IsoTaskTransmit->requestShadowMapUpdate();
537     if(m_IsoTaskReceive) m_IsoTaskReceive->requestShadowMapUpdate();
538 }
539
540 bool
541 IsoHandlerManager::setThreadParameters(bool rt, int priority) {
542     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) switch to: (rt=%d, prio=%d)...\n", this, rt, priority);
543     if (priority > THREAD_MAX_RTPRIO) priority = THREAD_MAX_RTPRIO; // cap the priority
544     if (priority < THREAD_MIN_RTPRIO) priority = THREAD_MIN_RTPRIO; // cap the priority
545     m_realtime = rt;
546     m_priority = priority;
547
548     // grab the options from the parent
549     Util::Configuration *config = m_service.getConfiguration();
550     int ihm_iso_prio_increase = ISOHANDLERMANAGER_ISO_PRIO_INCREASE;
551     int ihm_iso_prio_increase_xmit = ISOHANDLERMANAGER_ISO_PRIO_INCREASE_XMIT;
552     int ihm_iso_prio_increase_recv = ISOHANDLERMANAGER_ISO_PRIO_INCREASE_RECV;
553     if(config) {
554         config->getValueForSetting("ieee1394.isomanager.prio_increase", ihm_iso_prio_increase);
555         config->getValueForSetting("ieee1394.isomanager.prio_increase_xmit", ihm_iso_prio_increase_xmit);
556         config->getValueForSetting("ieee1394.isomanager.prio_increase_recv", ihm_iso_prio_increase_recv);
557     }
558
559     if (m_IsoThreadTransmit) {
560         if (m_realtime) {
561             m_IsoThreadTransmit->AcquireRealTime(m_priority
562                                                  + ihm_iso_prio_increase
563                                                  + ihm_iso_prio_increase_xmit);
564         } else {
565             m_IsoThreadTransmit->DropRealTime();
566         }
567     }
568     if (m_IsoThreadReceive) {
569         if (m_realtime) {
570             m_IsoThreadReceive->AcquireRealTime(m_priority
571                                                 + ihm_iso_prio_increase
572                                                 + ihm_iso_prio_increase_recv);
573         } else {
574             m_IsoThreadReceive->DropRealTime();
575         }
576     }
577
578     return true;
579 }
580
581 bool IsoHandlerManager::init()
582 {
583     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing ISO manager %p...\n", this);
584     // check state
585     if(m_State != E_Created) {
586         debugError("Manager already initialized...\n");
587         return false;
588     }
589
590     // grab the options from the parent
591     Util::Configuration *config = m_service.getConfiguration();
592     int ihm_iso_prio_increase = ISOHANDLERMANAGER_ISO_PRIO_INCREASE;
593     int ihm_iso_prio_increase_xmit = ISOHANDLERMANAGER_ISO_PRIO_INCREASE_XMIT;
594     int ihm_iso_prio_increase_recv = ISOHANDLERMANAGER_ISO_PRIO_INCREASE_RECV;
595     int64_t isotask_activity_timeout_usecs = ISOHANDLERMANAGER_ISO_TASK_WAIT_TIMEOUT_USECS;
596     if(config) {
597         config->getValueForSetting("ieee1394.isomanager.prio_increase", ihm_iso_prio_increase);
598         config->getValueForSetting("ieee1394.isomanager.prio_increase_xmit", ihm_iso_prio_increase_xmit);
599         config->getValueForSetting("ieee1394.isomanager.prio_increase_recv", ihm_iso_prio_increase_recv);
600         config->getValueForSetting("ieee1394.isomanager.isotask_activity_timeout_usecs", isotask_activity_timeout_usecs);
601     }
602
603     // create threads to iterate our ISO handlers
604     debugOutput( DEBUG_LEVEL_VERBOSE, "Create iso thread for %p transmit...\n", this);
605     m_IsoTaskTransmit = new IsoTask( *this, IsoHandler::eHT_Transmit );
606     if(!m_IsoTaskTransmit) {
607         debugFatal("No task\n");
608         return false;
609     }
610     m_IsoTaskTransmit->setVerboseLevel(getDebugLevel());
611     m_IsoTaskTransmit->m_activity_wait_timeout_nsec = isotask_activity_timeout_usecs * 1000LL;
612     m_IsoThreadTransmit = new Util::PosixThread(m_IsoTaskTransmit, "ISOXMT", m_realtime,
613                                                 m_priority + ihm_iso_prio_increase
614                                                 + ihm_iso_prio_increase_xmit,
615                                                 PTHREAD_CANCEL_DEFERRED);
616
617     if(!m_IsoThreadTransmit) {
618         debugFatal("No thread\n");
619         return false;
620     }
621     m_IsoThreadTransmit->setVerboseLevel(getDebugLevel());
622
623     debugOutput( DEBUG_LEVEL_VERBOSE, "Create iso thread for %p receive...\n", this);
624     m_IsoTaskReceive = new IsoTask( *this, IsoHandler::eHT_Receive );
625     if(!m_IsoTaskReceive) {
626         debugFatal("No task\n");
627         return false;
628     }
629     m_IsoTaskReceive->setVerboseLevel(getDebugLevel());
630     m_IsoThreadReceive = new Util::PosixThread(m_IsoTaskReceive, "ISORCV", m_realtime,
631                                                m_priority + ihm_iso_prio_increase
632                                                + ihm_iso_prio_increase_recv,
633                                                PTHREAD_CANCEL_DEFERRED);
634
635     if(!m_IsoThreadReceive) {
636         debugFatal("No thread\n");
637         return false;
638     }
639     m_IsoThreadReceive->setVerboseLevel(getDebugLevel());
640     // register the thread with the RT watchdog
641     Util::Watchdog *watchdog = m_service.getWatchdog();
642     if(watchdog) {
643         if(!watchdog->registerThread(m_IsoThreadTransmit)) {
644             debugWarning("could not register iso transmit thread with watchdog\n");
645         }
646         if(!watchdog->registerThread(m_IsoThreadReceive)) {
647             debugWarning("could not register iso receive thread with watchdog\n");
648         }
649     } else {
650         debugWarning("could not find valid watchdog\n");
651     }
652
653     if (m_IsoThreadTransmit->Start() != 0) {
654         debugFatal("Could not start ISO Transmit thread\n");
655         return false;
656     }
657     if (m_IsoThreadReceive->Start() != 0) {
658         debugFatal("Could not start ISO Receive thread\n");
659         return false;
660     }
661
662     m_State=E_Running;
663     return true;
664 }
665
666 void
667 IsoHandlerManager::signalActivityTransmit()
668 {
669     assert(m_IsoTaskTransmit);
670     m_IsoTaskTransmit->signalActivity();
671 }
672
673 void
674 IsoHandlerManager::signalActivityReceive()
675 {
676     assert(m_IsoTaskReceive);
677     m_IsoTaskReceive->signalActivity();
678 }
679
680 bool IsoHandlerManager::registerHandler(IsoHandler *handler)
681 {
682     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
683     assert(handler);
684     handler->setVerboseLevel(getDebugLevel());
685     m_IsoHandlers.push_back(handler);
686     requestShadowMapUpdate();
687     return true;
688 }
689
690 bool IsoHandlerManager::unregisterHandler(IsoHandler *handler)
691 {
692     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
693     assert(handler);
694
695     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
696       it != m_IsoHandlers.end();
697       ++it )
698     {
699         if ( *it == handler ) {
700             m_IsoHandlers.erase(it);
701             requestShadowMapUpdate();
702             return true;
703         }
704     }
705     debugFatal("Could not find handler (%p)\n", handler);
706     return false; //not found
707 }
708
709 /**
710  * Registers an StreamProcessor with the IsoHandlerManager.
711  *
712  * If nescessary, an IsoHandler is created to handle this stream.
713  * Once an StreamProcessor is registered to the handler, it will be included
714  * in the ISO streaming cycle (i.e. receive/transmit of it will occur).
715  *
716  * @param stream the stream to register
717  * @return true if registration succeeds
718  *
719  * \todo : currently there is a one-to-one mapping
720  *        between streams and handlers, this is not ok for
721  *        multichannel receive
722  */
723 bool IsoHandlerManager::registerStream(StreamProcessor *stream)
724 {
725     debugOutput( DEBUG_LEVEL_VERBOSE, "Registering %s stream %p\n", stream->getTypeString(), stream);
726     assert(stream);
727
728     IsoHandler* h = NULL;
729
730     // make sure the stream isn't already attached to a handler
731     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
732       it != m_IsoHandlers.end();
733       ++it )
734     {
735         if((*it)->isStreamRegistered(stream)) {
736             debugError( "stream already registered!\n");
737             return false;
738         }
739     }
740
741     // clean up all handlers that aren't used
742     pruneHandlers();
743
744     // allocate a handler for this stream
745     if (stream->getType()==StreamProcessor::ePT_Receive) {
746         // grab the options from the parent
747         Util::Configuration *config = m_service.getConfiguration();
748         int receive_mode_setting = DEFAULT_ISO_RECEIVE_MODE;
749         int bufferfill_mode_threshold = BUFFERFILL_MODE_THRESHOLD;
750         int min_interrupts_per_period = MINIMUM_INTERRUPTS_PER_PERIOD;
751         int max_nb_buffers_recv = MAX_RECV_NB_BUFFERS;
752         int min_packetsize_recv = MIN_RECV_PACKET_SIZE;
753         if(config) {
754             config->getValueForSetting("ieee1394.isomanager.iso_receive_mode", receive_mode_setting);
755             config->getValueForSetting("ieee1394.isomanager.bufferfill_mode_threshold", bufferfill_mode_threshold);
756             config->getValueForSetting("ieee1394.isomanager.min_interrupts_per_period", min_interrupts_per_period);
757             config->getValueForSetting("ieee1394.isomanager.max_nb_buffers_recv", max_nb_buffers_recv);
758             config->getValueForSetting("ieee1394.isomanager.min_packetsize_recv", min_packetsize_recv);
759         }
760
761         // setup the optimal parameters for the raw1394 ISO buffering
762         unsigned int packets_per_period = stream->getPacketsPerPeriod();
763         // reserve space for the 1394 header too (might not be necessary)
764         unsigned int max_packet_size = stream->getMaxPacketSize() + 8;
765         unsigned int page_size = getpagesize();
766
767         enum raw1394_iso_dma_recv_mode receive_mode =
768                 RAW1394_DMA_PACKET_PER_BUFFER;
769         switch(receive_mode_setting) {
770             case 0:
771                 if(packets_per_period < (unsigned)bufferfill_mode_threshold) {
772                     debugOutput( DEBUG_LEVEL_VERBOSE, "Using packet-per-buffer mode (auto) [%d, %d]\n",
773                                  packets_per_period, bufferfill_mode_threshold);
774                     receive_mode = RAW1394_DMA_PACKET_PER_BUFFER;
775                 } else {
776                     debugOutput( DEBUG_LEVEL_VERBOSE, "Using bufferfill mode (auto) [%d, %d]\n",
777                                  packets_per_period, bufferfill_mode_threshold);
778                     receive_mode = RAW1394_DMA_BUFFERFILL;
779                 }
780                 break;
781             case 1:
782                 debugOutput( DEBUG_LEVEL_VERBOSE, "Using packet-per-buffer mode (config)\n");
783                 receive_mode = RAW1394_DMA_PACKET_PER_BUFFER;
784                 break;
785             case 2:
786                 debugOutput( DEBUG_LEVEL_VERBOSE, "Using bufferfill mode (config)\n");
787                 receive_mode = RAW1394_DMA_BUFFERFILL;
788                 break;
789             default: debugWarning("Bogus receive mode setting in config: %d\n", receive_mode_setting);
790         }
791
792         // Ensure we don't request a packet size bigger than the
793         // kernel-enforced maximum which is currently 1 page.
794         // NOTE: PP: this is not really true AFAICT
795         if (max_packet_size > page_size) {
796             debugError("max packet size (%u) > page size (%u)\n", max_packet_size, page_size);
797             return false;
798         }
799         if (max_packet_size < (unsigned)min_packetsize_recv) {
800             debugError("min packet size (%u) < MIN_RECV_PACKET_SIZE (%u), using min value\n",
801                        max_packet_size, min_packetsize_recv);
802             max_packet_size = min_packetsize_recv;
803         }
804
805         // apparently a too small value causes issues too
806         if(max_packet_size < 200) max_packet_size = 200;
807
808         // the interrupt/wakeup interval prediction of raw1394 is a mess...
809         int irq_interval = (packets_per_period-1) / min_interrupts_per_period;
810         if(irq_interval <= 0) irq_interval=1;
811
812         // the receive buffer size doesn't matter for the latency,
813         // it does seem to be confined to a certain region for correct
814         // operation. However it is not clear how many.
815         int buffers = max_nb_buffers_recv;
816
817         // ensure at least 2 hardware interrupts per ISO buffer wraparound
818         if(irq_interval > buffers/2) {
819             irq_interval = buffers/2;
820         }
821
822         // create the actual handler
823         debugOutput( DEBUG_LEVEL_VERBOSE, " creating IsoRecvHandler\n");
824         h = new IsoHandler(*this, IsoHandler::eHT_Receive,
825                            buffers, max_packet_size, irq_interval);
826
827         if(!h) {
828             debugFatal("Could not create IsoRecvHandler\n");
829             return false;
830         }
831
832         h->setReceiveMode(receive_mode);
833
834     } else if (stream->getType()==StreamProcessor::ePT_Transmit) {
835         // grab the options from the parent
836         Util::Configuration *config = m_service.getConfiguration();
837         int min_interrupts_per_period = MINIMUM_INTERRUPTS_PER_PERIOD;
838         int max_nb_buffers_xmit = MAX_XMIT_NB_BUFFERS;
839         int max_packetsize_xmit = MAX_XMIT_PACKET_SIZE;
840         int min_packetsize_xmit = MIN_XMIT_PACKET_SIZE;
841         if(config) {
842             config->getValueForSetting("ieee1394.isomanager.min_interrupts_per_period", min_interrupts_per_period);
843             config->getValueForSetting("ieee1394.isomanager.max_nb_buffers_xmit", max_nb_buffers_xmit);
844             config->getValueForSetting("ieee1394.isomanager.max_packetsize_xmit", max_packetsize_xmit);
845             config->getValueForSetting("ieee1394.isomanager.min_packetsize_xmit", min_packetsize_xmit);
846         }
847
848         // setup the optimal parameters for the raw1394 ISO buffering
849         // reserve space for the 1394 header too (might not be necessary)
850         unsigned int max_packet_size = stream->getMaxPacketSize() + 8;
851
852         if (max_packet_size > (unsigned)max_packetsize_xmit) {
853             debugError("max packet size (%u) > MAX_XMIT_PACKET_SIZE (%u)\n",
854                        max_packet_size, max_packetsize_xmit);
855             return false;
856         }
857         if (max_packet_size < (unsigned)min_packetsize_xmit) {
858             debugError("min packet size (%u) < MIN_XMIT_PACKET_SIZE (%u), using min value\n",
859                        max_packet_size, min_packetsize_xmit);
860             max_packet_size = min_packetsize_xmit;
861         }
862
863         int buffers = max_nb_buffers_xmit;
864         unsigned int packets_per_period = stream->getPacketsPerPeriod();
865
866         int irq_interval = (packets_per_period-1) / min_interrupts_per_period;
867         if(irq_interval <= 0) irq_interval=1;
868         // ensure at least 2 hardware interrupts per ISO buffer wraparound
869         if(irq_interval > buffers/2) {
870             irq_interval = buffers/2;
871         }
872
873         debugOutput( DEBUG_LEVEL_VERBOSE, " creating IsoXmitHandler\n");
874
875         // create the actual handler
876         h = new IsoHandler(*this, IsoHandler::eHT_Transmit,
877                            buffers, max_packet_size, irq_interval);
878
879         if(!h) {
880             debugFatal("Could not create IsoXmitHandler\n");
881             return false;
882         }
883
884     } else {
885         debugFatal("Bad stream type\n");
886         return false;
887     }
888
889     h->setVerboseLevel(getDebugLevel());
890
891     // register the stream with the handler
892     if(!h->registerStream(stream)) {
893         debugFatal("Could not register receive stream with handler\n");
894         return false;
895     }
896
897     // register the handler with the manager
898     if(!registerHandler(h)) {
899         debugFatal("Could not register receive handler with manager\n");
900         return false;
901     }
902     debugOutput( DEBUG_LEVEL_VERBOSE, " registered stream (%p) with handler (%p)\n", stream, h);
903
904     m_StreamProcessors.push_back(stream);
905     debugOutput( DEBUG_LEVEL_VERBOSE, " %zd streams, %zd handlers registered\n",
906                                       m_StreamProcessors.size(), m_IsoHandlers.size());
907     return true;
908 }
909
910 bool IsoHandlerManager::unregisterStream(StreamProcessor *stream)
911 {
912     debugOutput( DEBUG_LEVEL_VERBOSE, "Unregistering %s stream %p\n", stream->getTypeString(), stream);
913     assert(stream);
914
915     // make sure the stream isn't attached to a handler anymore
916     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
917       it != m_IsoHandlers.end();
918       ++it )
919     {
920         if((*it)->isStreamRegistered(stream)) {
921             if(!(*it)->unregisterStream(stream)) {
922                 debugOutput( DEBUG_LEVEL_VERBOSE, " could not unregister stream (%p) from handler (%p)...\n",stream,*it);
923                 return false;
924             }
925             debugOutput( DEBUG_LEVEL_VERBOSE, " unregistered stream (%p) from handler (%p)...\n",stream,*it);
926         }
927     }
928
929     // clean up all handlers that aren't used
930     pruneHandlers();
931
932     // remove the stream from the registered streams list
933     for ( StreamProcessorVectorIterator it = m_StreamProcessors.begin();
934       it != m_StreamProcessors.end();
935       ++it )
936     {
937         if ( *it == stream ) {
938             m_StreamProcessors.erase(it);
939             debugOutput( DEBUG_LEVEL_VERBOSE, " deleted stream (%p) from list...\n", *it);
940             return true;
941         }
942     }
943     return false; //not found
944 }
945
946 /**
947  * @brief unregister a handler from the manager
948  * @note called without the lock held.
949  */
950 void IsoHandlerManager::pruneHandlers() {
951     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
952     IsoHandlerVector toUnregister;
953
954     // find all handlers that are not in use
955     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
956           it != m_IsoHandlers.end();
957           ++it )
958     {
959         if(!((*it)->inUse())) {
960             debugOutput( DEBUG_LEVEL_VERBOSE, " handler (%p) not in use\n",*it);
961             toUnregister.push_back(*it);
962         }
963     }
964     // delete them
965     for ( IsoHandlerVectorIterator it = toUnregister.begin();
966           it != toUnregister.end();
967           ++it )
968     {
969         unregisterHandler(*it);
970
971         debugOutput( DEBUG_LEVEL_VERBOSE, " deleting handler (%p)\n",*it);
972
973         // Now the handler's been unregistered it won't be reused
974         // again.  Therefore it really needs to be formally deleted
975         // to free up the raw1394 handle.  Otherwise things fall
976         // apart after several xrun recoveries as the system runs
977         // out of resources to support all the disused but still
978         // allocated raw1394 handles.  At least this is the current
979         // theory as to why we end up with "memory allocation"
980         // failures after several Xrun recoveries.
981         delete *it;
982     }
983 }
984
985 int
986 IsoHandlerManager::getPacketLatencyForStream(Streaming::StreamProcessor *stream) {
987     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
988       it != m_IsoHandlers.end();
989       ++it )
990     {
991         if((*it)->isStreamRegistered(stream)) {
992             return (*it)->getIrqInterval();
993         }
994     }
995     debugError("Stream %p has no attached handler\n", stream);
996     return 0;
997 }
998
999 IsoHandlerManager::IsoHandler *
1000 IsoHandlerManager::getHandlerForStream(Streaming::StreamProcessor *stream) {
1001     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
1002       it != m_IsoHandlers.end();
1003       ++it )
1004     {
1005         if((*it)->isStreamRegistered(stream)) {
1006             return (*it);
1007         }
1008     }
1009     debugError("Stream %p has no attached handler\n", stream);
1010     return NULL;
1011 }
1012
1013 void
1014 IsoHandlerManager::dumpInfoForStream(Streaming::StreamProcessor *stream)
1015 {
1016     IsoHandler *h = getHandlerForStream(stream);
1017     if (h) {
1018         debugOutputShort( DEBUG_LEVEL_NORMAL, "  Packets, Dropped, Skipped : %d, %d, %d\n",
1019                             h->m_packets, h->m_dropped, h->m_skipped);
1020     } else {
1021         debugError("No handler for stream %p??\n", stream);
1022     }
1023 }
1024
1025 void IsoHandlerManager::setIsoStartCycleForStream(Streaming::StreamProcessor *stream, signed int cycle) {
1026     // Permit the direct manipulation of the m_switch_on_cycle field from
1027     // the stream's handler.  This is usually used to set it to -1 so the
1028     // kernel (at least with the ieee1394 stack) starts the streaming as
1029     // soon as possible, something that is required for some interfaces (eg:
1030     // RME).  Note that as of 20 Dec 2010 it seems that ordinarily
1031     // m_switch_on_cycle remains fixed at 0 (its initialised value) because
1032     // requestEnable() doesn't set it.  This allows the override configured
1033     // by this function to take effect.
1034     IsoHandler *h = getHandlerForStream(stream);
1035     h->setIsoStartCycle(cycle);
1036 }
1037
1038 bool
1039 IsoHandlerManager::startHandlerForStream(Streaming::StreamProcessor *stream) {
1040     return startHandlerForStream(stream, -1);
1041 }
1042
1043 bool
1044 IsoHandlerManager::startHandlerForStream(Streaming::StreamProcessor *stream, int cycle) {
1045     // check state
1046     if(m_State != E_Running) {
1047         debugError("Incorrect state, expected E_Running, got %s\n", eHSToString(m_State));
1048         return false;
1049     }
1050     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
1051       it != m_IsoHandlers.end();
1052       ++it )
1053     {
1054         if((*it)->isStreamRegistered(stream)) {
1055             debugOutput( DEBUG_LEVEL_VERBOSE, " starting handler %p for stream %p\n", *it, stream);
1056             if(!(*it)->requestEnable(cycle)) {
1057                 debugOutput( DEBUG_LEVEL_VERBOSE, " could not request enable for handler %p)\n",*it);
1058                 return false;
1059             }
1060
1061             if((*it)->getType() == IsoHandler::eHT_Transmit) {
1062                 m_IsoTaskTransmit->requestShadowMapUpdate();
1063             } else {
1064                 m_IsoTaskReceive->requestShadowMapUpdate();
1065             }
1066
1067             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " requested enable for handler %p\n", *it);
1068             return true;
1069         }
1070     }
1071     debugError("Stream %p has no attached handler\n", stream);
1072     return false;
1073 }
1074
1075 bool
1076 IsoHandlerManager::stopHandlerForStream(Streaming::StreamProcessor *stream) {
1077     // check state
1078     if(m_State != E_Running) {
1079         debugError("Incorrect state, expected E_Running, got %s\n", eHSToString(m_State));
1080         return false;
1081     }
1082     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
1083       it != m_IsoHandlers.end();
1084       ++it )
1085     {
1086         if((*it)->isStreamRegistered(stream)) {
1087             debugOutput( DEBUG_LEVEL_VERBOSE, " stopping handler %p for stream %p\n", *it, stream);
1088             if(!(*it)->requestDisable()) {
1089                 debugOutput( DEBUG_LEVEL_VERBOSE, " could not request disable for handler %p\n",*it);
1090                 return false;
1091             }
1092
1093             if((*it)->getType() == IsoHandler::eHT_Transmit) {
1094                 m_IsoTaskTransmit->requestShadowMapUpdate();
1095             } else {
1096                 m_IsoTaskReceive->requestShadowMapUpdate();
1097             }
1098
1099             debugOutput(DEBUG_LEVEL_VERBOSE, " requested disable for handler %p\n", *it);
1100             return true;
1101         }
1102     }
1103     debugError("Stream %p has no attached handler\n", stream);
1104     return false;
1105 }
1106
1107 bool IsoHandlerManager::stopHandlers() {
1108     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
1109
1110     // check state
1111     if(m_State != E_Running) {
1112         debugError("Incorrect state, expected E_Running, got %s\n", eHSToString(m_State));
1113         return false;
1114     }
1115
1116     bool retval=true;
1117
1118     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
1119         it != m_IsoHandlers.end();
1120         ++it )
1121     {
1122         debugOutput( DEBUG_LEVEL_VERBOSE, "Stopping handler (%p)\n",*it);
1123
1124         if(!(*it)->requestDisable()) {
1125             debugOutput( DEBUG_LEVEL_VERBOSE, " could not request disable for handler %p\n",*it);
1126             return false;
1127         }
1128
1129         if((*it)->getType() == IsoHandler::eHT_Transmit) {
1130             m_IsoTaskTransmit->requestShadowMapUpdate();
1131         } else {
1132             m_IsoTaskReceive->requestShadowMapUpdate();
1133         }
1134
1135         debugOutput(DEBUG_LEVEL_VERBOSE, " requested disable for handler %p\n", *it);
1136     }
1137
1138     if (retval) {
1139         m_State=E_Prepared;
1140     } else {
1141         m_State=E_Error;
1142     }
1143     return retval;
1144 }
1145
1146 bool IsoHandlerManager::reset() {
1147     debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n");
1148     // check state
1149     if(m_State == E_Error) {
1150         debugFatal("Resetting from error condition not yet supported...\n");
1151         return false;
1152     }
1153     // if not in an error condition, reset means stop the handlers
1154     return stopHandlers();
1155 }
1156
1157 void IsoHandlerManager::setVerboseLevel(int i) {
1158     setDebugLevel(i);
1159     // propagate the debug level
1160     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
1161           it != m_IsoHandlers.end();
1162           ++it )
1163     {
1164         (*it)->setVerboseLevel(i);
1165     }
1166     if(m_IsoThreadTransmit) m_IsoThreadTransmit->setVerboseLevel(i);
1167     if(m_IsoTaskTransmit)   m_IsoTaskTransmit->setVerboseLevel(i);
1168     if(m_IsoThreadReceive)  m_IsoThreadReceive->setVerboseLevel(i);
1169     if(m_IsoTaskReceive)    m_IsoTaskReceive->setVerboseLevel(i);
1170     setDebugLevel(i);
1171     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", i );
1172 }
1173
1174 void IsoHandlerManager::dumpInfo() {
1175     #ifdef DEBUG
1176     unsigned int i=0;
1177     debugOutputShort( DEBUG_LEVEL_NORMAL, "Dumping IsoHandlerManager Stream handler information...\n");
1178     debugOutputShort( DEBUG_LEVEL_NORMAL, " State: %d\n",(int)m_State);
1179
1180     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin();
1181           it != m_IsoHandlers.end();
1182           ++it )
1183     {
1184         debugOutputShort( DEBUG_LEVEL_NORMAL, " IsoHandler %d (%p)\n",i++,*it);
1185         (*it)->dumpInfo();
1186     }
1187     #endif
1188 }
1189
1190 const char *
1191 IsoHandlerManager::eHSToString(enum eHandlerStates s) {
1192     switch (s) {
1193         default: return "Invalid";
1194         case E_Created: return "Created";
1195         case E_Prepared: return "Prepared";
1196         case E_Running: return "Running";
1197         case E_Error: return "Error";
1198     }
1199 }
1200
1201
1202 // ISOHANDLER
1203
1204 /* the C callbacks */
1205 enum raw1394_iso_disposition
1206 IsoHandlerManager::IsoHandler::iso_transmit_handler(raw1394handle_t handle,
1207         unsigned char *data, unsigned int *length,
1208         unsigned char *tag, unsigned char *sy,
1209         int cycle, unsigned int dropped1) {
1210
1211     IsoHandler *xmitHandler = static_cast<IsoHandler *>(raw1394_get_userdata(handle));
1212     assert(xmitHandler);
1213     unsigned int skipped = (dropped1 & 0xFFFF0000) >> 16;
1214     unsigned int dropped = dropped1 & 0xFFFF;
1215     return xmitHandler->getPacket(data, length, tag, sy, cycle, dropped, skipped);
1216 }
1217
1218 enum raw1394_iso_disposition
1219 IsoHandlerManager::IsoHandler::iso_receive_handler(raw1394handle_t handle, unsigned char *data,
1220                         unsigned int length, unsigned char channel,
1221                         unsigned char tag, unsigned char sy, unsigned int cycle,
1222                         unsigned int dropped) {
1223
1224     IsoHandler *recvHandler = static_cast<IsoHandler *>(raw1394_get_userdata(handle));
1225     assert(recvHandler);
1226
1227     return recvHandler->putPacket(data, length, channel, tag, sy, cycle, dropped);
1228 }
1229
1230 IsoHandlerManager::IsoHandler::IsoHandler(IsoHandlerManager& manager, enum EHandlerType t)
1231    : m_manager( manager )
1232    , m_type ( t )
1233    , m_handle( NULL )
1234    , m_buf_packets( 400 )
1235    , m_max_packet_size( 1024 )
1236    , m_irq_interval( -1 )
1237    , m_last_cycle( -1 )
1238    , m_last_now( 0xFFFFFFFF )
1239    , m_last_packet_handled_at( 0xFFFFFFFF )
1240    , m_receive_mode ( RAW1394_DMA_PACKET_PER_BUFFER )
1241    , m_Client( 0 )
1242    , m_speed( RAW1394_ISO_SPEED_400 )
1243    , m_State( eHS_Stopped )
1244    , m_NextState( eHS_Stopped )
1245    , m_switch_on_cycle(0)
1246 #ifdef DEBUG
1247    , m_packets ( 0 )
1248    , m_dropped( 0 )
1249    , m_skipped( 0 )
1250    , m_min_ahead( 7999 )
1251 #endif
1252 {
1253     pthread_mutex_init(&m_disable_lock, NULL);
1254 }
1255
1256 IsoHandlerManager::IsoHandler::IsoHandler(IsoHandlerManager& manager, enum EHandlerType t,
1257                        unsigned int buf_packets, unsigned int max_packet_size, int irq)
1258    : m_manager( manager )
1259    , m_type ( t )
1260    , m_handle( NULL )
1261    , m_buf_packets( buf_packets )
1262    , m_max_packet_size( max_packet_size )
1263    , m_irq_interval( irq )
1264    , m_last_cycle( -1 )
1265    , m_last_now( 0xFFFFFFFF )
1266    , m_last_packet_handled_at( 0xFFFFFFFF )
1267    , m_receive_mode ( RAW1394_DMA_PACKET_PER_BUFFER )
1268    , m_Client( 0 )
1269    , m_speed( RAW1394_ISO_SPEED_400 )
1270    , m_State( eHS_Stopped )
1271    , m_NextState( eHS_Stopped )
1272    , m_switch_on_cycle(0)
1273 #ifdef DEBUG
1274    , m_packets ( 0 )
1275    , m_dropped( 0 )
1276    , m_skipped( 0 )
1277    , m_min_ahead( 7999 )
1278 #endif
1279 {
1280 }
1281
1282 IsoHandlerManager::IsoHandler::IsoHandler(IsoHandlerManager& manager, enum EHandlerType t, unsigned int buf_packets,
1283                        unsigned int max_packet_size, int irq,
1284                        enum raw1394_iso_speed speed)
1285    : m_manager( manager )
1286    , m_type ( t )
1287    , m_handle( NULL )
1288    , m_buf_packets( buf_packets )
1289    , m_max_packet_size( max_packet_size )
1290    , m_irq_interval( irq )
1291    , m_last_cycle( -1 )
1292    , m_last_now( 0xFFFFFFFF )
1293    , m_last_packet_handled_at( 0xFFFFFFFF )
1294    , m_receive_mode ( RAW1394_DMA_PACKET_PER_BUFFER )
1295    , m_Client( 0 )
1296    , m_speed( speed )
1297    , m_State( eHS_Stopped )
1298    , m_NextState( eHS_Stopped )
1299    , m_switch_on_cycle(0)
1300 #ifdef DEBUG
1301    , m_packets( 0 )
1302    , m_dropped( 0 )
1303    , m_skipped( 0 )
1304    , m_min_ahead( 7999 )
1305 #endif
1306 {
1307 }
1308
1309 IsoHandlerManager::IsoHandler::~IsoHandler() {
1310 // Don't call until libraw1394's raw1394_new_handle() function has been
1311 // fixed to correctly initialise the iso_packet_infos field.  Bug is
1312 // confirmed present in libraw1394 1.2.1.  In any case,
1313 // raw1394_destroy_handle() will do any iso system shutdown required.
1314 //     raw1394_iso_shutdown(m_handle);
1315
1316 // Typically, by the time this function is called the IsoTask thread would
1317 // have called disable() on the handler (in the FW_ISORCV/FW_ISOXMT
1318 // threads).  However, the raw1394_destroy_handle() call therein takes
1319 // upwards of 20 milliseconds to complete under the new kernel firewire
1320 // stack, and may not have completed by the time ~IsoHandler() is called by
1321 // the "jackd" thread.  Thus, wait for the lock before testing the state
1322 // of the handle so any in-progress disable() is complete.
1323     if (pthread_mutex_trylock(&m_disable_lock) == EBUSY) {
1324         pthread_mutex_lock(&m_disable_lock);
1325         pthread_mutex_unlock(&m_disable_lock);
1326     }
1327     if(m_handle) {
1328         if (m_State == eHS_Running) {
1329             debugError("BUG: Handler still running!\n");
1330             disable();
1331         }
1332     }
1333     pthread_mutex_destroy(&m_disable_lock);
1334 }
1335
1336 bool
1337 IsoHandlerManager::IsoHandler::canIterateClient()
1338 {
1339     debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, "checking...\n");
1340     if(m_Client) {
1341         bool result;
1342
1343         if (m_type == eHT_Receive) {
1344             result = m_Client->canProducePacket();
1345         } else {
1346             result = m_Client->canConsumePacket();
1347         }
1348         debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, " returns %d\n", result);
1349         return result && (m_State != eHS_Error);
1350     } else {
1351         debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, " no client\n");
1352     }
1353     return false;
1354 }
1355
1356 bool
1357 IsoHandlerManager::IsoHandler::iterate() {
1358     return iterate(m_manager.get1394Service().getCycleTimer());
1359 }
1360
1361 bool
1362 IsoHandlerManager::IsoHandler::iterate(uint32_t cycle_timer_now) {
1363     debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, "(%p, %s) Iterating ISO handler at %08X...\n",
1364                        this, getTypeString(), cycle_timer_now);
1365     m_last_now = cycle_timer_now;
1366     if(m_State == eHS_Running) {
1367         assert(m_handle);
1368
1369         #if ISOHANDLER_FLUSH_BEFORE_ITERATE
1370         // this flushes all packets received since the poll() returned
1371         // from kernel to userspace such that they are processed by this
1372         // iterate. Doing so might result in lower latency capability
1373         // and/or better reliability
1374         if(m_type == eHT_Receive) {
1375             raw1394_iso_recv_flush(m_handle);
1376         }
1377         #endif
1378
1379         if(raw1394_loop_iterate(m_handle)) {
1380             debugError( "IsoHandler (%p): Failed to iterate handler: %s\n",
1381                         this, strerror(errno));
1382             return false;
1383         }
1384         debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, "(%p, %s) done interating ISO handler...\n",
1385                            this, getTypeString());
1386         return true;
1387     } else {
1388         debugOutput(DEBUG_LEVEL_VERBOSE, "(%p, %s) Not iterating a non-running handler...\n",
1389                     this, getTypeString());
1390         return false;
1391     }
1392 }
1393
1394 /**
1395  * Bus reset handler
1396  *
1397  * @return ?
1398  */
1399
1400 bool
1401 IsoHandlerManager::IsoHandler::handleBusReset()
1402 {
1403     debugOutput( DEBUG_LEVEL_NORMAL, "bus reset...\n");
1404     m_last_packet_handled_at = 0xFFFFFFFF;
1405
1406     #define CSR_CYCLE_TIME            0x200
1407     #define CSR_REGISTER_BASE  0xfffff0000000ULL
1408     // do a simple read on ourself in order to update the internal structures
1409     // this avoids read failures after a bus reset
1410     quadlet_t buf=0;
1411     raw1394_read(m_handle, raw1394_get_local_id(m_handle),
1412                  CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf);
1413
1414     return m_Client->handleBusReset();
1415 }
1416
1417 /**
1418  * Call this if you find out that this handler has died for some
1419  * external reason.
1420  */
1421 void
1422 IsoHandlerManager::IsoHandler::notifyOfDeath()
1423 {
1424     m_State = eHS_Error;
1425     m_NextState = eHS_Error;
1426
1427     // notify the client of the fact that we have died
1428     m_Client->handlerDied();
1429
1430     // wake ourselves up
1431     if(m_handle) raw1394_wake_up(m_handle);
1432 }
1433
1434 void IsoHandlerManager::IsoHandler::dumpInfo()
1435 {
1436     int channel=-1;
1437     if (m_Client) channel=m_Client->getChannel();
1438
1439     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Handler type................: %s\n",
1440             getTypeString());
1441     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Port, Channel...............: %2d, %2d\n",
1442             m_manager.get1394Service().getPort(), channel);
1443     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Buffer, MaxPacketSize, IRQ..: %4d, %4d, %4d\n",
1444             m_buf_packets, m_max_packet_size, m_irq_interval);
1445     if (this->getType() == eHT_Transmit) {
1446         debugOutputShort( DEBUG_LEVEL_NORMAL, "  Speed ..................: %2d\n",
1447                                             m_speed);
1448         #ifdef DEBUG
1449         debugOutputShort( DEBUG_LEVEL_NORMAL, "  Min ISOXMT bufferfill : %04d\n", m_min_ahead);
1450         #endif
1451     }
1452     #ifdef DEBUG
1453     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Last cycle, dropped.........: %4d, %4u, %4u\n",
1454             m_last_cycle, m_dropped, m_skipped);
1455     #endif
1456
1457 }
1458
1459 void IsoHandlerManager::IsoHandler::setVerboseLevel(int l)
1460 {
1461     setDebugLevel(l);
1462     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
1463 }
1464
1465 bool IsoHandlerManager::IsoHandler::registerStream(StreamProcessor *stream)
1466 {
1467     assert(stream);
1468     debugOutput( DEBUG_LEVEL_VERBOSE, "registering stream (%p)\n", stream);
1469
1470     if (m_Client) {
1471             debugFatal( "Generic IsoHandlers can have only one client\n");
1472             return false;
1473     }
1474     m_Client=stream;
1475     return true;
1476 }
1477
1478 bool IsoHandlerManager::IsoHandler::unregisterStream(StreamProcessor *stream)
1479 {
1480     assert(stream);
1481     debugOutput( DEBUG_LEVEL_VERBOSE, "unregistering stream (%p)\n", stream);
1482
1483     if(stream != m_Client) {
1484             debugFatal( "no client registered\n");
1485             return false;
1486     }
1487     m_Client=0;
1488     return true;
1489 }
1490
1491 // ISO packet interface
1492 enum raw1394_iso_disposition IsoHandlerManager::IsoHandler::putPacket(
1493                     unsigned char *data, unsigned int length,
1494                     unsigned char channel, unsigned char tag, unsigned char sy,
1495                     unsigned int cycle, unsigned int dropped) {
1496     // keep track of dropped cycles
1497     int dropped_cycles = 0;
1498     if (m_last_cycle != (int)cycle && m_last_cycle != -1 && m_manager.m_MissedCyclesOK == false) {
1499         dropped_cycles = diffCycles(cycle, m_last_cycle) - 1;
1500         #ifdef DEBUG
1501         if (dropped_cycles < 0) {
1502             debugWarning("(%p) dropped < 1 (%d), cycle: %d, last_cycle: %d, dropped: %d\n",
1503                          this, dropped_cycles, cycle, m_last_cycle, dropped);
1504         }
1505         if (dropped_cycles > 0) {
1506             debugOutput(DEBUG_LEVEL_VERBOSE,
1507                         "(%p) dropped %d packets on cycle %u, 'dropped'=%u, cycle=%d, m_last_cycle=%d\n",
1508                         this, dropped_cycles, cycle, dropped, cycle, m_last_cycle);
1509             m_dropped += dropped_cycles;
1510         }
1511         #endif
1512     }
1513     m_last_cycle = cycle;
1514
1515     // the m_last_now value is set when the iterate() function is called.
1516     uint32_t now_cycles = CYCLE_TIMER_GET_CYCLES(m_last_now);
1517
1518     // two cases can occur:
1519     // (1) this packet has been received before iterate() was called (normal case).
1520     // (2) this packet has been received after iterate() was called.
1521     //     happens when the kernel flushes more packets while we are already processing.
1522     //
1523     // In case (1) now_cycles is a small number of cycles larger than cycle. In
1524     // case (2) now_cycles is a small number of cycles smaller than cycle.
1525     // hence  abs(diffCycles(now_cycles, cycles)) has to be 'small'
1526
1527     // we can calculate the time of arrival for this packet as
1528     // 'now' + diffCycles(cycles, now_cycles) * TICKS_PER_CYCLE
1529     // in its properly wrapped version
1530     int64_t diff_cycles = diffCycles(cycle, now_cycles);
1531     int64_t tmp = CYCLE_TIMER_TO_TICKS(m_last_now);
1532     tmp += diff_cycles * (int64_t)TICKS_PER_CYCLE;
1533     uint64_t pkt_ctr_ticks = wrapAtMinMaxTicks(tmp);
1534     uint32_t pkt_ctr = TICKS_TO_CYCLE_TIMER(pkt_ctr_ticks);
1535     #ifdef DEBUG
1536     if( (now_cycles < cycle)
1537         && diffCycles(now_cycles, cycle) < 0
1538         // ignore this on dropped cycles, since it's normal
1539         // that now is ahead on the received packets (as we miss packets)
1540         && dropped_cycles == 0)
1541     {
1542         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Special non-unwrapping happened\n");
1543     }
1544     #endif
1545
1546     #if ISOHANDLER_CHECK_CTR_RECONSTRUCTION
1547     // add a seconds field
1548     uint32_t now = m_manager.get1394Service().getCycleTimer();
1549     uint32_t now_secs_ref = CYCLE_TIMER_GET_SECS(now);
1550     // causality results in the fact that 'now' is always after 'cycle'
1551     // or at best, equal (if this handler was called within 125us after
1552     // the packet was on the wire).
1553     if(CYCLE_TIMER_GET_CYCLES(now) < cycle) {
1554         // the cycle field has wrapped, substract one second
1555         if(now_secs_ref == 0) {
1556             now_secs_ref = 127;
1557         } else  {
1558             now_secs_ref -= 1;
1559         }
1560     }
1561     uint32_t pkt_ctr_ref = cycle << 12;
1562     pkt_ctr_ref |= (now_secs_ref & 0x7F) << 25;
1563
1564     if((pkt_ctr & ~0x0FFFL) != pkt_ctr_ref) {
1565         debugWarning("reconstructed CTR counter discrepancy\n");
1566         debugWarning(" ingredients: %X, %X, %X, %X, %X, %d, %ld, %ld, %"PRId64"\n",
1567                      cycle, pkt_ctr_ref, pkt_ctr,
1568                      now, m_last_now, now_secs_ref,
1569                      (long int)CYCLE_TIMER_GET_SECS(now),
1570                      (long int)CYCLE_TIMER_GET_SECS(m_last_now),
1571                      tmp);
1572         debugWarning(" diffcy = %"PRId64" \n", diff_cycles);
1573     }
1574     #endif
1575     m_last_packet_handled_at = pkt_ctr;
1576
1577     // leave the offset field (for now?)
1578
1579     debugOutputExtreme(DEBUG_LEVEL_ULTRA_VERBOSE,
1580                 "received packet: length=%d, channel=%d, cycle=%d, at %08X\n",
1581                 length, channel, cycle, pkt_ctr);
1582     m_packets++;
1583     #ifdef DEBUG
1584     if (length > m_max_packet_size) {
1585         debugWarning("(%p, %s) packet too large: len=%u max=%u\n",
1586                      this, getTypeString(), length, m_max_packet_size);
1587     }
1588     if(m_last_cycle == -1) {
1589         debugOutput(DEBUG_LEVEL_VERBOSE, "Handler for %s SP %p is alive (cycle = %u)\n", getTypeString(), this, cycle);
1590     }
1591     #endif
1592
1593     // iterate the client if required
1594     if(m_Client)
1595         return m_Client->putPacket(data, length, channel, tag, sy, pkt_ctr, dropped_cycles);
1596
1597     return RAW1394_ISO_OK;
1598 }
1599
1600 enum raw1394_iso_disposition
1601 IsoHandlerManager::IsoHandler::getPacket(unsigned char *data, unsigned int *length,
1602                       unsigned char *tag, unsigned char *sy,
1603                       int cycle, unsigned int dropped, unsigned int skipped) {
1604
1605     uint32_t pkt_ctr;
1606     if (cycle < 0) {
1607         // mark invalid
1608         pkt_ctr = 0xFFFFFFFF;
1609     } else {
1610         // the m_last_now value is set when the iterate() function is called.
1611         uint32_t now_cycles = CYCLE_TIMER_GET_CYCLES(m_last_now);
1612
1613         // two cases can occur:
1614         // (1) this packet has been received before iterate() was called (normal case).
1615         // (2) this packet has been received after iterate() was called.
1616         //     happens when the kernel flushes more packets while we are already processing.
1617         //
1618         // In case (1) now_cycles is a small number of cycles larger than cycle. In
1619         // case (2) now_cycles is a small number of cycles smaller than cycle.
1620         // hence  abs(diffCycles(now_cycles, cycles)) has to be 'small'
1621
1622         // we can calculate the time of arrival for this packet as
1623         // 'now' + diffCycles(cycles, now_cycles) * TICKS_PER_CYCLE
1624         // in its properly wrapped version
1625         int64_t diff_cycles = diffCycles(cycle, now_cycles);
1626         int64_t tmp = CYCLE_TIMER_TO_TICKS(m_last_now);
1627         tmp += diff_cycles * (int64_t)TICKS_PER_CYCLE;
1628         uint64_t pkt_ctr_ticks = wrapAtMinMaxTicks(tmp);
1629         pkt_ctr = TICKS_TO_CYCLE_TIMER(pkt_ctr_ticks);
1630
1631         #if ISOHANDLER_CHECK_CTR_RECONSTRUCTION
1632         // add a seconds field
1633         uint32_t now = m_manager.get1394Service().getCycleTimer();
1634         uint32_t now_secs_ref = CYCLE_TIMER_GET_SECS(now);
1635         // causality results in the fact that 'now' is always after 'cycle'
1636         if(CYCLE_TIMER_GET_CYCLES(now) > (unsigned int)cycle) {
1637             // the cycle field has wrapped, add one second
1638             now_secs_ref += 1;
1639             // no need for this:
1640             if(now_secs_ref == 128) {
1641                now_secs_ref = 0;
1642             }
1643         }
1644         uint32_t pkt_ctr_ref = cycle << 12;
1645         pkt_ctr_ref |= (now_secs_ref & 0x7F) << 25;
1646
1647         if(((pkt_ctr & ~0x0FFFL) != pkt_ctr_ref) && (m_packets > m_buf_packets)) {
1648             debugWarning("reconstructed CTR counter discrepancy\n");
1649             debugWarning(" ingredients: %X, %X, %X, %X, %X, %d, %ld, %ld, %"PRId64"\n",
1650                         cycle, pkt_ctr_ref, pkt_ctr,
1651                          now, m_last_now, now_secs_ref,
1652                          (long int)CYCLE_TIMER_GET_SECS(now),
1653                          (long int)CYCLE_TIMER_GET_SECS(m_last_now),
1654                          tmp);
1655             debugWarning(" diffcy = %"PRId64" \n", diff_cycles);
1656         }
1657         #endif
1658     }
1659     if (m_packets < m_buf_packets) { // these are still prebuffer packets
1660         m_last_packet_handled_at = 0xFFFFFFFF;
1661     } else {
1662         m_last_packet_handled_at = pkt_ctr;
1663     }
1664     debugOutputExtreme(DEBUG_LEVEL_ULTRA_VERBOSE,
1665                 "sending packet: length=%d, cycle=%d, at %08X\n",
1666                 *length, cycle, pkt_ctr);
1667
1668     m_packets++;
1669
1670     #ifdef DEBUG
1671     if(m_last_cycle == -1) {
1672         debugOutput(DEBUG_LEVEL_VERBOSE, "Handler for %s SP %p is alive. cycle=%d state=%i\n", getTypeString(), this, cycle, m_State);
1673     }
1674     #endif
1675
1676     // keep track of dropped cycles
1677     int dropped_cycles = 0;
1678     if (m_last_cycle != cycle && m_last_cycle != -1) {
1679         dropped_cycles = diffCycles(cycle, m_last_cycle) - 1;
1680         // correct for skipped packets
1681         // since those are not dropped, but only delayed
1682         dropped_cycles -= skipped;
1683
1684         #ifdef DEBUG
1685         if(skipped) {
1686             debugOutput(DEBUG_LEVEL_VERY_VERBOSE,
1687                         "(%p) skipped %d cycles, cycle: %d, last_cycle: %d, dropped: %d\n",
1688                         this, skipped, cycle, m_last_cycle, dropped);
1689             m_skipped += skipped;
1690         }
1691         if (dropped_cycles < 0) {
1692             debugWarning("(%p) dropped < 1 (%d), cycle: %d, last_cycle: %d, dropped: %d, skipped: %d\n",
1693                          this, dropped_cycles, cycle, m_last_cycle, dropped, skipped);
1694         }
1695         if (dropped_cycles > 0) {
1696             debugOutput(DEBUG_LEVEL_VERBOSE,
1697                         "(%p) dropped %d packets on cycle %u (last_cycle=%u, dropped=%d, skipped: %d)\n",
1698                         this, dropped_cycles, cycle, m_last_cycle, dropped, skipped);
1699             m_dropped += dropped_cycles - skipped;
1700         }
1701         #endif
1702     }
1703     if (cycle >= 0) {
1704         m_last_cycle = cycle;
1705        
1706         #ifdef DEBUG
1707 /*        int ahead = diffCycles(cycle, now_cycles);
1708         if (ahead < m_min_ahead) m_min_ahead = ahead;
1709 */
1710         #endif
1711     }
1712
1713     #ifdef DEBUG
1714     if (dropped > 0) {
1715         debugOutput(DEBUG_LEVEL_VERBOSE,
1716                     "(%p) OHCI issue on cycle %u (dropped_cycles=%d, last_cycle=%u, dropped=%d, skipped: %d)\n",
1717                     this, cycle, dropped_cycles, m_last_cycle, dropped, skipped);
1718     }
1719     #endif
1720
1721     if(m_Client) {
1722         enum raw1394_iso_disposition retval;
1723         retval = m_Client->getPacket(data, length, tag, sy, pkt_ctr, dropped_cycles, skipped, m_max_packet_size);
1724         #ifdef DEBUG
1725         if (*length > m_max_packet_size) {
1726             debugWarning("(%p, %s) packet too large: len=%u max=%u\n",
1727                          this, getTypeString(), *length, m_max_packet_size);
1728         }
1729         #endif
1730             return retval;
1731     }
1732
1733     *tag = 0;
1734     *sy = 0;
1735     *length = 0;
1736     return RAW1394_ISO_OK;
1737 }
1738
1739 bool
1740 IsoHandlerManager::IsoHandler::enable(int cycle)
1741 {
1742     debugOutput( DEBUG_LEVEL_VERBOSE, "start on cycle %d\n", cycle);
1743
1744     // check the state
1745     if(m_State != eHS_Stopped) {
1746         debugError("Incorrect state, expected eHS_Stopped, got %d\n",(int)m_State);
1747         return false;
1748     }
1749
1750     assert(m_handle == NULL);
1751
1752     // create a handle for the ISO traffic
1753     m_handle = raw1394_new_handle_on_port( m_manager.get1394Service().getPort() );
1754     if ( !m_handle ) {
1755         if ( !errno ) {
1756             debugError("libraw1394 not compatible\n");
1757         } else {
1758             debugError("Could not get 1394 handle: %s\n", strerror(errno) );
1759             debugError("Are ieee1394 and raw1394 drivers loaded?\n");
1760         }
1761         return false;
1762     }
1763     raw1394_set_userdata(m_handle, static_cast<void *>(this));
1764
1765     // prepare the handler, allocate the resources
1766     debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing iso handler (%p, client=%p)\n", this, m_Client);
1767     dumpInfo();
1768     if (getType() == eHT_Receive) {
1769         if(raw1394_iso_recv_init(m_handle,
1770                                 iso_receive_handler,
1771                                 m_buf_packets,
1772                                 m_max_packet_size,
1773                                 m_Client->getChannel(),
1774                                 m_receive_mode,
1775                                 m_irq_interval)) {
1776             debugFatal("Could not do receive initialization (PACKET_PER_BUFFER)!\n" );
1777             debugFatal("  %s\n",strerror(errno));
1778             return false;
1779         }
1780
1781         if(raw1394_iso_recv_start(m_handle, cycle, -1, 0)) {
1782             debugFatal("Could not start receive handler (%s)\n",strerror(errno));
1783             dumpInfo();
1784             return false;
1785         }
1786     } else {
1787         if(raw1394_iso_xmit_init(m_handle,
1788                                 iso_transmit_handler,
1789                                 m_buf_packets,
1790                                 m_max_packet_size,
1791                                 m_Client->getChannel(),
1792                                 m_speed,
1793                                 m_irq_interval)) {
1794             debugFatal("Could not do xmit initialisation!\n" );
1795             return false;
1796         }
1797
1798         if(raw1394_iso_xmit_start(m_handle, cycle, 0)) {
1799             debugFatal("Could not start xmit handler (%s)\n", strerror(errno));
1800             dumpInfo();
1801             return false;
1802         }
1803     }
1804
1805 #ifdef DEBUG
1806     m_min_ahead = 7999;
1807 #endif
1808
1809     m_packets = 0;
1810
1811     // indicate that the first iterate() still has to occur.
1812     m_last_now = 0xFFFFFFFF;
1813     m_last_packet_handled_at = 0xFFFFFFFF;
1814
1815     m_State = eHS_Running;
1816     m_NextState = eHS_Running;
1817     return true;
1818 }
1819
1820 bool
1821 IsoHandlerManager::IsoHandler::disable()
1822 {
1823     signed int i, have_lock = 0;
1824
1825     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p, %s) enter...\n",
1826                  this, (m_type==eHT_Receive?"Receive":"Transmit"));
1827
1828     i = pthread_mutex_trylock(&m_disable_lock);
1829     if (i == 0)
1830         have_lock = 1;
1831     else
1832     if (i == EBUSY) {
1833         // Some other thread is disabling this handler, a process which can
1834         // take considerable time when using the new kernel firewire stack.
1835         // Wait until it is finished before returning so the present caller
1836         // can act knowing that the disable has occurred and is complete
1837         // (which is what normally would be expected).
1838         debugOutput( DEBUG_LEVEL_VERBOSE, "waiting for disable lock\n");
1839         pthread_mutex_lock(&m_disable_lock);
1840         debugOutput( DEBUG_LEVEL_VERBOSE, "now have disable lock\n");
1841         if (m_State == eHS_Stopped) {
1842             debugOutput( DEBUG_LEVEL_VERBOSE, "another disable() has completed\n");
1843             pthread_mutex_unlock(&m_disable_lock);
1844             return true;
1845         }
1846         have_lock = 1;
1847     }
1848
1849     // check state
1850     if(m_State != eHS_Running) {
1851         debugError("Incorrect state, expected eHS_Running, got %d\n",(int)m_State);
1852         if (have_lock)
1853             pthread_mutex_unlock(&m_disable_lock);
1854         return false;
1855     }
1856
1857     assert(m_handle != NULL);
1858
1859     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p, %s) wake up handle...\n",
1860                  this, (m_type==eHT_Receive?"Receive":"Transmit"));
1861
1862     // wake up any waiting reads/polls
1863     raw1394_wake_up(m_handle);
1864
1865     // this is put here to try and avoid the
1866     // Runaway context problem
1867     // don't know if it will help though.
1868 /*    if(m_State != eHS_Error) { // if the handler is dead, this might block forever
1869         raw1394_iso_xmit_sync(m_handle);
1870     }*/
1871     debugOutput( DEBUG_LEVEL_VERBOSE, "(%p, %s) stop...\n",
1872                  this, (m_type==eHT_Receive?"Receive":"Transmit"));
1873
1874     // stop iso traffic
1875     raw1394_iso_stop(m_handle);
1876     // deallocate resources
1877
1878     // Don't call until libraw1394's raw1394_new_handle() function has been
1879     // fixed to correctly initialise the iso_packet_infos field.  Bug is
1880     // confirmed present in libraw1394 1.2.1.
1881     raw1394_iso_shutdown(m_handle);
1882
1883     // When running on the new kernel firewire stack, this call can take of
1884     // the order of 20 milliseconds to return, in which time other threads
1885     // may wish to test the state of the handler and call this function
1886     // themselves.  The m_disable_lock mutex is used to work around this.
1887     raw1394_destroy_handle(m_handle);
1888     m_handle = NULL;
1889
1890     m_State = eHS_Stopped;
1891     m_NextState = eHS_Stopped;
1892
1893     if (have_lock)
1894         pthread_mutex_unlock(&m_disable_lock);
1895     return true;
1896 }
1897
1898 // functions to request enable or disable at the next opportunity
1899 bool
1900 IsoHandlerManager::IsoHandler::requestEnable(int cycle)
1901 {
1902     if (m_State == eHS_Running) {
1903         debugError("Enable requested on enabled stream '%s'\n", getTypeString());
1904         return false;
1905     }
1906     if (m_State != eHS_Stopped) {
1907         debugError("Enable requested on stream '%s' with state: %d\n", getTypeString(), m_State);
1908         return false;
1909     }
1910     m_NextState = eHS_Running;
1911     return true;
1912 }
1913
1914 bool
1915 IsoHandlerManager::IsoHandler::requestDisable()
1916 {
1917     if (m_State == eHS_Stopped) {
1918         // Don't treat this as an error condition because during a user
1919         // shutdown the stream would have been disabled by
1920         // stopHandlerForStream().  Therefore when requestDisable() is
1921         // subnsequently called by IsoHandlerManager::stopHandlers() in the
1922         // IsoHandlerManager destructor with the stream disabled the
1923         // condition is not an error.
1924         //
1925         // For now print a warning, but this might be removed in future if
1926         // the above framework remains in place.
1927         debugWarning("Disable requested on disabled stream\n");
1928         return true;
1929     }
1930     if (m_State != eHS_Running) {
1931         debugError("Disable requested on stream with state=%d\n", m_State);
1932         return false;
1933     }
1934     m_NextState = eHS_Stopped;
1935     return true;
1936 }
1937
1938 // Explicitly preset m_switch_on_cycle since requestEnable doesn't do this
1939 // and thus all enables requested via that route always occur on cycle 0.
1940 void
1941 IsoHandlerManager::IsoHandler::setIsoStartCycle(signed int cycle)
1942 {
1943   m_switch_on_cycle = cycle;
1944 }
1945
1946 void
1947 IsoHandlerManager::IsoHandler::updateState()
1948 {
1949     // execute state changes requested
1950     if(m_State != m_NextState) {
1951         debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) handler needs state update from %d => %d\n", this, m_State, m_NextState);
1952         if(m_State == eHS_Stopped && m_NextState == eHS_Running) {
1953             debugOutput(DEBUG_LEVEL_VERBOSE, "handler has to be enabled\n");
1954             enable(m_switch_on_cycle);
1955         } else if(m_State == eHS_Running && m_NextState == eHS_Stopped) {
1956             debugOutput(DEBUG_LEVEL_VERBOSE, "handler has to be disabled\n");
1957             disable();
1958         } else {
1959             debugError("Unknown state transition\n");
1960         }
1961     }
1962 }
1963
1964 /**
1965  * @brief convert a EHandlerType to a string
1966  * @param t the type
1967  * @return a char * describing the state
1968  */
1969 const char *
1970 IsoHandlerManager::IsoHandler::eHTToString(enum EHandlerType t) {
1971     switch (t) {
1972         case eHT_Receive: return "Receive";
1973         case eHT_Transmit: return "Transmit";
1974         default: return "error: unknown type";
1975     }
1976 }
Note: See TracBrowser for help on using the browser.