root/branches/libffado-2.0/src/libieee1394/IsoHandlerManager.h

Revision 1372, 7.8 kB (checked in by ppalmers, 12 years ago)

Host controller reliability changes:

  • make receive DMA mode selectable (but still hardcoded ATM). Some controllers seem to work better in bufferfill mode.
  • introduce a maximum number of ISO buffers for receive, lower the max nb of ISO buffers for xmit
  • make the number of buffers for receive and transmit a power of two
  • ensure at least two hardware interrupts per complete ISO buffer wraparound
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 #ifndef __FFADO_ISOHANDLERMANAGER__
25 #define __FFADO_ISOHANDLERMANAGER__
26
27 #include "config.h"
28 #include "debugmodule/debugmodule.h"
29
30 #include "libutil/Thread.h"
31
32 #include "IsoHandler.h"
33
34 #include <sys/poll.h>
35 #include <errno.h>
36 #include <vector>
37 #include <semaphore.h>
38
39 class Ieee1394Service;
40 //class IsoHandler;
41 //enum IsoHandler::EHandlerType;
42
43 namespace Streaming {
44     class StreamProcessor;
45     typedef std::vector<StreamProcessor *> StreamProcessorVector;
46     typedef std::vector<StreamProcessor *>::iterator StreamProcessorVectorIterator;
47 }
48
49 typedef std::vector<IsoHandler *> IsoHandlerVector;
50 typedef std::vector<IsoHandler *>::iterator IsoHandlerVectorIterator;
51
52 class IsoHandlerManager;
53
54 // threads that will handle the packet framing
55 // one thread per direction, as a compromise for one per
56 // channel and one for all
57 class IsoTask : public Util::RunnableInterface
58 {
59     public:
60         IsoTask(IsoHandlerManager& manager, enum IsoHandler::EHandlerType);
61         virtual ~IsoTask();
62
63     public:
64         bool Init();
65         bool Execute();
66
67         /**
68          * @brief requests the thread to sync it's stream map with the manager
69          */
70         bool requestShadowMapUpdate();
71         enum eActivityResult {
72             eAR_Activity,
73             eAR_Timeout,
74             eAR_Interrupted,
75             eAR_Error
76         };
77
78         /**
79          * @brief signals that something happened in one of the clients of this task
80          */
81         void signalActivity();
82         /**
83          * @brief wait until something happened in one of the clients of this task
84          */
85         enum eActivityResult waitForActivity();
86
87         /**
88          * @brief This should be called when a busreset has happened.
89          */
90         bool handleBusReset();
91
92         void setVerboseLevel(int i);
93     protected:
94         IsoHandlerManager& m_manager;
95
96         // the event request structure
97         int32_t request_update;
98
99         // static allocation due to RT constraints
100         // this is the map used by the actual thread
101         // it is a shadow of the m_StreamProcessors vector
102         struct pollfd   m_poll_fds_shadow[ISOHANDLERMANAGER_MAX_ISO_HANDLERS_PER_PORT];
103         IsoHandler *    m_IsoHandler_map_shadow[ISOHANDLERMANAGER_MAX_ISO_HANDLERS_PER_PORT];
104         unsigned int    m_poll_nfds_shadow;
105         IsoHandler *    m_SyncIsoHandler;
106
107         // updates the streams map
108         void updateShadowMapHelper();
109
110 #ifdef DEBUG
111         uint64_t m_last_loop_entry;
112         int m_successive_short_loops;
113 #endif
114
115         // activity signaling
116         sem_t m_activity_semaphore;
117
118         enum IsoHandler::EHandlerType m_handlerType;
119         bool m_running;
120         bool m_in_busreset;
121
122         // debug stuff
123         DECLARE_DEBUG_MODULE;
124 };
125
126 /*!
127 \brief The ISO Handler management class
128
129  This class manages the use of ISO handlers by ISO streams.
130  You can register an Streaming::StreamProcessor with an IsoHandlerManager. This
131  manager will assign an IsoHandler to the stream. If nescessary
132  the manager allocates a new handler. If there is already a handler
133  that can handle the Streaming::StreamProcessor (e.g. in case of multichannel receive),
134  it can be assigned.
135
136 */
137
138 class IsoHandlerManager
139 {
140     friend class IsoTask;
141
142     public:
143
144         IsoHandlerManager(Ieee1394Service& service);
145         IsoHandlerManager(Ieee1394Service& service, bool run_rt, int rt_prio);
146         virtual ~IsoHandlerManager();
147
148         bool setThreadParameters(bool rt, int priority);
149
150         void setVerboseLevel(int l); ///< set the verbose level
151
152         void dumpInfo(); ///< print some information about the manager to stdout/stderr
153
154         bool registerStream(Streaming::StreamProcessor *); ///< register an iso stream with the manager
155         bool unregisterStream(Streaming::StreamProcessor *); ///< unregister an iso stream from the manager
156
157         bool startHandlers(); ///< start the managed ISO handlers
158         bool startHandlers(int cycle); ///< start the managed ISO handlers
159         bool stopHandlers(); ///< stop the managed ISO handlers
160
161         bool reset(); ///< reset the ISO manager and all streams
162         bool init();
163
164         bool disable(IsoHandler *); ///< disables a handler
165         bool enable(IsoHandler *); ///< enables a handler
166
167         /**
168          * @brief signals that something happened in one of the clients
169          */
170         void signalActivityTransmit();
171         void signalActivityReceive();
172
173         ///> disables the handler attached to the stream
174         bool stopHandlerForStream(Streaming::StreamProcessor *);
175         ///> starts the handler attached to the specific stream
176         bool startHandlerForStream(Streaming::StreamProcessor *);
177         ///> starts the handler attached to the specific stream on a specific cycle
178         bool startHandlerForStream(Streaming::StreamProcessor *, int cycle);
179
180         /**
181          * returns the latency of a wake-up for this stream.
182          * The latency is the time it takes for a packet is delivered to the
183          * stream after it has been received (was on the wire).
184          * expressed in cycles
185          */
186         int getPacketLatencyForStream(Streaming::StreamProcessor *);
187
188         void flushHandlerForStream(Streaming::StreamProcessor *stream);
189         IsoHandler * getHandlerForStream(Streaming::StreamProcessor *stream);
190
191         Ieee1394Service& get1394Service() {return m_service;};
192
193         void requestShadowMapUpdate();
194
195         /**
196          * This should be called when a busreset has happened.
197          */
198         bool handleBusReset();
199
200         /**
201          * @brief set iso receive mode. doesn't have any effect if the stream is running
202          * @param m receive mode
203          */
204         void setReceiveMode(enum raw1394_iso_dma_recv_mode m)
205             {m_receive_mode = m;}
206
207     // the state machine
208     private:
209         enum eHandlerStates {
210             E_Created,
211             E_Prepared,
212             E_Running,
213             E_Error
214         };
215
216         enum eHandlerStates m_State;
217         const char *eHSToString(enum eHandlerStates);
218
219     private:
220         Ieee1394Service&  m_service;
221         // note: there is a disctinction between streams and handlers
222         // because one handler can serve multiple streams (in case of
223         // multichannel receive)
224
225         // only streams are allowed to be registered externally.
226         // we allocate a handler if we need one, otherwise the stream
227         // is assigned to another handler
228
229         // the collection of handlers
230         IsoHandlerVector m_IsoHandlers;
231
232         bool registerHandler(IsoHandler *);
233         bool unregisterHandler(IsoHandler *);
234         void pruneHandlers();
235
236         // the collection of streams
237         Streaming::StreamProcessorVector m_StreamProcessors;
238
239         // handler thread/task
240         bool            m_realtime;
241         int             m_priority;
242         Util::Thread *  m_IsoThreadTransmit;
243         IsoTask *       m_IsoTaskTransmit;
244         Util::Thread *  m_IsoThreadReceive;
245         IsoTask *       m_IsoTaskReceive;
246         enum raw1394_iso_dma_recv_mode m_receive_mode;
247
248         // debug stuff
249         DECLARE_DEBUG_MODULE;
250
251 };
252
253 #endif /* __FFADO_ISOHANDLERMANAGER__  */
254
255
256
Note: See TracBrowser for help on using the browser.