Version
menu_open
link
Target Platform(s):

include/AK/Tools/Android/AkPlatformFuncs.h

Go to the documentation of this file.
00001 
00002 //
00003 // AkPlatformFuncs.h 
00004 //
00005 // Audiokinetic platform-dependent functions definition.
00006 //
00007 // Copyright (c) 2006 Audiokinetic Inc. / All Rights Reserved
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         // TO DO ANDROID ... is there something better
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         // To see output of this 
00043         // adb logcat ActivityManager:I YourApplication:D AKDEBUG:D *:S
00044         __android_log_print(ANDROID_LOG_INFO, "AKDEBUG", "%s", in_pszMsg);  
00045     }   
00046 #else   
00047     inline void OutputDebugMsg( const char* ){}
00048 #endif
00049     // Atomic Operations
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 #ifdef AK_CPU_ARM
00079         __asm("DMB ST");    //Wait for stores to complete.
00080 #elif AK_CPU_X86
00081         __asm("mfence");    
00082 #endif*/
00083     }
00084 
00085     // Time functions
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,                  // Thread routine.
00126         void * pParams,                                 // Routine params.
00127         const AkThreadProperties & in_threadProperties, // Properties. NULL for default.
00128         AkThread * out_pThread,                         // Returned thread handle.
00129         const char * /*in_szThreadName*/ )              // Opt thread name.
00130     {
00131         AKASSERT( out_pThread != NULL );
00132 
00133         pthread_attr_t  attr;
00134 
00135         // Create the attr
00136         AKVERIFY(!pthread_attr_init(&attr));
00137         // Set the stack size
00138         AKVERIFY(!pthread_attr_setstacksize(&attr,in_threadProperties.uStackSize));
00139 
00140         AKVERIFY(!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));     
00141 
00142         // Create the tread
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         // ::CreateThread() return NULL if it fails.
00154         if ( !*out_pThread )
00155         {
00156             AkClearThread( out_pThread );
00157             return;
00158         }       
00159 
00160         // Try to set the thread policy
00161         int sched_policy = in_threadProperties.uSchedPolicy;        
00162 
00163         // Get the priority for the policy
00164         int minPriority, maxPriority;
00165         minPriority = sched_get_priority_min(sched_policy);
00166         maxPriority = sched_get_priority_max(sched_policy);
00167 
00168         // Set the thread priority if valid
00169         sched_param schedParam;
00170         schedParam.sched_priority = in_threadProperties.nPriority;  
00171         AKASSERT( in_threadProperties.nPriority >= minPriority && in_threadProperties.nPriority <= maxPriority );       
00172 
00173         //pthread_setschedparam WILL fail on Android Lollipop when used with SCHED_FIFO (the default).  Not allowed anymore. (ignore the error code).
00174         int err = pthread_setschedparam(*out_pThread, sched_policy, &schedParam);
00175         if (err != 0)
00176         {           
00177             //Make sure the priority is well set, even if the policy could not.         
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 }

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