00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00044 #ifndef PA_UNIX_UTIL_H
00045 #define PA_UNIX_UTIL_H
00046
00047 #include "pa_cpuload.h"
00048 #include <assert.h>
00049 #include <pthread.h>
00050 #include <signal.h>
00051
00052 #ifdef __cplusplus
00053 extern "C"
00054 {
00055 #endif
00056
00057 #define PA_MIN(x,y) ( (x) < (y) ? (x) : (y) )
00058 #define PA_MAX(x,y) ( (x) > (y) ? (x) : (y) )
00059
00060
00061 #if defined __GNUC__ && __GNUC__ >= 3
00062 #define UNLIKELY(expr) __builtin_expect( (expr), 0 )
00063 #else
00064 #define UNLIKELY(expr) (expr)
00065 #endif
00066
00067 #define STRINGIZE_HELPER(expr) #expr
00068 #define STRINGIZE(expr) STRINGIZE_HELPER(expr)
00069
00070 #define PA_UNLESS(expr, code) \
00071 do { \
00072 if( UNLIKELY( (expr) == 0 ) ) \
00073 { \
00074 PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
00075 result = (code); \
00076 goto error; \
00077 } \
00078 } while (0);
00079
00080 static PaError paUtilErr_;
00081
00082
00083 #define PA_ENSURE(expr) \
00084 do { \
00085 if( UNLIKELY( (paUtilErr_ = (expr)) < paNoError ) ) \
00086 { \
00087 PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
00088 result = paUtilErr_; \
00089 goto error; \
00090 } \
00091 } while (0);
00092
00093 #define PA_ASSERT_CALL(expr, success) \
00094 paUtilErr_ = (expr); \
00095 assert( success == paUtilErr_ );
00096
00097 #define PA_ENSURE_SYSTEM(expr, success) \
00098 do { \
00099 if( UNLIKELY( (paUtilErr_ = (expr)) != success ) ) \
00100 { \
00101 \
00102 if( pthread_equal(pthread_self(), paUnixMainThread) ) \
00103 { \
00104 PaUtil_SetLastHostErrorInfo( paALSA, paUtilErr_, strerror( paUtilErr_ ) ); \
00105 } \
00106 PaUtil_DebugPrint( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" ); \
00107 result = paUnanticipatedHostError; \
00108 goto error; \
00109 } \
00110 } while( 0 );
00111
00112 typedef struct {
00113 pthread_t callbackThread;
00114 } PaUtilThreading;
00115
00116 PaError PaUtil_InitializeThreading( PaUtilThreading *threading );
00117 void PaUtil_TerminateThreading( PaUtilThreading *threading );
00118 PaError PaUtil_StartThreading( PaUtilThreading *threading, void *(*threadRoutine)(void *), void *data );
00119 PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *exitResult );
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 extern pthread_t paUnixMainThread;
00136
00137 typedef struct
00138 {
00139 pthread_mutex_t mtx;
00140 } PaUnixMutex;
00141
00142 PaError PaUnixMutex_Initialize( PaUnixMutex* self );
00143 PaError PaUnixMutex_Terminate( PaUnixMutex* self );
00144 PaError PaUnixMutex_Lock( PaUnixMutex* self );
00145 PaError PaUnixMutex_Unlock( PaUnixMutex* self );
00146
00147 typedef struct
00148 {
00149 pthread_t thread;
00150 int parentWaiting;
00151 int stopRequested;
00152 int locked;
00153 PaUnixMutex mtx;
00154 pthread_cond_t cond;
00155 volatile sig_atomic_t stopRequest;
00156 } PaUnixThread;
00157
00160 PaError PaUnixThreading_Initialize();
00161
00171 #define PaUnixThreading_EXIT(result) \
00172 do { \
00173 PaError* pres = NULL; \
00174 if( paNoError != (result) ) \
00175 { \
00176 pres = malloc( sizeof (PaError) ); \
00177 *pres = (result); \
00178 } \
00179 pthread_exit( pres ); \
00180 } while (0);
00181
00193 PaError PaUnixThread_New( PaUnixThread* self, void* (*threadFunc)( void* ), void* threadArg, PaTime waitForChild,
00194 int rtSched );
00195
00201 PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResult );
00202
00209 PaError PaUnixThread_PrepareNotify( PaUnixThread* self );
00210
00215 PaError PaUnixThread_NotifyParent( PaUnixThread* self );
00216
00219 int PaUnixThread_StopRequested( PaUnixThread* self );
00220
00221 #ifdef __cplusplus
00222 }
00223 #endif
00224 #endif