Version
menu_open
link
Target Platform(s):

include/AK/Tools/Android/AkPlatformFuncs.h

Go to the documentation of this file.
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 }

Was this page helpful?

Need Support?

Questions? Problems? Need more info? Contact us, and we can help!

Visit our Support page

Tell us about your project. We're here to help.

Register your project and we'll help you get started with no strings attached!

Get started with Wwise