Version
menu_open
link
Wwise SDK 2023.1.4
AkPlatformFuncs.h
Go to the documentation of this file.
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  Copyright (c) 2024 Audiokinetic Inc.
25 *******************************************************************************/
26 
27 // AkPlatformFuncs.h
28 
29 /// \file
30 /// Platform-dependent functions definition.
31 
32 #ifndef _AK_TOOLS_COMMON_AKPLATFORMFUNCS_H
33 #define _AK_TOOLS_COMMON_AKPLATFORMFUNCS_H
34 
37 
38 // Uncomment the following to enable built-in platform profiler markers in the sound engine
39 //#define AK_ENABLE_INSTRUMENT
40 
41 #if defined(AK_NULL_PLATFORM)
42 // null platform has no funcs
43 struct AkThreadProperties {};
44 #elif defined(AK_WIN)
46 
47 #elif defined (AK_XBOX)
49 
50 #elif defined (AK_APPLE)
52 #include <AK/Tools/POSIX/AkPlatformFuncs.h>
53 
54 #elif defined( AK_ANDROID ) || defined ( AK_LINUX_AOSP )
56 
57 #elif defined (AK_PS4)
59 
60 #elif defined (AK_PS5)
62 
63 #elif defined (AK_EMSCRIPTEN)
65 
66 #elif defined (AK_LINUX)
68 #include <AK/Tools/POSIX/AkPlatformFuncs.h>
69 
70 #elif defined (AK_QNX)
71 #include <AK/Tools/QNX/AkPlatformFuncs.h>
72 #include <AK/Tools/POSIX/AkPlatformFuncs.h>
73 
74 #elif defined (AK_NX)
76 
77 #else
78 #error AkPlatformFuncs.h: Undefined platform
79 #endif
80 
81 #ifndef AkPrefetchZero
82 #define AkPrefetchZero(___Dest, ___Size)
83 #endif
84 
85 #ifndef AkPrefetchZeroAligned
86 #define AkPrefetchZeroAligned(___Dest, ___Size)
87 #endif
88 
89 #ifndef AkZeroMemAligned
90 #define AkZeroMemAligned(___Dest, ___Size) AKPLATFORM::AkMemSet(___Dest, 0, ___Size);
91 #endif
92 #ifndef AkZeroMemLarge
93 #define AkZeroMemLarge(___Dest, ___Size) AKPLATFORM::AkMemSet(___Dest, 0, ___Size);
94 #endif
95 #ifndef AkZeroMemSmall
96 #define AkZeroMemSmall(___Dest, ___Size) AKPLATFORM::AkMemSet(___Dest, 0, ___Size);
97 #endif
98 
99 #ifndef AkAllocaSIMD
100 #ifdef __clang__
101 #if __has_builtin( __builtin_alloca_with_align )
102 #define AkAllocaSIMD( _size_ ) __builtin_alloca_with_align( _size_, 128 )
103 #else
104 // work around alloca alignment issues in versions of clang before 4.0
105 #define AkAllocaSIMD( _size_ ) (void*)( ( ( uintptr_t )AkAlloca( _size_ + 16 ) + 0xF ) & ~0xF )
106 #endif
107 #else
108 #define AkAllocaSIMD( _size_ ) AkAlloca( _size_ )
109 #endif
110 #endif
111 
112 #ifndef AK_THREAD_INIT_CODE
113 #define AK_THREAD_INIT_CODE(_threadProperties)
114 #endif
115 
116 #ifndef AK_PLATFORM_MEMCPY
117 namespace AKPLATFORM
118 {
119  /// Platform Independent Helper for memcpy/memmove/memset
120  AkForceInline void AkMemCpy(void* pDest, const void* pSrc, AkUInt32 uSize)
121  {
122  memcpy(pDest, pSrc, uSize);
123  }
124 
125  AkForceInline void AkMemMove(void* pDest, const void* pSrc, AkUInt32 uSize)
126  {
127  memmove(pDest, pSrc, uSize);
128  }
129 
130  AkForceInline void AkMemSet(void* pDest, AkInt32 iVal, AkUInt32 uSize)
131  {
132  memset(pDest, iVal, uSize);
133  }
134 }
135 #endif // AK_PLATFORM_MEMCPY
136 
137 #if !defined(AK_NULL_PLATFORM)
138 /// Platform-dependent helpers
139 namespace AKPLATFORM
140 {
142  {
143  AkGetDefaultThreadProperties(out_threadProperties);
144  out_threadProperties.nPriority = AK_THREAD_PRIORITY_ABOVE_NORMAL;
145  }
146 
147  // fallback implementations for when platform don't have their own implementation
148 #if !defined(AK_LIMITEDSPINFORZERO)
149  // Waits for a limited amount of time for in_pVal to hit zero (without yielding the thread)
150  inline void AkLimitedSpinForZero(AkAtomic32* in_pVal)
151  {
152  AkInt64 endSpinTime = 0;
153  AkInt64 currentTime = 0;
154  PerformanceCounter(&endSpinTime);
155  endSpinTime += AkInt64(AK::g_fFreqRatio * 0.01); // only spin for about 10us
156  while (true)
157  {
158  // if pval is zero, skip out
159  if (AkAtomicLoad32(in_pVal) == 0)
160  {
161  break;
162  }
163  AkSpinHint();
164 
165  // Check if we've hit the deadline for the timeout
166  PerformanceCounter(&currentTime);
167  if (currentTime > endSpinTime)
168  {
169  break;
170  }
171  }
172  }
173 
174  // Waits for a limited amount of time for in_pVal to get atomically shift from the expected value to the proposed one
175  // returns true if acquisition succeeded
176  inline bool AkLimitedSpinToAcquire(AkAtomic32* in_pVal, AkInt32 in_proposed, AkInt32 in_expected)
177  {
178  if (AkAtomicCas32(in_pVal, in_proposed, in_expected))
179  {
180  return true;
181  }
182 
183  // Cas failed, start the slower evaluation
184  AkInt64 endSpinTime = 0;
185  AkInt64 currentTime = 0;
186  PerformanceCounter(&endSpinTime);
187  endSpinTime += AkInt64(AK::g_fFreqRatio * 0.01); // only spin for about 10us
188  while (true)
189  {
190  // attempt cas to acquire and if successful, skip out
191  if (AkAtomicCas32(in_pVal, in_proposed, in_expected))
192  {
193  return true;
194  }
195  AkSpinHint();
196 
197  // Check if we've hit the deadline for the timeout
198  PerformanceCounter(&currentTime);
199  if (currentTime > endSpinTime)
200  {
201  return false;
202  }
203  }
204  }
205 #endif // !defined(AK_LIMITEDSPINFORZERO)
206 
207  inline void AkSpinWaitForZero(AkAtomic32* in_pVal)
208  {
209  if (AkAtomicLoad32(in_pVal) == 0)
210  {
211  return;
212  }
213 
214  // do a limited spin on-the-spot until in_pVal hits zero
215  AkLimitedSpinForZero(in_pVal);
216 
217  // if in_pVal is still non-zero, then the other thread is either blocked or waiting for us. Yield for real.
218  while (AkAtomicLoad32(in_pVal))
219  AkThreadYield();
220  }
221 
222  // Waits for a limited amount of time for in_pVal to get atomically shift from 0 to 1
223  inline void AkSpinToAcquire(AkAtomic32* in_pVal, AkInt32 in_proposed, AkInt32 in_expected)
224  {
225  // do a limited spin on-the-spot until in_pVal can successfully hit 1
226  // or if it fails, then the other thread is either blocked or waiting for us. Yield for real.
227  while (!AkLimitedSpinToAcquire(in_pVal, in_proposed, in_expected))
228  {
229  AkThreadYield();
230  }
231  }
232 }
233 #endif
234 
235 #ifndef AK_PERF_RECORDING_RESET
236 #define AK_PERF_RECORDING_RESET()
237 #endif
238 #ifndef AK_PERF_RECORDING_START
239 #define AK_PERF_RECORDING_START( __StorageName__, __uExecutionCountStart__, __uExecutionCountStop__ )
240 #endif
241 #ifndef AK_PERF_RECORDING_STOP
242 #define AK_PERF_RECORDING_STOP( __StorageName__, __uExecutionCountStart__, __uExecutionCountStop__ )
243 #endif
244 
245 #endif // _AK_TOOLS_COMMON_AKPLATFORMFUNCS_H
void AkSpinHint()
Definition: AkAtomic.h:36
AkForceInline void AkMemMove(void *pDest, const void *pSrc, AkUInt32 uSize)
int nPriority
Thread priority.
Platform-dependent helpers.
Definition: AkBitFuncs.h:43
__forceinline int AkAtomicCas32(AkAtomic32 *pDest, long proposed, long expected)
Definition: AkAtomic.h:68
#define AK_THREAD_PRIORITY_ABOVE_NORMAL
int32_t AkInt32
Signed 32-bit integer.
void PerformanceCounter(AkInt64 *out_piLastTime)
Platform Independent Helper.
volatile uint32_t AkAtomic32
Definition: AkAtomic.h:45
AkForceInline void AkMemCpy(void *pDest, const void *pSrc, AkUInt32 uSize)
Platform Independent Helper for memcpy/memmove/memset.
AkForceInline void AkGetDefaultThreadProperties(AkThreadProperties &out_threadProperties)
Platform Independent Helper.
void AkLimitedSpinForZero(AkAtomic32 *in_pVal)
bool AkLimitedSpinToAcquire(AkAtomic32 *in_pVal, AkInt32 in_proposed, AkInt32 in_expected)
AkReal32 g_fFreqRatio
void AkGetDefaultHighPriorityThreadProperties(AkThreadProperties &out_threadProperties)
int64_t AkInt64
Signed 64-bit integer.
void AkSpinToAcquire(AkAtomic32 *in_pVal, AkInt32 in_proposed, AkInt32 in_expected)
#define AkThreadYield()
Definition: AkAtomic.h:34
void AkSpinWaitForZero(AkAtomic32 *in_pVal)
uint32_t AkUInt32
Unsigned 32-bit integer.
AkForceInline void AkMemSet(void *pDest, AkInt32 iVal, AkUInt32 uSize)
#define AkForceInline
Definition: AkTypes.h:63
__forceinline long AkAtomicLoad32(AkAtomic32 *pSrc)
Definition: AkAtomic.h:58

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