Version
menu_open
link
Wwise SDK 2023.1.3
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_WIN)
43 
44 #elif defined (AK_XBOX)
46 
47 #elif defined (AK_APPLE)
49 #include <AK/Tools/POSIX/AkPlatformFuncs.h>
50 
51 #elif defined( AK_ANDROID ) || defined ( AK_LINUX_AOSP )
53 
54 #elif defined (AK_PS4)
56 
57 #elif defined (AK_PS5)
59 
60 #elif defined (AK_EMSCRIPTEN)
62 
63 #elif defined (AK_LINUX)
65 #include <AK/Tools/POSIX/AkPlatformFuncs.h>
66 
67 #elif defined (AK_QNX)
68 #include <AK/Tools/QNX/AkPlatformFuncs.h>
69 #include <AK/Tools/POSIX/AkPlatformFuncs.h>
70 
71 #elif defined (AK_NX)
73 
74 #else
75 #error AkPlatformFuncs.h: Undefined platform
76 #endif
77 
78 #ifndef AkPrefetchZero
79 #define AkPrefetchZero(___Dest, ___Size)
80 #endif
81 
82 #ifndef AkPrefetchZeroAligned
83 #define AkPrefetchZeroAligned(___Dest, ___Size)
84 #endif
85 
86 #ifndef AkZeroMemAligned
87 #define AkZeroMemAligned(___Dest, ___Size) AKPLATFORM::AkMemSet(___Dest, 0, ___Size);
88 #endif
89 #ifndef AkZeroMemLarge
90 #define AkZeroMemLarge(___Dest, ___Size) AKPLATFORM::AkMemSet(___Dest, 0, ___Size);
91 #endif
92 #ifndef AkZeroMemSmall
93 #define AkZeroMemSmall(___Dest, ___Size) AKPLATFORM::AkMemSet(___Dest, 0, ___Size);
94 #endif
95 
96 #ifndef AkAllocaSIMD
97 #ifdef __clang__
98 #if __has_builtin( __builtin_alloca_with_align )
99 #define AkAllocaSIMD( _size_ ) __builtin_alloca_with_align( _size_, 128 )
100 #else
101 // work around alloca alignment issues in versions of clang before 4.0
102 #define AkAllocaSIMD( _size_ ) (void*)( ( ( uintptr_t )AkAlloca( _size_ + 16 ) + 0xF ) & ~0xF )
103 #endif
104 #else
105 #define AkAllocaSIMD( _size_ ) AkAlloca( _size_ )
106 #endif
107 #endif
108 
109 #ifndef AK_THREAD_INIT_CODE
110 #define AK_THREAD_INIT_CODE(_threadProperties)
111 #endif
112 
113 /// Platform-dependent helpers
114 namespace AKPLATFORM
115 {
117  {
118  AkGetDefaultThreadProperties(out_threadProperties);
119  out_threadProperties.nPriority = AK_THREAD_PRIORITY_ABOVE_NORMAL;
120  }
121 
122  // fallback implementations for when platform don't have their own implementation
123 #if !defined(AK_LIMITEDSPINFORZERO)
124  // Waits for a limited amount of time for in_pVal to hit zero (without yielding the thread)
125  inline void AkLimitedSpinForZero(AkAtomic32* in_pVal)
126  {
127  AkInt64 endSpinTime = 0;
128  AkInt64 currentTime = 0;
129  PerformanceCounter(&endSpinTime);
130  endSpinTime += AkInt64(AK::g_fFreqRatio * 0.01); // only spin for about 10us
131  while (true)
132  {
133  // if pval is zero, skip out
134  if (AkAtomicLoad32(in_pVal) == 0)
135  {
136  break;
137  }
138  AkSpinHint();
139 
140  // Check if we've hit the deadline for the timeout
141  PerformanceCounter(&currentTime);
142  if (currentTime > endSpinTime)
143  {
144  break;
145  }
146  }
147  }
148 
149  // Waits for a limited amount of time for in_pVal to get atomically shift from the expected value to the proposed one
150  // returns true if acquisition succeeded
151  inline bool AkLimitedSpinToAcquire(AkAtomic32* in_pVal, AkInt32 in_proposed, AkInt32 in_expected)
152  {
153  if (AkAtomicCas32(in_pVal, in_proposed, in_expected))
154  {
155  return true;
156  }
157 
158  // Cas failed, start the slower evaluation
159  AkInt64 endSpinTime = 0;
160  AkInt64 currentTime = 0;
161  PerformanceCounter(&endSpinTime);
162  endSpinTime += AkInt64(AK::g_fFreqRatio * 0.01); // only spin for about 10us
163  while (true)
164  {
165  // attempt cas to acquire and if successful, skip out
166  if (AkAtomicCas32(in_pVal, in_proposed, in_expected))
167  {
168  return true;
169  }
170  AkSpinHint();
171 
172  // Check if we've hit the deadline for the timeout
173  PerformanceCounter(&currentTime);
174  if (currentTime > endSpinTime)
175  {
176  return false;
177  }
178  }
179  }
180 #endif // !defined(AK_LIMITEDSPINFORZERO)
181 
182  inline void AkSpinWaitForZero(AkAtomic32* in_pVal)
183  {
184  if (AkAtomicLoad32(in_pVal) == 0)
185  {
186  return;
187  }
188 
189  // do a limited spin on-the-spot until in_pVal hits zero
190  AkLimitedSpinForZero(in_pVal);
191 
192  // if in_pVal is still non-zero, then the other thread is either blocked or waiting for us. Yield for real.
193  while (AkAtomicLoad32(in_pVal))
194  AkThreadYield();
195  }
196 
197  // Waits for a limited amount of time for in_pVal to get atomically shift from 0 to 1
198  inline void AkSpinToAcquire(AkAtomic32* in_pVal, AkInt32 in_proposed, AkInt32 in_expected)
199  {
200  // do a limited spin on-the-spot until in_pVal can successfully hit 1
201  // or if it fails, then the other thread is either blocked or waiting for us. Yield for real.
202  while (!AkLimitedSpinToAcquire(in_pVal, in_proposed, in_expected))
203  {
204  AkThreadYield();
205  }
206  }
207 }
208 
209 #ifndef AK_PERF_RECORDING_RESET
210 #define AK_PERF_RECORDING_RESET()
211 #endif
212 #ifndef AK_PERF_RECORDING_START
213 #define AK_PERF_RECORDING_START( __StorageName__, __uExecutionCountStart__, __uExecutionCountStop__ )
214 #endif
215 #ifndef AK_PERF_RECORDING_STOP
216 #define AK_PERF_RECORDING_STOP( __StorageName__, __uExecutionCountStart__, __uExecutionCountStop__ )
217 #endif
218 
219 #endif // _AK_TOOLS_COMMON_AKPLATFORMFUNCS_H
void AkSpinHint()
Definition: AkAtomic.h:36
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 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)
__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