pa_unix_util.h

Go to the documentation of this file.
00001 /*
00002  * $Id: pa_unix_util.h 1083 2006-08-23 07:30:49Z rossb $
00003  * Portable Audio I/O Library
00004  * UNIX platform-specific support functions
00005  *
00006  * Based on the Open Source API proposed by Ross Bencina
00007  * Copyright (c) 1999-2000 Ross Bencina
00008  *
00009  * Permission is hereby granted, free of charge, to any person obtaining
00010  * a copy of this software and associated documentation files
00011  * (the "Software"), to deal in the Software without restriction,
00012  * including without limitation the rights to use, copy, modify, merge,
00013  * publish, distribute, sublicense, and/or sell copies of the Software,
00014  * and to permit persons to whom the Software is furnished to do so,
00015  * subject to the following conditions:
00016  *
00017  * The above copyright notice and this permission notice shall be
00018  * included in all copies or substantial portions of the Software.
00019  *
00020  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00021  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00022  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00023  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
00024  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
00025  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00026  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00027  */
00028 
00029 /*
00030  * The text above constitutes the entire PortAudio license; however, 
00031  * the PortAudio community also makes the following non-binding requests:
00032  *
00033  * Any person wishing to distribute modifications to the Software is
00034  * requested to send the modifications to the original developer so that
00035  * they can be incorporated into the canonical version. It is also 
00036  * requested that these non-binding requests be included along with the 
00037  * license above.
00038  */
00039 
00040 #ifndef PA_UNIX_UTIL_H
00041 #define PA_UNIX_UTIL_H
00042 
00043 #include "pa_cpuload.h"
00044 #include <assert.h>
00045 #include <pthread.h>
00046 #include <signal.h>
00047 
00048 #ifdef __cplusplus
00049 extern "C"
00050 {
00051 #endif /* __cplusplus */
00052 
00053 #define PA_MIN(x,y) ( (x) < (y) ? (x) : (y) )
00054 #define PA_MAX(x,y) ( (x) > (y) ? (x) : (y) )
00055 
00056 /* Utilize GCC branch prediction for error tests */
00057 #if defined __GNUC__ && __GNUC__ >= 3
00058 #define UNLIKELY(expr) __builtin_expect( (expr), 0 )
00059 #else
00060 #define UNLIKELY(expr) (expr)
00061 #endif
00062 
00063 #define STRINGIZE_HELPER(expr) #expr
00064 #define STRINGIZE(expr) STRINGIZE_HELPER(expr)
00065 
00066 #define PA_UNLESS(expr, code) \
00067     do { \
00068         if( UNLIKELY( (expr) == 0 ) ) \
00069         { \
00070             PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
00071             result = (code); \
00072             goto error; \
00073         } \
00074     } while (0);
00075 
00076 static PaError paUtilErr_;          /* Used with PA_ENSURE */
00077 
00078 /* Check PaError */
00079 #define PA_ENSURE(expr) \
00080     do { \
00081         if( UNLIKELY( (paUtilErr_ = (expr)) < paNoError ) ) \
00082         { \
00083             PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
00084             result = paUtilErr_; \
00085             goto error; \
00086         } \
00087     } while (0);
00088 
00089 #define PA_ASSERT_CALL(expr, success) \
00090     paUtilErr_ = (expr); \
00091     assert( success == paUtilErr_ );
00092 
00093 #define PA_ENSURE_SYSTEM(expr, success) \
00094     do { \
00095         if( UNLIKELY( (paUtilErr_ = (expr)) != success ) ) \
00096         { \
00097             /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \
00098             if( pthread_equal(pthread_self(), paUnixMainThread) ) \
00099             { \
00100                 PaUtil_SetLastHostErrorInfo( paALSA, paUtilErr_, strerror( paUtilErr_ ) ); \
00101             } \
00102             PaUtil_DebugPrint( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" ); \
00103             result = paUnanticipatedHostError; \
00104             goto error; \
00105         } \
00106     } while( 0 );
00107 
00108 typedef struct {
00109     pthread_t callbackThread;
00110 } PaUtilThreading;
00111 
00112 PaError PaUtil_InitializeThreading( PaUtilThreading *threading );
00113 void PaUtil_TerminateThreading( PaUtilThreading *threading );
00114 PaError PaUtil_StartThreading( PaUtilThreading *threading, void *(*threadRoutine)(void *), void *data );
00115 PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *exitResult );
00116 
00117 /* State accessed by utility functions */
00118 
00119 /*
00120 void PaUnix_SetRealtimeScheduling( int rt );
00121 
00122 void PaUtil_InitializeThreading( PaUtilThreading *th, PaUtilCpuLoadMeasurer *clm );
00123 
00124 PaError PaUtil_CreateCallbackThread( PaUtilThreading *th, void *(*CallbackThreadFunc)( void * ), PaStream *s );
00125 
00126 PaError PaUtil_KillCallbackThread( PaUtilThreading *th, PaError *exitResult );
00127 
00128 void PaUtil_CallbackUpdate( PaUtilThreading *th );
00129 */
00130 
00131 extern pthread_t paUnixMainThread;
00132 
00133 typedef struct
00134 {
00135     pthread_mutex_t mtx;
00136 } PaUnixMutex;
00137 
00138 PaError PaUnixMutex_Initialize( PaUnixMutex* self );
00139 PaError PaUnixMutex_Terminate( PaUnixMutex* self );
00140 PaError PaUnixMutex_Lock( PaUnixMutex* self );
00141 PaError PaUnixMutex_Unlock( PaUnixMutex* self );
00142 
00143 typedef struct
00144 {
00145     pthread_t thread;
00146     int parentWaiting;
00147     int stopRequested;
00148     int locked;
00149     PaUnixMutex mtx;
00150     pthread_cond_t cond;
00151     volatile sig_atomic_t stopRequest;
00152 } PaUnixThread;
00153 
00156 PaError PaUnixThreading_Initialize();
00157 
00167 #define PaUnixThreading_EXIT(result) \
00168     do { \
00169         PaError* pres = NULL; \
00170         if( paNoError != (result) ) \
00171         { \
00172             pres = malloc( sizeof (PaError) ); \
00173             *pres = (result); \
00174         } \
00175         pthread_exit( pres ); \
00176     } while (0);
00177 
00188 PaError PaUnixThread_New( PaUnixThread* self, void* (*threadFunc)( void* ), void* threadArg, PaTime waitForChild );
00189 
00195 PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResult );
00196 
00203 PaError PaUnixThread_PrepareNotify( PaUnixThread* self );
00204 
00209 PaError PaUnixThread_NotifyParent( PaUnixThread* self );
00210 
00213 int PaUnixThread_StopRequested( PaUnixThread* self );
00214 
00215 #ifdef __cplusplus
00216 }
00217 #endif /* __cplusplus */
00218 #endif

Generated on Fri Nov 17 07:08:00 2006 for PortAudio by  doxygen 1.5.1