Table of Contents

Target Platform(s):
Wwise SDK 2019.1.9
AkPlatformFuncs.h
1 /*******************************************************************************
2 The content of this file includes portions of the AUDIOKINETIC Wwise Technology
3 released in source code form as part of the SDK installer package.
4 
5 Commercial License Usage
6 
7 Licensees holding valid commercial licenses to the AUDIOKINETIC Wwise Technology
8 may use this file in accordance with the end user license agreement provided
9 with the software or, alternatively, in accordance with the terms contained in a
10 written agreement between you and Audiokinetic Inc.
11 
12 Apache License Usage
13 
14 Alternatively, this file may be used under the Apache License, Version 2.0 (the
15 "Apache License"); you may not use this file except in compliance with the
16 Apache License. You may obtain a copy of the Apache License at
17 http://www.apache.org/licenses/LICENSE-2.0.
18 
19 Unless required by applicable law or agreed to in writing, software distributed
20 under the Apache License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
21 OR CONDITIONS OF ANY KIND, either express or implied. See the Apache License for
22 the specific language governing permissions and limitations under the License.
23 
24  Version: <VERSION> Build: <BUILDNUMBER>
25  Copyright (c) <COPYRIGHTYEAR> Audiokinetic Inc.
26 *******************************************************************************/
27 
28 #pragma once
29 
30 #include <AK/Tools/Common/AkAssert.h>
31 #include <AK/SoundEngine/Common/AkTypes.h>
32 #include <android/log.h>
33 
34 #include <time.h>
35 #include <stdlib.h>
36 
37 #define AK_THREAD_INIT_CODE(_threadProperties) syscall(__NR_sched_setaffinity, 0, sizeof(_threadProperties.dwAffinityMask), &_threadProperties.dwAffinityMask)
38 
39 
40 namespace AKPLATFORM
41 {
42  /// Platform Independent Helper
43  inline void PerformanceFrequency( AkInt64 * out_piFreq )
44  {
45  // TO DO ANDROID ... is there something better
46  *out_piFreq = CLOCKS_PER_SEC;
47  }
48 }
49 
50 #include <AK/Tools/POSIX/AkPlatformFuncs.h>
51 
52 namespace AKPLATFORM
53 {
54 
55 #ifndef AK_OPTIMIZED
56  /// Output a debug message on the console (Ansi string)
57  inline void OutputDebugMsg( const char* in_pszMsg )
58  {
59  // To see output of this
60  // adb logcat ActivityManager:I YourApplication:D AKDEBUG:D *:S
61  __android_log_print(ANDROID_LOG_INFO, "AKDEBUG", "%s", in_pszMsg);
62  }
63 #else
64  inline void OutputDebugMsg( const char* ){}
65 #endif
66  // Atomic Operations
67  // ------------------------------------------------------------------
68 
69  /// Platform Independent Helper
70  inline AkInt32 AkInterlockedIncrement( AkAtomic32 * pValue )
71  {
72  return __atomic_add_fetch(pValue,1, __ATOMIC_SEQ_CST);
73  }
74 
75  /// Platform Independent Helper
76  inline AkInt32 AkInterlockedDecrement( AkAtomic32 * pValue )
77  {
78  return __atomic_sub_fetch(pValue,1, __ATOMIC_SEQ_CST);
79  }
80 
81  inline bool AkInterlockedCompareExchange( volatile AkAtomic32* io_pDest, AkInt32 in_newValue, AkInt32 in_expectedOldVal )
82  {
83  return __atomic_compare_exchange(io_pDest, &in_expectedOldVal, &in_newValue, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
84  }
85 
86  inline bool AkInterlockedCompareExchange( volatile AkAtomic64* io_pDest, AkInt64 in_newValue, AkInt64 in_expectedOldVal)
87  {
88  return __atomic_compare_exchange(io_pDest, &in_expectedOldVal, &in_newValue, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
89  }
90 
91  inline void AkMemoryBarrier()
92  {
93  __atomic_thread_fence(__ATOMIC_SEQ_CST);
94  /*
95 #ifdef AK_CPU_ARM
96  __asm("DMB ST"); //Wait for stores to complete.
97 #elif AK_CPU_X86
98  __asm("mfence");
99 #endif*/
100  }
101 
102  // Time functions
103  // ------------------------------------------------------------------
104 
105  /// Platform Independent Helper
106  inline void PerformanceCounter( AkInt64 * out_piLastTime )
107  {
108  *out_piLastTime = clock();
109  }
110 
111 
112  template<class destType, class srcType>
113  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 *) )
114  {
115  size_t i;
116  size_t lenToCopy = srcStrLen(in_pSrc);
117 
118  lenToCopy = (lenToCopy > in_MaxSize-1) ? in_MaxSize-1 : lenToCopy;
119  for(i = 0; i < lenToCopy; i++)
120  {
121  in_pdDest[i] = (destType) in_pSrc[i];
122  }
123  in_pdDest[lenToCopy] = (destType)0;
124 
125  return lenToCopy;
126  }
127 
128  #define CONVERT_UTF16_TO_CHAR( _astring_, _charstring_ ) \
129  _charstring_ = (char*)AkAlloca( (1 + AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)) * sizeof(char) ); \
130  AK_UTF16_TO_CHAR( _charstring_, (const AkUtf16*)_astring_, AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)+1 )
131 
132  #define AK_UTF16_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkSimpleConvertString( in_pdDest, in_pSrc, in_MaxSize, strlen, AKPLATFORM::AkUtf16StrLen )
133  #define AK_UTF16_TO_CHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkSimpleConvertString( in_pdDest, in_pSrc, in_MaxSize, strlen, AKPLATFORM::AkUtf16StrLen )
134  #define AK_CHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkSimpleConvertString( in_pdDest, in_pSrc, in_MaxSize, AKPLATFORM::AkUtf16StrLen, strlen)
135  #define AK_OSCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkSimpleConvertString( in_pdDest, in_pSrc, in_MaxSize, AKPLATFORM::AkUtf16StrLen, strlen)
136 
137  /// Stack allocations.
138  #define AkAlloca( _size_ ) __builtin_alloca( _size_ )
139 
140  #if __BIGGEST_ALIGNMENT__ < AK_SIMD_ALIGNMENT
141  #define AkAllocaSIMD( _size_ ) __builtin_alloca_with_align( _size_, AK_SIMD_ALIGNMENT*8 )
142  #endif
143 
144  /// Platform Independent Helper
145  inline void AkCreateThread(
146  AkThreadRoutine pStartRoutine, // Thread routine.
147  void * pParams, // Routine params.
148  const AkThreadProperties & in_threadProperties, // Properties. NULL for default.
149  AkThread * out_pThread, // Returned thread handle.
150  const char * /*in_szThreadName*/ ) // Opt thread name.
151  {
152  AKASSERT( out_pThread != NULL );
153 
154  pthread_attr_t attr;
155 
156  // Create the attr
157  AKVERIFY(!pthread_attr_init(&attr));
158  // Set the stack size
159  AKVERIFY(!pthread_attr_setstacksize(&attr,in_threadProperties.uStackSize));
160 
161  AKVERIFY(!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
162 
163  // Create the tread
164  int threadError = pthread_create( out_pThread, &attr, pStartRoutine, pParams);
165  AKASSERT( threadError == 0 );
166  AKVERIFY(!pthread_attr_destroy(&attr));
167 
168  if( threadError != 0 )
169  {
170  AkClearThread( out_pThread );
171  return;
172  }
173 
174  // ::CreateThread() return NULL if it fails.
175  if ( !*out_pThread )
176  {
177  AkClearThread( out_pThread );
178  return;
179  }
180 
181  // Try to set the thread policy
182  int sched_policy = in_threadProperties.uSchedPolicy;
183 
184  // Get the priority for the policy
185  int minPriority, maxPriority;
186  minPriority = sched_get_priority_min(sched_policy);
187  maxPriority = sched_get_priority_max(sched_policy);
188 
189  // Set the thread priority if valid
190  sched_param schedParam;
191  schedParam.sched_priority = in_threadProperties.nPriority;
192  AKASSERT( in_threadProperties.nPriority >= minPriority && in_threadProperties.nPriority <= maxPriority );
193 
194  //pthread_setschedparam WILL fail on Android Lollipop when used with SCHED_FIFO (the default). Not allowed anymore. (ignore the error code).
195  int err = pthread_setschedparam(*out_pThread, sched_policy, &schedParam);
196  if (err != 0)
197  {
198  //Make sure the priority is well set, even if the policy could not.
199  sched_policy = SCHED_NORMAL;
200  minPriority = sched_get_priority_min(sched_policy);
201  maxPriority = sched_get_priority_max(sched_policy);
202  if (in_threadProperties.nPriority == AK_THREAD_PRIORITY_ABOVE_NORMAL)
203  schedParam.sched_priority = maxPriority;
204  else if (in_threadProperties.nPriority == AK_THREAD_PRIORITY_BELOW_NORMAL)
205  schedParam.sched_priority = minPriority;
206  else
207  schedParam.sched_priority = (maxPriority + minPriority) / 2;
208  err = pthread_setschedparam(*out_pThread, sched_policy, &schedParam);
209  AKASSERT(err == 0);
210  }
211  }
212 }
int nPriority
Thread priority.
Definition: AkPlatformFuncs.h:75
void OutputDebugMsg(const char *in_pszMsg)
Output a debug message on the console (Ansi string)
Definition: AkPlatformFuncs.h:57
void AkMemoryBarrier()
Definition: AkPlatformFuncs.h:91
AkInt32 AkInterlockedIncrement(AkAtomic32 *pValue)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:70
AkInt32 AkInterlockedDecrement(AkAtomic32 *pValue)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:76
void AkCreateThread(AkThreadRoutine pStartRoutine, void *pParams, const AkThreadProperties &in_threadProperties, AkThread *out_pThread, const char *)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:145
void PerformanceCounter(AkInt64 *out_piLastTime)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:106
AkForceInline void AkClearThread(AkThread *in_pThread)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:218
size_t uStackSize
Thread stack size.
Definition: AkPlatformFuncs.h:77
void PerformanceFrequency(AkInt64 *out_piFreq)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:43
int uSchedPolicy
Thread scheduling policy.
Definition: AkPlatformFuncs.h:78
bool AkInterlockedCompareExchange(volatile AkAtomic32 *io_pDest, AkInt32 in_newValue, AkInt32 in_expectedOldVal)
Definition: AkPlatformFuncs.h:81
size_t AkSimpleConvertString(destType *in_pdDest, const srcType *in_pSrc, size_t in_MaxSize, size_t destStrLen(const destType *), size_t srcStrLen(const srcType *))
Definition: AkPlatformFuncs.h:113