00001 /******************************************************************************* 00002 The content of this file includes portions of the AUDIOKINETIC Wwise Technology 00003 released in source code form as part of the SDK installer package. 00004 00005 Commercial License Usage 00006 00007 Licensees holding valid commercial licenses to the AUDIOKINETIC Wwise Technology 00008 may use this file in accordance with the end user license agreement provided 00009 with the software or, alternatively, in accordance with the terms contained in a 00010 written agreement between you and Audiokinetic Inc. 00011 00012 Apache License Usage 00013 00014 Alternatively, this file may be used under the Apache License, Version 2.0 (the 00015 "Apache License"); you may not use this file except in compliance with the 00016 Apache License. You may obtain a copy of the Apache License at 00017 http://www.apache.org/licenses/LICENSE-2.0. 00018 00019 Unless required by applicable law or agreed to in writing, software distributed 00020 under the Apache License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 00021 OR CONDITIONS OF ANY KIND, either express or implied. See the Apache License for 00022 the specific language governing permissions and limitations under the License. 00023 00024 Version: <VERSION> Build: <BUILDNUMBER> 00025 Copyright (c) <COPYRIGHTYEAR> Audiokinetic Inc. 00026 *******************************************************************************/ 00027 00028 #pragma once 00029 00030 #include <AK/Tools/Common/AkAssert.h> 00031 #include <AK/SoundEngine/Common/AkTypes.h> 00032 #include <android/log.h> 00033 00034 #include <time.h> 00035 #include <stdlib.h> 00036 00037 #define AK_THREAD_INIT_CODE(_threadProperties) syscall(__NR_sched_setaffinity, 0, sizeof(_threadProperties.dwAffinityMask), &_threadProperties.dwAffinityMask) 00038 00039 00040 namespace AKPLATFORM 00041 { 00042 /// Platform Independent Helper 00043 inline void PerformanceFrequency( AkInt64 * out_piFreq ) 00044 { 00045 // TO DO ANDROID ... is there something better 00046 *out_piFreq = CLOCKS_PER_SEC; 00047 } 00048 } 00049 00050 #include <AK/Tools/POSIX/AkPlatformFuncs.h> 00051 00052 namespace AKPLATFORM 00053 { 00054 00055 #ifndef AK_OPTIMIZED 00056 /// Output a debug message on the console (Ansi string) 00057 inline void OutputDebugMsg( const char* in_pszMsg ) 00058 { 00059 // To see output of this 00060 // adb logcat ActivityManager:I YourApplication:D AKDEBUG:D *:S 00061 __android_log_print(ANDROID_LOG_INFO, "AKDEBUG", "%s", in_pszMsg); 00062 } 00063 #else 00064 inline void OutputDebugMsg( const char* ){} 00065 #endif 00066 // Atomic Operations 00067 // ------------------------------------------------------------------ 00068 00069 /// Platform Independent Helper 00070 inline AkInt32 AkInterlockedIncrement( AkAtomic32 * pValue ) 00071 { 00072 return __atomic_add_fetch(pValue,1, __ATOMIC_SEQ_CST); 00073 } 00074 00075 /// Platform Independent Helper 00076 inline AkInt32 AkInterlockedDecrement( AkAtomic32 * pValue ) 00077 { 00078 return __atomic_sub_fetch(pValue,1, __ATOMIC_SEQ_CST); 00079 } 00080 00081 inline bool AkInterlockedCompareExchange( volatile AkAtomic32* io_pDest, AkInt32 in_newValue, AkInt32 in_expectedOldVal ) 00082 { 00083 return __atomic_compare_exchange(io_pDest, &in_expectedOldVal, &in_newValue, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); 00084 } 00085 00086 inline bool AkInterlockedCompareExchange( volatile AkAtomic64* io_pDest, AkInt64 in_newValue, AkInt64 in_expectedOldVal) 00087 { 00088 return __atomic_compare_exchange(io_pDest, &in_expectedOldVal, &in_newValue, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); 00089 } 00090 00091 inline void AkMemoryBarrier() 00092 { 00093 __atomic_thread_fence(__ATOMIC_SEQ_CST); 00094 /* 00095 #ifdef AK_CPU_ARM 00096 __asm("DMB ST"); //Wait for stores to complete. 00097 #elif AK_CPU_X86 00098 __asm("mfence"); 00099 #endif*/ 00100 } 00101 00102 // Time functions 00103 // ------------------------------------------------------------------ 00104 00105 /// Platform Independent Helper 00106 inline void PerformanceCounter( AkInt64 * out_piLastTime ) 00107 { 00108 *out_piLastTime = clock(); 00109 } 00110 00111 00112 template<class destType, class srcType> 00113 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 *) ) 00114 { 00115 size_t i; 00116 size_t lenToCopy = srcStrLen(in_pSrc); 00117 00118 lenToCopy = (lenToCopy > in_MaxSize-1) ? in_MaxSize-1 : lenToCopy; 00119 for(i = 0; i < lenToCopy; i++) 00120 { 00121 in_pdDest[i] = (destType) in_pSrc[i]; 00122 } 00123 in_pdDest[lenToCopy] = (destType)0; 00124 00125 return lenToCopy; 00126 } 00127 00128 #define CONVERT_UTF16_TO_CHAR( _astring_, _charstring_ ) \ 00129 _charstring_ = (char*)AkAlloca( (1 + AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)) * sizeof(char) ); \ 00130 AK_UTF16_TO_CHAR( _charstring_, (const AkUtf16*)_astring_, AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)+1 ) 00131 00132 #define AK_UTF16_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkSimpleConvertString( in_pdDest, in_pSrc, in_MaxSize, strlen, AKPLATFORM::AkUtf16StrLen ) 00133 #define AK_UTF16_TO_CHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkSimpleConvertString( in_pdDest, in_pSrc, in_MaxSize, strlen, AKPLATFORM::AkUtf16StrLen ) 00134 #define AK_CHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkSimpleConvertString( in_pdDest, in_pSrc, in_MaxSize, AKPLATFORM::AkUtf16StrLen, strlen) 00135 #define AK_OSCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkSimpleConvertString( in_pdDest, in_pSrc, in_MaxSize, AKPLATFORM::AkUtf16StrLen, strlen) 00136 00137 /// Stack allocations. 00138 #define AkAlloca( _size_ ) __builtin_alloca( _size_ ) 00139 00140 /// Platform Independent Helper 00141 inline void AkCreateThread( 00142 AkThreadRoutine pStartRoutine, // Thread routine. 00143 void * pParams, // Routine params. 00144 const AkThreadProperties & in_threadProperties, // Properties. NULL for default. 00145 AkThread * out_pThread, // Returned thread handle. 00146 const char * /*in_szThreadName*/ ) // Opt thread name. 00147 { 00148 AKASSERT( out_pThread != NULL ); 00149 00150 pthread_attr_t attr; 00151 00152 // Create the attr 00153 AKVERIFY(!pthread_attr_init(&attr)); 00154 // Set the stack size 00155 AKVERIFY(!pthread_attr_setstacksize(&attr,in_threadProperties.uStackSize)); 00156 00157 AKVERIFY(!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE)); 00158 00159 // Create the tread 00160 int threadError = pthread_create( out_pThread, &attr, pStartRoutine, pParams); 00161 AKASSERT( threadError == 0 ); 00162 AKVERIFY(!pthread_attr_destroy(&attr)); 00163 00164 if( threadError != 0 ) 00165 { 00166 AkClearThread( out_pThread ); 00167 return; 00168 } 00169 00170 // ::CreateThread() return NULL if it fails. 00171 if ( !*out_pThread ) 00172 { 00173 AkClearThread( out_pThread ); 00174 return; 00175 } 00176 00177 // Try to set the thread policy 00178 int sched_policy = in_threadProperties.uSchedPolicy; 00179 00180 // Get the priority for the policy 00181 int minPriority, maxPriority; 00182 minPriority = sched_get_priority_min(sched_policy); 00183 maxPriority = sched_get_priority_max(sched_policy); 00184 00185 // Set the thread priority if valid 00186 sched_param schedParam; 00187 schedParam.sched_priority = in_threadProperties.nPriority; 00188 AKASSERT( in_threadProperties.nPriority >= minPriority && in_threadProperties.nPriority <= maxPriority ); 00189 00190 //pthread_setschedparam WILL fail on Android Lollipop when used with SCHED_FIFO (the default). Not allowed anymore. (ignore the error code). 00191 int err = pthread_setschedparam(*out_pThread, sched_policy, &schedParam); 00192 if (err != 0) 00193 { 00194 //Make sure the priority is well set, even if the policy could not. 00195 sched_policy = SCHED_NORMAL; 00196 minPriority = sched_get_priority_min(sched_policy); 00197 maxPriority = sched_get_priority_max(sched_policy); 00198 if (in_threadProperties.nPriority == AK_THREAD_PRIORITY_ABOVE_NORMAL) 00199 schedParam.sched_priority = maxPriority; 00200 else if (in_threadProperties.nPriority == AK_THREAD_PRIORITY_BELOW_NORMAL) 00201 schedParam.sched_priority = minPriority; 00202 else 00203 schedParam.sched_priority = (maxPriority + minPriority) / 2; 00204 err = pthread_setschedparam(*out_pThread, sched_policy, &schedParam); 00205 AKASSERT(err == 0); 00206 } 00207 } 00208 }
Questions? Problems? Need more info? Contact us, and we can help!
Visit our Support pageRegister your project and we'll help you get started with no strings attached!
Get started with Wwise