root/trunk/libffado/src/debugmodule/debugmodule.h

Revision 777, 10.7 kB (checked in by ppalmers, 16 years ago)

port freebob SSE optimized event encoding functions (untested)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*
2  * Copyright (C) 2005-2007 by Daniel Wagner
3  * Copyright (C) 2005-2007 by Pieter Palmers
4  *
5  * This file is part of FFADO
6  * FFADO = Free Firewire (pro-)audio drivers for linux
7  *
8  * FFADO is based upon FreeBoB
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  */
24
25 #ifndef DEBUGMODULE_H
26 #define DEBUGMODULE_H
27
28 #include "../fbtypes.h"
29 #include <assert.h>
30
31 #include <vector>
32 #include <iostream>
33
34 typedef short debug_level_t;
35
36 #define DEBUG_LEVEL_MESSAGE        0
37 #define DEBUG_LEVEL_FATAL          1
38 #define DEBUG_LEVEL_ERROR          2
39 #define DEBUG_LEVEL_WARNING        3
40 #define DEBUG_LEVEL_NORMAL         4
41 #define DEBUG_LEVEL_INFO           5
42 #define DEBUG_LEVEL_VERBOSE        6
43 #define DEBUG_LEVEL_VERY_VERBOSE   7
44 #define DEBUG_LEVEL_ULTRA_VERBOSE  8
45
46 #define DEBUG_MAX_MESSAGE_LENGTH 512
47
48 /* MB_NEXT() relies on the fact that MB_BUFFERS is a power of two */
49 #define MB_BUFFERS          (1<<16)
50
51 #define MB_NEXT(index)      (((index)+1) & (MB_BUFFERS-1))
52
53 #define MB_BUFFERSIZE       DEBUG_MAX_MESSAGE_LENGTH
54
55 #ifdef DEBUG
56  #define IMPLEMENT_BACKLOG
57 #endif
58
59 #ifdef IMPLEMENT_BACKLOG
60 // the backlog is a similar buffer as the message buffer
61 #define BACKLOG_MB_BUFFERS      (256)
62 #define BACKLOG_MB_NEXT(index)  (((index)+1) & (BACKLOG_MB_BUFFERS-1))
63 #define BACKLOG_MIN_LEVEL       DEBUG_LEVEL_VERY_VERBOSE
64 #endif
65
66 #define debugFatal( format, args... )                               \
67                 m_debugModule.print( DebugModule::eDL_Fatal,        \
68                                      __FILE__,                      \
69                                      __FUNCTION__,                  \
70                                      __LINE__,                      \
71                                      format,                        \
72                                      ##args )
73 #define debugError( format, args... )                               \
74                 m_debugModule.print( DebugModule::eDL_Error,        \
75                                      __FILE__,                      \
76                                      __FUNCTION__,                  \
77                                      __LINE__,                      \
78                                      format,                        \
79                                      ##args )
80 #define debugWarning( format, args... )                             \
81                 m_debugModule.print( DebugModule::eDL_Warning,      \
82                                      __FILE__,                      \
83                                      __FUNCTION__,                  \
84                                      __LINE__,                      \
85                                     format,                         \
86                                     ##args )
87
88 #define debugFatalShort( format, args... )                          \
89                 m_debugModule.printShort( DebugModule::eDL_Fatal,   \
90                                      format,                        \
91                                      ##args )
92 #define debugErrorShort( format, args... )                          \
93                 m_debugModule.printShort( DebugModule::eDL_Error,   \
94                                      format,                        \
95                                      ##args )
96 #define debugWarningShort( format, args... )                        \
97                 m_debugModule.printShort( DebugModule::eDL_Warning, \
98                                      format,                        \
99                                      ##args )
100
101 // these are for messages that are also displayed when not compiled
102 // for debug
103 #define printMessage( format, args... )                             \
104                 m_debugModule.print( DebugModule::eDL_Message,      \
105                                      __FILE__,                      \
106                                      __FUNCTION__,                  \
107                                      __LINE__,                      \
108                                     format,                         \
109                                     ##args )
110 #define printMessageShort( format, args... )                        \
111                 m_debugModule.printShort( DebugModule::eDL_Message, \
112                                      format,                        \
113                                      ##args )
114
115 #define DECLARE_DEBUG_MODULE static DebugModule m_debugModule
116 #define IMPL_DEBUG_MODULE( ClassName, RegisterName, Level )        \
117                 DebugModule ClassName::m_debugModule =             \
118                     DebugModule( #RegisterName, Level )
119
120 #define DECLARE_GLOBAL_DEBUG_MODULE extern DebugModule m_debugModule
121 #define IMPL_GLOBAL_DEBUG_MODULE( RegisterName, Level )            \
122                 DebugModule m_debugModule =                        \
123             DebugModule( #RegisterName, Level )
124
125 #define setDebugLevel( Level ) {                                    \
126                 m_debugModule.setLevel( Level ); \
127                 }
128
129 /*                m_debugModule.print( eDL_Normal,                        \
130                                      __FILE__,                     \
131                                      __FUNCTION__,                 \
132                                      __LINE__,                     \
133                                      "Setting debug level to %d\n",  \
134                                      Level ); \
135                 }*/
136
137 #define getDebugLevel(  )                                     \
138                 m_debugModule.getLevel( )
139
140 #define flushDebugOutput()      DebugModuleManager::instance()->flush()
141
142 #ifdef IMPLEMENT_BACKLOG
143
144 #define debugShowBackLog()          DebugModuleManager::instance()->showBackLog()
145 #define debugShowBackLogLines(x)    DebugModuleManager::instance()->showBackLog(x)
146
147 #else
148 #define debugShowBackLog()
149 #define debugShowBackLogLines(x)
150
151 #endif
152
153 #ifdef DEBUG
154
155     #define debugOutput( level, format, args... )                  \
156                 m_debugModule.print( level,                        \
157                                      __FILE__,                     \
158                                      __FUNCTION__,                 \
159                                      __LINE__,                     \
160                                      format,                       \
161                                      ##args )
162
163     #define debugOutputShort( level, format, args... )             \
164                 m_debugModule.printShort( level,                   \
165                                      format,                       \
166                                      ##args )
167
168 #else
169
170     #define debugOutput( level, format, args... )
171     #define debugOutputShort( level, format, args... )
172
173 #endif
174
175 /* Enable preemption checking for Linux Realtime Preemption kernels.
176  *
177  * This checks if any RT-safe code section does anything to cause CPU
178  * preemption.  Examples are sleep() or other system calls that block.
179  * If a problem is detected, the kernel writes a syslog entry, and
180  * sends SIGUSR2 to the client.
181  */
182
183 // #define DO_PREEMPTION_CHECKING
184
185 #include <sys/time.h>
186
187 #ifdef DO_PREEMPTION_CHECKING
188 #define CHECK_PREEMPTION(onoff) \
189     gettimeofday((struct timeval *)1, (struct timezone *)onoff)
190 #else
191 #define CHECK_PREEMPTION(onoff)
192 #endif
193
194 unsigned char toAscii( unsigned char c );
195 void quadlet2char( fb_quadlet_t quadlet, unsigned char* buff );
196 void hexDump( unsigned char *data_start, unsigned int length );
197 void hexDumpQuadlets( quadlet_t *data_start, unsigned int length );
198
199 class DebugModule {
200 public:
201     enum {
202         eDL_Message      = DEBUG_LEVEL_MESSAGE,
203         eDL_Fatal        = DEBUG_LEVEL_FATAL,
204         eDL_Error        = DEBUG_LEVEL_ERROR,
205         eDL_Warning      = DEBUG_LEVEL_WARNING,
206         eDL_Normal       = DEBUG_LEVEL_NORMAL,
207         eDL_Info         = DEBUG_LEVEL_INFO,
208         eDL_Verbose      = DEBUG_LEVEL_VERBOSE,
209         eDL_VeryVerbose  = DEBUG_LEVEL_VERY_VERBOSE,
210         eDL_UltraVerbose = DEBUG_LEVEL_ULTRA_VERBOSE,
211     } EDebugLevel;
212
213     DebugModule( std::string name, debug_level_t level );
214     virtual ~DebugModule();
215
216     void printShort( debug_level_t level,
217                      const char* format,
218                      ... ) const;
219
220     void print( debug_level_t level,
221                 const char*   file,
222                 const char*   function,
223                 unsigned int  line,
224                 const char*   format,
225                 ... ) const;
226
227     bool setLevel( debug_level_t level )
228         { m_level = level; return true; }
229     debug_level_t getLevel()
230         { return m_level; }
231     std::string getName()
232         { return m_name; }
233
234 protected:
235     const char* getPreSequence( debug_level_t level ) const;
236     const char* getPostSequence( debug_level_t level ) const;
237
238 private:
239     std::string   m_name;
240     debug_level_t m_level;
241 };
242
243
244 class DebugModuleManager {
245 public:
246     friend class DebugModule;
247
248     static DebugModuleManager* instance();
249     ~DebugModuleManager();
250
251     bool setMgrDebugLevel( std::string name, debug_level_t level );
252
253     void flush();
254
255     // the backlog is a ringbuffer of all the messages
256     // that have been recorded using the debugPrint
257     // statements, regardless of the debug level.
258     // This is useful to obtain more debug info
259     // when something goes wrong without having too
260     // much output in normal operation
261     void showBackLog();
262     void showBackLog(int nblines);
263
264 protected:
265     bool registerModule( DebugModule& debugModule );
266     bool unregisterModule( DebugModule& debugModule );
267
268     bool init();
269
270     void print(const char *msg);
271     void backlog_print(const char *msg);
272
273 private:
274     DebugModuleManager();
275
276     typedef std::vector< DebugModule* > DebugModuleVector;
277     typedef std::vector< DebugModule* >::iterator DebugModuleVectorIterator;
278
279     char mb_buffers[MB_BUFFERS][MB_BUFFERSIZE];
280     unsigned int mb_initialized;
281     unsigned int mb_inbuffer;
282     unsigned int mb_outbuffer;
283     unsigned int mb_overruns;
284     pthread_t mb_writer_thread;
285     pthread_mutex_t mb_write_lock;
286     pthread_mutex_t mb_flush_lock;
287     pthread_cond_t mb_ready_cond;
288
289     static void *mb_thread_func(void *arg);
290     void mb_flush();
291
292 #ifdef IMPLEMENT_BACKLOG
293     // the backlog
294     char bl_mb_buffers[BACKLOG_MB_BUFFERS][MB_BUFFERSIZE];
295     unsigned int bl_mb_inbuffer;
296     pthread_mutex_t bl_mb_write_lock;
297 #endif
298
299     static DebugModuleManager* m_instance;
300     DebugModuleVector          m_debugModules;
301 };
302
303 #endif
Note: See TracBrowser for help on using the browser.