root/trunk/libffado/src/libieee1394/IsoHandler.h

Revision 1005, 5.5 kB (checked in by ppalmers, 13 years ago)

Improve thread synchronisation. Switch back to separate threads for transmit and
receive since it is not possible to statically schedule things properly. One
of the threads (i.e. the client thread) is out of our control, hence it's
execution can't be controlled. Using separate threads and correct priorities
will shift this problem to the OS. Note that the priority of the packet
receive thread should be lower than the client thread (such that the client
thread is woken ASAP), and the priority of the transmit thread should be
higher than the client thread (such that packets are queued ASAP).
Extra benefit: multi-cores are used.

Some other startup improvements.

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_ISOHANDLER__
25 #define __FFADO_ISOHANDLER__
26
27 #include "debugmodule/debugmodule.h"
28
29 #include "libutil/Thread.h"
30
31 enum raw1394_iso_disposition;
32
33 class IsoHandlerManager;
34 namespace Streaming {
35     class StreamProcessor;
36 }
37
38 /*!
39 \brief The Base Class for ISO Handlers
40
41  These classes perform the actual ISO communication through libraw1394.
42  They are different from Streaming::StreamProcessors because one handler can provide multiple
43  streams with packets in case of ISO multichannel receive.
44
45 */
46
47 class IsoHandler
48 {
49 public:
50     enum EHandlerType {
51             eHT_Receive,
52             eHT_Transmit
53     };
54     IsoHandler(IsoHandlerManager& manager, enum EHandlerType t);
55     IsoHandler(IsoHandlerManager& manager, enum EHandlerType t,
56                unsigned int buf_packets, unsigned int max_packet_size, int irq);
57     IsoHandler(IsoHandlerManager& manager, enum EHandlerType t,
58                unsigned int buf_packets, unsigned int max_packet_size, int irq, enum raw1394_iso_speed speed);
59     ~IsoHandler();
60
61 private: // the ISO callback interface
62     static enum raw1394_iso_disposition
63     iso_receive_handler(raw1394handle_t handle, unsigned char *data,
64                         unsigned int length, unsigned char channel,
65                         unsigned char tag, unsigned char sy, unsigned int cycle,
66                         unsigned int dropped);
67
68     enum raw1394_iso_disposition
69             putPacket(unsigned char *data, unsigned int length,
70                         unsigned char channel, unsigned char tag, unsigned char sy,
71                         unsigned int cycle, unsigned int dropped, unsigned int skipped);
72
73     static enum raw1394_iso_disposition iso_transmit_handler(raw1394handle_t handle,
74                     unsigned char *data, unsigned int *length,
75                     unsigned char *tag, unsigned char *sy,
76                     int cycle, unsigned int dropped);
77     enum raw1394_iso_disposition
78             getPacket(unsigned char *data, unsigned int *length,
79                     unsigned char *tag, unsigned char *sy,
80                     int cycle, unsigned int dropped, unsigned int skipped);
81
82 public:
83     // runnable interface
84     bool iterate();
85
86     int getFileDescriptor() { return raw1394_get_fd(m_handle);};
87
88     bool init();
89     bool prepare();
90
91     void setVerboseLevel(int l);
92
93     bool enable() {return enable(-1);};
94     bool enable(int cycle);
95     bool disable();
96
97     void flush();
98     enum EHandlerType getType() {return m_type;};
99     const char *getTypeString() {return eHTToString(m_type); };
100
101     // pretty printing
102     const char *eHTToString(enum EHandlerType);
103
104     bool isEnabled()
105         {return m_State == E_Running;};
106
107     // no setter functions, because those would require a re-init
108     unsigned int getMaxPacketSize() { return m_max_packet_size;};
109     unsigned int getNbBuffers() { return m_buf_packets;};
110     int getPacketLatency() { return m_irq_interval;};
111
112     unsigned int getPreBuffers() {return m_prebuffers;};
113     void setPreBuffers(unsigned int n) {m_prebuffers=n;};
114
115     void dumpInfo();
116
117     bool inUse() {return (m_Client != 0) ;};
118     bool isStreamRegistered(Streaming::StreamProcessor *s) {return (m_Client == s);};
119
120     bool registerStream(Streaming::StreamProcessor *);
121     bool unregisterStream(Streaming::StreamProcessor *);
122
123     bool canIterateClient(); // FIXME: implement with functor
124
125     /**
126      * @brief request that the handler exits the packet processing loop ASAP
127      *
128      * The raw1394 lib doesn't provide a means to stop the packet iteration loop
129      * except when the iterate callback returns a DEFER value. Calling this function
130      * will make the callback return DEFER ASAP.
131      */
132     void requestIterateLoopExit() {m_dont_exit_iterate_loop = false;};
133     /**
134      * @brief allow the handler to stay in the packet processing loop
135      *
136      * This resets the state set by requestIterateLoopExit()
137      */
138     void allowIterateLoop() {m_dont_exit_iterate_loop = true;};
139
140 private:
141     IsoHandlerManager& m_manager;
142     enum EHandlerType m_type;
143     raw1394handle_t m_handle;
144     unsigned int    m_buf_packets;
145     unsigned int    m_max_packet_size;
146     int             m_irq_interval;
147
148     Streaming::StreamProcessor *m_Client; // FIXME: implement with functors
149
150     int handleBusReset(unsigned int generation);
151
152     static int busreset_handler(raw1394handle_t handle, unsigned int generation);
153
154     enum raw1394_iso_speed m_speed;
155     unsigned int m_prebuffers;
156     bool m_dont_exit_iterate_loop;
157
158     // the state machine
159     enum EHandlerStates {
160         E_Created,
161         E_Initialized,
162         E_Prepared,
163         E_Running,
164         E_Error
165     };
166     enum EHandlerStates m_State;
167
168     #ifdef DEBUG
169     int             m_packets;
170     #endif
171
172     DECLARE_DEBUG_MODULE;
173 };
174
175 #endif /* __FFADO_ISOHANDLER__  */
176
177
178
Note: See TracBrowser for help on using the browser.