00001
00002
00003
00004
00005
00006
00007
00008
00010
00011 #pragma once
00012
00013 #include <AK/Tools/Common/AkAssert.h>
00014 #include <AK/SoundEngine/Common/AkTypes.h>
00015 #include <android/log.h>
00016
00017 #include <time.h>
00018 #include <stdlib.h>
00019
00020 #define AK_THREAD_INIT_CODE(_threadProperties) syscall(__NR_sched_setaffinity, 0, sizeof(_threadProperties.dwAffinityMask), &_threadProperties.dwAffinityMask)
00021
00022
00023 namespace AKPLATFORM
00024 {
00026 inline void PerformanceFrequency( AkInt64 * out_piFreq )
00027 {
00028
00029 *out_piFreq = CLOCKS_PER_SEC;
00030 }
00031 }
00032
00033 #include <AK/Tools/POSIX/AkPlatformFuncs.h>
00034
00035 namespace AKPLATFORM
00036 {
00037
00038 #ifndef AK_OPTIMIZED
00039
00040 inline void OutputDebugMsg( const char* in_pszMsg )
00041 {
00042
00043
00044 __android_log_print(ANDROID_LOG_INFO, "AKDEBUG", "%s", in_pszMsg);
00045 }
00046 #else
00047 inline void OutputDebugMsg( const char* ){}
00048 #endif
00049
00050
00051
00053 inline AkInt32 AkInterlockedIncrement( AkInt32 * pValue )
00054 {
00055 return __atomic_add_fetch(pValue,1, __ATOMIC_SEQ_CST);
00056 }
00057
00059 inline AkInt32 AkInterlockedDecrement( AkInt32 * pValue )
00060 {
00061 return __atomic_sub_fetch(pValue,1, __ATOMIC_SEQ_CST);
00062 }
00063
00064 inline bool AkInterlockedCompareExchange( volatile AkInt32* io_pDest, AkInt32 in_newValue, AkInt32 in_expectedOldVal )
00065 {
00066 return __atomic_compare_exchange(io_pDest, &in_expectedOldVal, &in_newValue, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
00067 }
00068
00069 inline bool AkInterlockedCompareExchange( volatile AkInt64* io_pDest, AkInt64 in_newValue, AkInt64 in_expectedOldVal )
00070 {
00071 return __atomic_compare_exchange(io_pDest, &in_expectedOldVal, &in_newValue, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
00072 }
00073
00074 inline void AkMemoryBarrier()
00075 {
00076 __atomic_thread_fence(__ATOMIC_SEQ_CST);
00077
00078
00079
00080
00081
00082
00083 }
00084
00085
00086
00087
00089 inline void PerformanceCounter( AkInt64 * out_piLastTime )
00090 {
00091 *out_piLastTime = clock();
00092 }
00093
00094
00095 template<class destType, class srcType>
00096 inline size_t AkSimpleConvertString( destType* in_pdDest, const srcType* in_pSrc, size_t in_MaxSize, size_t destStrLen(const destType *), size_t srcStrLen(const srcType *) )
00097 {
00098 size_t i;
00099 size_t lenToCopy = srcStrLen(in_pSrc);
00100
00101 lenToCopy = (lenToCopy > in_MaxSize-1) ? in_MaxSize-1 : lenToCopy;
00102 for(i = 0; i < lenToCopy; i++)
00103 {
00104 in_pdDest[i] = (destType) in_pSrc[i];
00105 }
00106 in_pdDest[lenToCopy] = (destType)0;
00107
00108 return lenToCopy;
00109 }
00110
00111 #define CONVERT_UTF16_TO_CHAR( _astring_, _charstring_ ) \
00112 _charstring_ = (char*)AkAlloca( (1 + AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)) * sizeof(char) ); \
00113 AK_UTF16_TO_CHAR( _charstring_, (const AkUtf16*)_astring_, AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)+1 )
00114
00115 #define AK_UTF16_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkSimpleConvertString( in_pdDest, in_pSrc, in_MaxSize, strlen, AKPLATFORM::AkUtf16StrLen )
00116 #define AK_UTF16_TO_CHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkSimpleConvertString( in_pdDest, in_pSrc, in_MaxSize, strlen, AKPLATFORM::AkUtf16StrLen )
00117 #define AK_CHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkSimpleConvertString( in_pdDest, in_pSrc, in_MaxSize, AKPLATFORM::AkUtf16StrLen, strlen)
00118 #define AK_OSCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkSimpleConvertString( in_pdDest, in_pSrc, in_MaxSize, AKPLATFORM::AkUtf16StrLen, strlen)
00119
00121 #define AkAlloca( _size_ ) __builtin_alloca( _size_ )
00122
00124 inline void AkCreateThread(
00125 AkThreadRoutine pStartRoutine,
00126 void * pParams,
00127 const AkThreadProperties & in_threadProperties,
00128 AkThread * out_pThread,
00129 const char * )
00130 {
00131 AKASSERT( out_pThread != NULL );
00132
00133 pthread_attr_t attr;
00134
00135
00136 AKVERIFY(!pthread_attr_init(&attr));
00137
00138 AKVERIFY(!pthread_attr_setstacksize(&attr,in_threadProperties.uStackSize));
00139
00140 AKVERIFY(!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
00141
00142
00143 int threadError = pthread_create( out_pThread, &attr, pStartRoutine, pParams);
00144 AKASSERT( threadError == 0 );
00145 AKVERIFY(!pthread_attr_destroy(&attr));
00146
00147 if( threadError != 0 )
00148 {
00149 AkClearThread( out_pThread );
00150 return;
00151 }
00152
00153
00154 if ( !*out_pThread )
00155 {
00156 AkClearThread( out_pThread );
00157 return;
00158 }
00159
00160
00161 int sched_policy = in_threadProperties.uSchedPolicy;
00162
00163
00164 int minPriority, maxPriority;
00165 minPriority = sched_get_priority_min(sched_policy);
00166 maxPriority = sched_get_priority_max(sched_policy);
00167
00168
00169 sched_param schedParam;
00170 schedParam.sched_priority = in_threadProperties.nPriority;
00171 AKASSERT( in_threadProperties.nPriority >= minPriority && in_threadProperties.nPriority <= maxPriority );
00172
00173
00174 int err = pthread_setschedparam(*out_pThread, sched_policy, &schedParam);
00175 if (err != 0)
00176 {
00177
00178 sched_policy = SCHED_NORMAL;
00179 minPriority = sched_get_priority_min(sched_policy);
00180 maxPriority = sched_get_priority_max(sched_policy);
00181 if (in_threadProperties.nPriority == AK_THREAD_PRIORITY_ABOVE_NORMAL)
00182 schedParam.sched_priority = maxPriority;
00183 else if (in_threadProperties.nPriority == AK_THREAD_PRIORITY_BELOW_NORMAL)
00184 schedParam.sched_priority = minPriority;
00185 else
00186 schedParam.sched_priority = (maxPriority + minPriority) / 2;
00187 err = pthread_setschedparam(*out_pThread, sched_policy, &schedParam);
00188 AKASSERT(err == 0);
00189 }
00190 }
00191 }