From 0ee1fbbe7fe322a8e34cae345ca13161253ade18 Mon Sep 17 00:00:00 2001 From: Hamilton Date: Wed, 8 Dec 2021 16:59:18 -0800 Subject: [PATCH 01/16] Realtime thread registration You must call AERealtimeWatchdogStartMonitoring and AERealtimeWatchdogStopMonitoring at the beginning and end of any coreAudio realtime thread. All this does is set the static thread pointer to the address of the CoreAudio thread. It's not as simple as dropping the library into a project and it magically working, like before, but performance is increased by a large amount if you call lots of obj-c (a quick profile run showed about 10% cpu savings). Uncomment #define USE_WATCHDOG_REGISTRATION_FUNCTIONS 1 to try it out. --- RealtimeWatchdog.xcodeproj/project.pbxproj | 10 ++- RealtimeWatchdog/AERealtimeWatchdog-arm64.s | 2 + .../AERealtimeWatchdog-simulator-x86_64.s | 1 + RealtimeWatchdog/AERealtimeWatchdog.h | 3 + RealtimeWatchdog/AERealtimeWatchdog.m | 6 ++ RealtimeWatchdog/AERealtimeWatchdogExt.h | 55 ++++++++++++++++ RealtimeWatchdog/AERealtimeWatchdogExt.m | 65 +++++++++++++++++++ 7 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 RealtimeWatchdog/AERealtimeWatchdogExt.h create mode 100644 RealtimeWatchdog/AERealtimeWatchdogExt.m diff --git a/RealtimeWatchdog.xcodeproj/project.pbxproj b/RealtimeWatchdog.xcodeproj/project.pbxproj index 7aae1b0..68e4d7f 100644 --- a/RealtimeWatchdog.xcodeproj/project.pbxproj +++ b/RealtimeWatchdog.xcodeproj/project.pbxproj @@ -11,6 +11,8 @@ 4C636E421D0D87AF005A380B /* AERealtimeWatchdog-simulator-x86_64.s in Sources */ = {isa = PBXBuildFile; fileRef = 4C636E3E1D0D87AF005A380B /* AERealtimeWatchdog-simulator-x86_64.s */; settings = {COMPILER_FLAGS = "-fno-modules"; }; }; 4C636E431D0D87AF005A380B /* AERealtimeWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C636E401D0D87AF005A380B /* AERealtimeWatchdog.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 4C636E461D0D882E005A380B /* AERealtimeWatchdog.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C636E3F1D0D87AF005A380B /* AERealtimeWatchdog.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A40738DF271A3EC100C636FB /* AERealtimeWatchdogExt.m in Sources */ = {isa = PBXBuildFile; fileRef = A40738DE271A3EC100C636FB /* AERealtimeWatchdogExt.m */; }; + A43D51A827212EDF00C931B1 /* AERealtimeWatchdogExt.h in Headers */ = {isa = PBXBuildFile; fileRef = A40738DD271A339600C636FB /* AERealtimeWatchdogExt.h */; settings = {ATTRIBUTES = (Public, ); }; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -19,6 +21,8 @@ 4C636E3E1D0D87AF005A380B /* AERealtimeWatchdog-simulator-x86_64.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = "AERealtimeWatchdog-simulator-x86_64.s"; sourceTree = ""; }; 4C636E3F1D0D87AF005A380B /* AERealtimeWatchdog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AERealtimeWatchdog.h; sourceTree = ""; }; 4C636E401D0D87AF005A380B /* AERealtimeWatchdog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AERealtimeWatchdog.m; sourceTree = ""; }; + A40738DD271A339600C636FB /* AERealtimeWatchdogExt.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AERealtimeWatchdogExt.h; sourceTree = ""; }; + A40738DE271A3EC100C636FB /* AERealtimeWatchdogExt.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AERealtimeWatchdogExt.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -55,6 +59,8 @@ 4C636E3E1D0D87AF005A380B /* AERealtimeWatchdog-simulator-x86_64.s */, 4C636E3F1D0D87AF005A380B /* AERealtimeWatchdog.h */, 4C636E401D0D87AF005A380B /* AERealtimeWatchdog.m */, + A40738DD271A339600C636FB /* AERealtimeWatchdogExt.h */, + A40738DE271A3EC100C636FB /* AERealtimeWatchdogExt.m */, ); path = RealtimeWatchdog; sourceTree = ""; @@ -67,6 +73,7 @@ buildActionMask = 2147483647; files = ( 4C636E461D0D882E005A380B /* AERealtimeWatchdog.h in Headers */, + A43D51A827212EDF00C931B1 /* AERealtimeWatchdogExt.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -96,7 +103,7 @@ 4C636E291D0D878B005A380B /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1250; + LastUpgradeCheck = 1310; ORGANIZATIONNAME = "A Tasty Pixel"; TargetAttributes = { 4C636E301D0D878B005A380B = { @@ -127,6 +134,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + A40738DF271A3EC100C636FB /* AERealtimeWatchdogExt.m in Sources */, 4C636E421D0D87AF005A380B /* AERealtimeWatchdog-simulator-x86_64.s in Sources */, 4C636E431D0D87AF005A380B /* AERealtimeWatchdog.m in Sources */, 4C636E411D0D87AF005A380B /* AERealtimeWatchdog-arm64.s in Sources */, diff --git a/RealtimeWatchdog/AERealtimeWatchdog-arm64.s b/RealtimeWatchdog/AERealtimeWatchdog-arm64.s index 77738e4..612f4ea 100644 --- a/RealtimeWatchdog/AERealtimeWatchdog-arm64.s +++ b/RealtimeWatchdog/AERealtimeWatchdog-arm64.s @@ -43,6 +43,8 @@ * limitations under the License. */ +#define REALTIME_WATCHDOG_INCLUDED_BY_ASM 1 + #include "AERealtimeWatchdog.h" #if __arm64__ && REALTIME_WATCHDOG_ENABLED diff --git a/RealtimeWatchdog/AERealtimeWatchdog-simulator-x86_64.s b/RealtimeWatchdog/AERealtimeWatchdog-simulator-x86_64.s index f1d6036..decf3a4 100644 --- a/RealtimeWatchdog/AERealtimeWatchdog-simulator-x86_64.s +++ b/RealtimeWatchdog/AERealtimeWatchdog-simulator-x86_64.s @@ -43,6 +43,7 @@ * limitations under the License. */ +#define REALTIME_WATCHDOG_INCLUDED_BY_ASM 1 #include #include "AERealtimeWatchdog.h" diff --git a/RealtimeWatchdog/AERealtimeWatchdog.h b/RealtimeWatchdog/AERealtimeWatchdog.h index da9d6e9..16a5783 100644 --- a/RealtimeWatchdog/AERealtimeWatchdog.h +++ b/RealtimeWatchdog/AERealtimeWatchdog.h @@ -31,3 +31,6 @@ #define REALTIME_WATCHDOG_ENABLED 1 #endif + + +#import "AERealtimeWatchdogExt.h" diff --git a/RealtimeWatchdog/AERealtimeWatchdog.m b/RealtimeWatchdog/AERealtimeWatchdog.m index af4a215..ef77d98 100755 --- a/RealtimeWatchdog/AERealtimeWatchdog.m +++ b/RealtimeWatchdog/AERealtimeWatchdog.m @@ -58,6 +58,8 @@ static void AERealtimeWatchdogUnsafeActivityWarning(const char * activity) { } +pthread_t sAERealtimeThread = 0; + BOOL AERealtimeWatchdogIsOnRealtimeThread(void) { pthread_t thread = pthread_self(); @@ -67,6 +69,10 @@ BOOL AERealtimeWatchdogIsOnRealtimeThread(void) { if ( pthread_getschedparam(thread, &policy, ¶m) == 0 && param.sched_priority >= sched_get_priority_max(policy) ) { return YES; } +#elif defined(USE_WATCHDOG_REGISTRATION_FUNCTIONS) // Trying a thread registration test + if (sAERealtimeThread == thread) { + return YES; + } #else char name[21]; if ( pthread_getname_np(thread, name, sizeof(name)) == 0 && !strcmp(name, "AURemoteIO::IOThread") ) { diff --git a/RealtimeWatchdog/AERealtimeWatchdogExt.h b/RealtimeWatchdog/AERealtimeWatchdogExt.h new file mode 100644 index 0000000..2e7d642 --- /dev/null +++ b/RealtimeWatchdog/AERealtimeWatchdogExt.h @@ -0,0 +1,55 @@ +// +// AERealtimeWatchdogMonitor.h +// TheAmazingAudioEngine +// +// Created by Michael Tyson on 12/06/2016. +// Idea by Taylor Holliday +// Copyright © 2016 A Tasty Pixel. All rights reserved. +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// + +// Uncomment the following to use the thread registration functions. You must call +// AERealtimeWatchdogStartMonitoring and AERealtimeWatchdogStopMonitoring from the realtime thread. +//#define USE_WATCHDOG_REGISTRATION_FUNCTIONS 1 + + +#if !(REALTIME_WATCHDOG_INCLUDED_BY_ASM) +#if (REALTIME_WATCHDOG_ENABLED && USE_WATCHDOG_REGISTRATION_FUNCTIONS) + +#if defined(__cplusplus) +extern "C" { +#endif + // Call this at the very top of the playback and record callbacks + void AERealtimeWatchdogStartMonitoring(void); + // Call this at the very end of the playback and record callbacks + void AERealtimeWatchdogStopMonitoring(void); +#if defined(__cplusplus) +} +#endif + +#else // !REALTIME_WATCHDOG_ENABLED + + // Stubbed out for release + static inline void AERealtimeWatchdogStartMonitoring(void) {}; + static inline void AERealtimeWatchdogStopMonitoring(void) {}; + +#endif // REALTIME_WATCHDOG_ENABLED +#endif // REALTIME_WATCHDOG_INCLUDED_BY_ASM + diff --git a/RealtimeWatchdog/AERealtimeWatchdogExt.m b/RealtimeWatchdog/AERealtimeWatchdogExt.m new file mode 100644 index 0000000..ea4af2c --- /dev/null +++ b/RealtimeWatchdog/AERealtimeWatchdogExt.m @@ -0,0 +1,65 @@ +// +// AERealtimeWatchdogMonitor.h +// TheAmazingAudioEngine +// +// Created by Michael Tyson on 12/06/2016. +// Idea by Taylor Holliday +// Copyright © 2016 A Tasty Pixel. All rights reserved. +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// + +#import +#import +#import + +#import "AERealtimeWatchdog.h" + +#if (REALTIME_WATCHDOG_ENABLED && USE_WATCHDOG_REGISTRATION_FUNCTIONS) + + +extern pthread_t sAERealtimeThread; + + +// Call this at the very top of the playback and record callbacks +void AERealtimeWatchdogStartMonitoring(void) { + pthread_t thread = pthread_self(); + + // All we really need is to assign sAERealtimeThread, but do a few sanity checks + char name[21]; + if ( pthread_getname_np(thread, name, sizeof(name)) == 0 && !strcmp(name, "AURemoteIO::IOThread") ) { + if (sAERealtimeThread != NULL) { + printf("AERealtimeWatchdog: Unmatched start/stop!\n"); + } + sAERealtimeThread = thread; + } else { + printf("AERealtimeWatchdog: %s not called from the realtime thread!\n", __FUNCTION__); + sAERealtimeThread = NULL; + } +} + +// Call this at the very end of the playback and record callbacks +void AERealtimeWatchdogStopMonitoring(void) { + if (sAERealtimeThread == NULL) { + printf("AERealtimeWatchdog: Unmatched start/stop!\n"); + } + sAERealtimeThread = NULL; +} + +#endif From 41fa30495e19d971b45163a5b2432e741fce4693 Mon Sep 17 00:00:00 2001 From: Michael Tyson Date: Wed, 22 Sep 2021 13:23:54 +1000 Subject: [PATCH 02/16] Removed dispatch_semaphore_signal (this is actually RT safe) Originally added by @pwnified in 26a14d04 --- RealtimeWatchdog/AERealtimeWatchdog.m | 6 ------ 1 file changed, 6 deletions(-) diff --git a/RealtimeWatchdog/AERealtimeWatchdog.m b/RealtimeWatchdog/AERealtimeWatchdog.m index ef77d98..56b8e97 100755 --- a/RealtimeWatchdog/AERealtimeWatchdog.m +++ b/RealtimeWatchdog/AERealtimeWatchdog.m @@ -140,7 +140,6 @@ typedef ssize_t (*recvfrom_t)(int socket, void *restrict buffer, size_t length, typedef dispatch_semaphore_t (*dispatch_semaphore_create_t)(long value); typedef long (*dispatch_semaphore_wait_t)(dispatch_semaphore_t dsema, dispatch_time_t timeout); -typedef long (*dispatch_semaphore_signal_t)(dispatch_semaphore_t dsema); // Overrides @@ -389,9 +388,4 @@ long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout return funcptr(dsema, timeout); } -long dispatch_semaphore_signal(dispatch_semaphore_t dsema) { - CHECK_FUNCTION(dispatch_semaphore_signal); - return funcptr(dsema); -} - #endif From c0ea897e47978e47614be62fd0cc7f5aee578c1c Mon Sep 17 00:00:00 2001 From: Michael Tyson Date: Thu, 24 Mar 2022 12:00:40 +1100 Subject: [PATCH 03/16] Xcode version update --- RealtimeWatchdog.xcodeproj/project.pbxproj | 6 +++--- .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 RealtimeWatchdog.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/RealtimeWatchdog.xcodeproj/project.pbxproj b/RealtimeWatchdog.xcodeproj/project.pbxproj index 68e4d7f..9e49d26 100644 --- a/RealtimeWatchdog.xcodeproj/project.pbxproj +++ b/RealtimeWatchdog.xcodeproj/project.pbxproj @@ -103,7 +103,7 @@ 4C636E291D0D878B005A380B /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1310; + LastUpgradeCheck = 1330; ORGANIZATIONNAME = "A Tasty Pixel"; TargetAttributes = { 4C636E301D0D878B005A380B = { @@ -193,7 +193,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; PUBLIC_HEADERS_FOLDER_PATH = "$(PROJECT_NAME)"; @@ -244,7 +244,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; PUBLIC_HEADERS_FOLDER_PATH = "$(PROJECT_NAME)"; SDKROOT = iphoneos; diff --git a/RealtimeWatchdog.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/RealtimeWatchdog.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/RealtimeWatchdog.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + From e799b4223e9b8c3f35912762ddfff279daf0bf6a Mon Sep 17 00:00:00 2001 From: Michael Tyson Date: Thu, 24 Mar 2022 12:01:10 +1100 Subject: [PATCH 04/16] Added objc_loadWeakRetained and objc_retainAutoreleasedReturnValue to watch list --- RealtimeWatchdog/AERealtimeWatchdog.m | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/RealtimeWatchdog/AERealtimeWatchdog.m b/RealtimeWatchdog/AERealtimeWatchdog.m index 56b8e97..aad6e6a 100755 --- a/RealtimeWatchdog/AERealtimeWatchdog.m +++ b/RealtimeWatchdog/AERealtimeWatchdog.m @@ -100,7 +100,9 @@ BOOL AERealtimeWatchdogIsOnRealtimeThread(void) { typedef int (*objc_sync_enter_t)(id obj); typedef id (*objc_storeStrong_t)(id *object, id value); typedef id (*objc_loadWeak_t)(id *object); +typedef id (*objc_loadWeakRetained_t)(id *object); typedef id (*objc_storeWeak_t)(id *object, id value); +typedef id (*objc_retainAutoreleasedReturnValue_t)(id *object, id value); typedef id (*object_getIvar_t)(id object, Ivar ivar); typedef id (*objc_msgSend_t)(void); typedef ssize_t (*send_t)(int socket, const void *buffer, size_t length, int flags); @@ -205,12 +207,24 @@ id objc_loadWeak(id * object) { return funcptr(object); } +id objc_loadWeakRetained(id * object); +id objc_loadWeakRetained(id * object) { + CHECK_FUNCTION_MSG(objc_loadWeakRetained, "weak load"); + return funcptr(object); +} + id objc_storeWeak(id * object, id value); id objc_storeWeak(id * object, id value) { CHECK_FUNCTION_MSG(objc_storeWeak, "weak store"); return funcptr(object,value); } +id objc_retainAutoreleasedReturnValue(id * object, id value); +id objc_retainAutoreleasedReturnValue(id * object, id value) { + CHECK_FUNCTION_MSG(objc_retainAutoreleasedReturnValue, "retain autoreleased return value"); + return funcptr(object,value); +} + id object_getIvar(id object, Ivar value); id object_getIvar(id object, Ivar value) { CHECK_FUNCTION_MSG(object_getIvar, "ivar fetch"); From deddb6cb6be1cb3ffbb7c1f22e51d3035b5fdde8 Mon Sep 17 00:00:00 2001 From: Michael Tyson Date: Thu, 24 Mar 2022 12:01:29 +1100 Subject: [PATCH 05/16] Added AERealtimeWatchdogPause/Resume utilities --- RealtimeWatchdog/AERealtimeWatchdog.h | 13 +++++++++++++ RealtimeWatchdog/AERealtimeWatchdog.m | 20 +++++++++++++------- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/RealtimeWatchdog/AERealtimeWatchdog.h b/RealtimeWatchdog/AERealtimeWatchdog.h index 16a5783..aed0a83 100644 --- a/RealtimeWatchdog/AERealtimeWatchdog.h +++ b/RealtimeWatchdog/AERealtimeWatchdog.h @@ -32,5 +32,18 @@ #endif +#ifndef __ASSEMBLER__ + +/*! + * Pause monitoring until AERealtimeWatchdogResume called + */ +void AERealtimeWatchdogPause(void); + +/*! + * Resume monitoring + */ +void AERealtimeWatchdogResume(void); + +#endif #import "AERealtimeWatchdogExt.h" diff --git a/RealtimeWatchdog/AERealtimeWatchdog.m b/RealtimeWatchdog/AERealtimeWatchdog.m index aad6e6a..80dfdc9 100755 --- a/RealtimeWatchdog/AERealtimeWatchdog.m +++ b/RealtimeWatchdog/AERealtimeWatchdog.m @@ -26,11 +26,22 @@ // #import "AERealtimeWatchdog.h" +#import + +static BOOL __paused = NO; + +void AERealtimeWatchdogPause(void) { + __paused = YES; +} + +void AERealtimeWatchdogResume(void) { + __paused = NO; +} + #ifdef REALTIME_WATCHDOG_ENABLED #import #import -#import #import #import #include @@ -40,8 +51,6 @@ //#define REPORT_EVERY_INFRACTION - - static void AERealtimeWatchdogUnsafeActivityWarning(const char * activity) { #ifndef REPORT_EVERY_INFRACTION static BOOL once = NO; @@ -84,9 +93,6 @@ BOOL AERealtimeWatchdogIsOnRealtimeThread(void) { } - - - #pragma mark - Overrides // Signatures for the functions we'll override @@ -151,7 +157,7 @@ typedef ssize_t (*recvfrom_t)(int socket, void *restrict buffer, size_t length, dispatch_once(&onceToken, ^{ \ funcptr = (name##_t) dlsym(RTLD_NEXT, #name); \ }); \ - if ( AERealtimeWatchdogIsOnRealtimeThread() ) AERealtimeWatchdogUnsafeActivityWarning(msg); + if ( !__paused && AERealtimeWatchdogIsOnRealtimeThread() ) AERealtimeWatchdogUnsafeActivityWarning(msg); #define CHECK_FUNCTION(name) CHECK_FUNCTION_MSG(name, #name) From 4d41b33a64f68c29ede2e407a04a99434b03b792 Mon Sep 17 00:00:00 2001 From: Michael Tyson Date: Thu, 24 Mar 2022 12:02:25 +1100 Subject: [PATCH 06/16] Updated podspec --- RealtimeWatchdog.podspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RealtimeWatchdog.podspec b/RealtimeWatchdog.podspec index 523be64..6ff5af4 100644 --- a/RealtimeWatchdog.podspec +++ b/RealtimeWatchdog.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "RealtimeWatchdog" - s.version = "1.0.2" + s.version = "1.0.3" s.summary = "A library for iOS audio which acts as a watchdog for unsafe activity on the audio thread." s.description = <<-DESC This library for iOS acts as a watchdog for activities on the Core Audio thread that are considered unsafe: @@ -17,7 +17,7 @@ It won’t catch everything, and it won’t catch anything in Apple’s own syst s.homepage = "https://github.com/TheAmazingAudioEngine/RealtimeWatchdog" s.license = 'zlib' s.author = { "Michael Tyson" => "michael@atastypixel.com" } - s.source = { :git => "https://github.com/TheAmazingAudioEngine/RealtimeWatchdog.git", :tag => "1.0.2" } + s.source = { :git => "https://github.com/TheAmazingAudioEngine/RealtimeWatchdog.git", :tag => "1.0.3" } s.ios.deployment_target = '9.0' s.source_files = 'RealtimeWatchdog/*' s.pod_target_xcconfig = { 'OTHER_CFLAGS' => '-fno-modules' } From b1d453cefac7814c38f6bbc23537614cc5faef3e Mon Sep 17 00:00:00 2001 From: Hamilton Date: Wed, 8 Dec 2021 16:59:18 -0800 Subject: [PATCH 07/16] Realtime thread registration You must call AERealtimeWatchdogStartMonitoring and AERealtimeWatchdogStopMonitoring at the beginning and end of any coreAudio realtime thread. All this does is set the static thread pointer to the address of the CoreAudio thread. It's not as simple as dropping the library into a project and it magically working, like before, but performance is increased by a large amount if you call lots of obj-c (a quick profile run showed about 10% cpu savings). Uncomment #define USE_WATCHDOG_REGISTRATION_FUNCTIONS 1 to try it out. --- RealtimeWatchdog/AERealtimeWatchdog.h | 2 ++ RealtimeWatchdog/AERealtimeWatchdogExt.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/RealtimeWatchdog/AERealtimeWatchdog.h b/RealtimeWatchdog/AERealtimeWatchdog.h index aed0a83..1570ffc 100644 --- a/RealtimeWatchdog/AERealtimeWatchdog.h +++ b/RealtimeWatchdog/AERealtimeWatchdog.h @@ -34,6 +34,8 @@ #ifndef __ASSEMBLER__ +#import "AERealtimeWatchdogExt.h" + /*! * Pause monitoring until AERealtimeWatchdogResume called */ diff --git a/RealtimeWatchdog/AERealtimeWatchdogExt.h b/RealtimeWatchdog/AERealtimeWatchdogExt.h index 2e7d642..011e5ca 100644 --- a/RealtimeWatchdog/AERealtimeWatchdogExt.h +++ b/RealtimeWatchdog/AERealtimeWatchdogExt.h @@ -30,7 +30,7 @@ //#define USE_WATCHDOG_REGISTRATION_FUNCTIONS 1 -#if !(REALTIME_WATCHDOG_INCLUDED_BY_ASM) +#ifndef __ASSEMBLER__ #if (REALTIME_WATCHDOG_ENABLED && USE_WATCHDOG_REGISTRATION_FUNCTIONS) #if defined(__cplusplus) From 2e5acc5a5cff54953c7738a3c6ff7f6c5f5da99e Mon Sep 17 00:00:00 2001 From: Hamilton Date: Thu, 7 Apr 2022 16:48:36 -0700 Subject: [PATCH 08/16] Realtime thread registration You must call AERealtimeWatchdogStartMonitoring and AERealtimeWatchdogStopMonitoring at the beginning and end of any coreAudio realtime thread. All this does is set the static thread pointer to the address of the CoreAudio thread. It's not as simple as dropping the library into a project and it magically working, like before, but performance is increased by a large amount if you call lots of obj-c (a quick profile run showed about 10% cpu savings). Uncomment #define USE_WATCHDOG_REGISTRATION_FUNCTIONS 1 to try it out. --- RealtimeWatchdog/AERealtimeWatchdog.h | 1 - 1 file changed, 1 deletion(-) diff --git a/RealtimeWatchdog/AERealtimeWatchdog.h b/RealtimeWatchdog/AERealtimeWatchdog.h index 1570ffc..2aa6bc5 100644 --- a/RealtimeWatchdog/AERealtimeWatchdog.h +++ b/RealtimeWatchdog/AERealtimeWatchdog.h @@ -48,4 +48,3 @@ void AERealtimeWatchdogResume(void); #endif -#import "AERealtimeWatchdogExt.h" From 4dbe5a02bda4b17d666df270e1dbf33ac0561aac Mon Sep 17 00:00:00 2001 From: Hamilton Date: Thu, 7 Apr 2022 16:50:34 -0700 Subject: [PATCH 09/16] Merge conflicts --- RealtimeWatchdog/AERealtimeWatchdog-arm64.s | 2 -- RealtimeWatchdog/AERealtimeWatchdog-simulator-x86_64.s | 2 -- 2 files changed, 4 deletions(-) diff --git a/RealtimeWatchdog/AERealtimeWatchdog-arm64.s b/RealtimeWatchdog/AERealtimeWatchdog-arm64.s index 612f4ea..77738e4 100644 --- a/RealtimeWatchdog/AERealtimeWatchdog-arm64.s +++ b/RealtimeWatchdog/AERealtimeWatchdog-arm64.s @@ -43,8 +43,6 @@ * limitations under the License. */ -#define REALTIME_WATCHDOG_INCLUDED_BY_ASM 1 - #include "AERealtimeWatchdog.h" #if __arm64__ && REALTIME_WATCHDOG_ENABLED diff --git a/RealtimeWatchdog/AERealtimeWatchdog-simulator-x86_64.s b/RealtimeWatchdog/AERealtimeWatchdog-simulator-x86_64.s index decf3a4..40286e4 100644 --- a/RealtimeWatchdog/AERealtimeWatchdog-simulator-x86_64.s +++ b/RealtimeWatchdog/AERealtimeWatchdog-simulator-x86_64.s @@ -43,8 +43,6 @@ * limitations under the License. */ -#define REALTIME_WATCHDOG_INCLUDED_BY_ASM 1 - #include #include "AERealtimeWatchdog.h" #if __x86_64__ && TARGET_OS_SIMULATOR && REALTIME_WATCHDOG_ENABLED From 57214746dc5cfc22846f1fd2b6c7d3c8f61d06ee Mon Sep 17 00:00:00 2001 From: Hamilton Date: Tue, 24 May 2022 17:09:45 -0700 Subject: [PATCH 10/16] Xcode noise --- RealtimeWatchdog.xcodeproj/project.pbxproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RealtimeWatchdog.xcodeproj/project.pbxproj b/RealtimeWatchdog.xcodeproj/project.pbxproj index 9e49d26..80b74a4 100644 --- a/RealtimeWatchdog.xcodeproj/project.pbxproj +++ b/RealtimeWatchdog.xcodeproj/project.pbxproj @@ -103,7 +103,7 @@ 4C636E291D0D878B005A380B /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1330; + LastUpgradeCheck = 1340; ORGANIZATIONNAME = "A Tasty Pixel"; TargetAttributes = { 4C636E301D0D878B005A380B = { @@ -193,7 +193,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; PUBLIC_HEADERS_FOLDER_PATH = "$(PROJECT_NAME)"; @@ -244,7 +244,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; PUBLIC_HEADERS_FOLDER_PATH = "$(PROJECT_NAME)"; SDKROOT = iphoneos; From 1a8ffdbe7dc9774dd20b5f836db4bee8b1cf0a02 Mon Sep 17 00:00:00 2001 From: Hamilton Date: Wed, 7 Jun 2023 01:00:15 -0700 Subject: [PATCH 11/16] Support iOS app on mac The realtime audio thread has a different name on apple silicon. This uses the __attribute__((constructor)) to set the name on startup. --- RealtimeWatchdog.xcodeproj/project.pbxproj | 2 +- RealtimeWatchdog/AERealtimeWatchdog.m | 18 ++++++++++++++++-- RealtimeWatchdog/AERealtimeWatchdogExt.m | 6 +++--- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/RealtimeWatchdog.xcodeproj/project.pbxproj b/RealtimeWatchdog.xcodeproj/project.pbxproj index 80b74a4..2438dba 100644 --- a/RealtimeWatchdog.xcodeproj/project.pbxproj +++ b/RealtimeWatchdog.xcodeproj/project.pbxproj @@ -103,7 +103,7 @@ 4C636E291D0D878B005A380B /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1340; + LastUpgradeCheck = 1420; ORGANIZATIONNAME = "A Tasty Pixel"; TargetAttributes = { 4C636E301D0D878B005A380B = { diff --git a/RealtimeWatchdog/AERealtimeWatchdog.m b/RealtimeWatchdog/AERealtimeWatchdog.m index 80dfdc9..7515fe2 100755 --- a/RealtimeWatchdog/AERealtimeWatchdog.m +++ b/RealtimeWatchdog/AERealtimeWatchdog.m @@ -26,6 +26,7 @@ // #import "AERealtimeWatchdog.h" +#import #import static BOOL __paused = NO; @@ -67,6 +68,19 @@ static void AERealtimeWatchdogUnsafeActivityWarning(const char * activity) { } +char kAERealtimeWatchdogThreadName[64] = "AURemoteIO::IOThread"; + +void InitRealtimeThreadName(void) __attribute__((constructor)); +void InitRealtimeThreadName(void) { + if (@available(iOS 14.0, *)) { + if (NSProcessInfo.processInfo.isiOSAppOnMac) { + strncpy(kAERealtimeWatchdogThreadName, "com.apple.audio.IOThread.client", sizeof(kAERealtimeWatchdogThreadName)); + } + } +} + + + pthread_t sAERealtimeThread = 0; BOOL AERealtimeWatchdogIsOnRealtimeThread(void) { @@ -83,8 +97,8 @@ BOOL AERealtimeWatchdogIsOnRealtimeThread(void) { return YES; } #else - char name[21]; - if ( pthread_getname_np(thread, name, sizeof(name)) == 0 && !strcmp(name, "AURemoteIO::IOThread") ) { + char name[64]; + if ( pthread_getname_np(thread, name, sizeof(name)) == 0 && !strcmp(name, kAERealtimeWatchdogThreadName) ) { return YES; } #endif diff --git a/RealtimeWatchdog/AERealtimeWatchdogExt.m b/RealtimeWatchdog/AERealtimeWatchdogExt.m index ea4af2c..0ec8100 100644 --- a/RealtimeWatchdog/AERealtimeWatchdogExt.m +++ b/RealtimeWatchdog/AERealtimeWatchdogExt.m @@ -35,15 +35,15 @@ extern pthread_t sAERealtimeThread; - +extern char kAERealtimeWatchdogThreadName[64]; // Call this at the very top of the playback and record callbacks void AERealtimeWatchdogStartMonitoring(void) { pthread_t thread = pthread_self(); // All we really need is to assign sAERealtimeThread, but do a few sanity checks - char name[21]; - if ( pthread_getname_np(thread, name, sizeof(name)) == 0 && !strcmp(name, "AURemoteIO::IOThread") ) { + char name[64]; + if ( pthread_getname_np(thread, name, sizeof(name)) == 0 && !strcmp(name, kAERealtimeWatchdogThreadName) ) { if (sAERealtimeThread != NULL) { printf("AERealtimeWatchdog: Unmatched start/stop!\n"); } From 37f7e34409021208163ebb58ba617015a6488d3e Mon Sep 17 00:00:00 2001 From: Hamilton Date: Thu, 15 Jun 2023 16:58:54 -0700 Subject: [PATCH 12/16] Fix thread name for mac catalyst --- RealtimeWatchdog/AERealtimeWatchdog.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/RealtimeWatchdog/AERealtimeWatchdog.m b/RealtimeWatchdog/AERealtimeWatchdog.m index 7515fe2..fa6acc3 100755 --- a/RealtimeWatchdog/AERealtimeWatchdog.m +++ b/RealtimeWatchdog/AERealtimeWatchdog.m @@ -72,6 +72,11 @@ static void AERealtimeWatchdogUnsafeActivityWarning(const char * activity) { void InitRealtimeThreadName(void) __attribute__((constructor)); void InitRealtimeThreadName(void) { + if (@available(iOS 13.0, *)) { + if (NSProcessInfo.processInfo.isMacCatalystApp) { + strncpy(kAERealtimeWatchdogThreadName, "com.apple.audio.IOThread.client", sizeof(kAERealtimeWatchdogThreadName)); + } + } if (@available(iOS 14.0, *)) { if (NSProcessInfo.processInfo.isiOSAppOnMac) { strncpy(kAERealtimeWatchdogThreadName, "com.apple.audio.IOThread.client", sizeof(kAERealtimeWatchdogThreadName)); From 0d1c26c9cd33cd5f246475854c59f97b02b081d3 Mon Sep 17 00:00:00 2001 From: Hamilton Date: Mon, 24 Jul 2023 17:38:07 -0700 Subject: [PATCH 13/16] isMacCatalystApp replaced by TARGET_OS_MACCATALYST Unfortunately, processInfo.isiOSAppOnMac is still required for targets "My Mac (Designed for iPad)" --- RealtimeWatchdog/AERealtimeWatchdog.m | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/RealtimeWatchdog/AERealtimeWatchdog.m b/RealtimeWatchdog/AERealtimeWatchdog.m index fa6acc3..71a8602 100755 --- a/RealtimeWatchdog/AERealtimeWatchdog.m +++ b/RealtimeWatchdog/AERealtimeWatchdog.m @@ -67,16 +67,14 @@ static void AERealtimeWatchdogUnsafeActivityWarning(const char * activity) { #endif } - +#if TARGET_OS_MACCATALYST +char kAERealtimeWatchdogThreadName[64] = "com.apple.audio.IOThread.client"; +#else char kAERealtimeWatchdogThreadName[64] = "AURemoteIO::IOThread"; +#endif void InitRealtimeThreadName(void) __attribute__((constructor)); void InitRealtimeThreadName(void) { - if (@available(iOS 13.0, *)) { - if (NSProcessInfo.processInfo.isMacCatalystApp) { - strncpy(kAERealtimeWatchdogThreadName, "com.apple.audio.IOThread.client", sizeof(kAERealtimeWatchdogThreadName)); - } - } if (@available(iOS 14.0, *)) { if (NSProcessInfo.processInfo.isiOSAppOnMac) { strncpy(kAERealtimeWatchdogThreadName, "com.apple.audio.IOThread.client", sizeof(kAERealtimeWatchdogThreadName)); From 670800c8c5c8c3b366df906b610333741782b671 Mon Sep 17 00:00:00 2001 From: Hamilton Date: Sat, 6 Jan 2024 20:23:02 -0800 Subject: [PATCH 14/16] Xcode noise --- RealtimeWatchdog.xcodeproj/project.pbxproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RealtimeWatchdog.xcodeproj/project.pbxproj b/RealtimeWatchdog.xcodeproj/project.pbxproj index 2438dba..fe4c348 100644 --- a/RealtimeWatchdog.xcodeproj/project.pbxproj +++ b/RealtimeWatchdog.xcodeproj/project.pbxproj @@ -103,7 +103,7 @@ 4C636E291D0D878B005A380B /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1420; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = "A Tasty Pixel"; TargetAttributes = { 4C636E301D0D878B005A380B = { @@ -193,7 +193,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; PUBLIC_HEADERS_FOLDER_PATH = "$(PROJECT_NAME)"; @@ -244,7 +244,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; PUBLIC_HEADERS_FOLDER_PATH = "$(PROJECT_NAME)"; SDKROOT = iphoneos; From da1b7cec3ca0de180500b17b467d5fac8092b27a Mon Sep 17 00:00:00 2001 From: Hamilton Date: Thu, 16 May 2024 13:04:36 -0700 Subject: [PATCH 15/16] Use #ifdef not #if To better work with swift --- RealtimeWatchdog.xcodeproj/project.pbxproj | 2 +- RealtimeWatchdog/AERealtimeWatchdog.m | 1 + RealtimeWatchdog/AERealtimeWatchdogExt.h | 2 +- RealtimeWatchdog/AERealtimeWatchdogExt.m | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/RealtimeWatchdog.xcodeproj/project.pbxproj b/RealtimeWatchdog.xcodeproj/project.pbxproj index fe4c348..ae4f392 100644 --- a/RealtimeWatchdog.xcodeproj/project.pbxproj +++ b/RealtimeWatchdog.xcodeproj/project.pbxproj @@ -103,7 +103,7 @@ 4C636E291D0D878B005A380B /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1510; + LastUpgradeCheck = 1530; ORGANIZATIONNAME = "A Tasty Pixel"; TargetAttributes = { 4C636E301D0D878B005A380B = { diff --git a/RealtimeWatchdog/AERealtimeWatchdog.m b/RealtimeWatchdog/AERealtimeWatchdog.m index 71a8602..6bb9a46 100755 --- a/RealtimeWatchdog/AERealtimeWatchdog.m +++ b/RealtimeWatchdog/AERealtimeWatchdog.m @@ -73,6 +73,7 @@ static void AERealtimeWatchdogUnsafeActivityWarning(const char * activity) { char kAERealtimeWatchdogThreadName[64] = "AURemoteIO::IOThread"; #endif +// This function will be called before main() to set the thread name void InitRealtimeThreadName(void) __attribute__((constructor)); void InitRealtimeThreadName(void) { if (@available(iOS 14.0, *)) { diff --git a/RealtimeWatchdog/AERealtimeWatchdogExt.h b/RealtimeWatchdog/AERealtimeWatchdogExt.h index 011e5ca..d6d913c 100644 --- a/RealtimeWatchdog/AERealtimeWatchdogExt.h +++ b/RealtimeWatchdog/AERealtimeWatchdogExt.h @@ -31,7 +31,7 @@ #ifndef __ASSEMBLER__ -#if (REALTIME_WATCHDOG_ENABLED && USE_WATCHDOG_REGISTRATION_FUNCTIONS) +#if defined(REALTIME_WATCHDOG_ENABLED) && defined(USE_WATCHDOG_REGISTRATION_FUNCTIONS) #if defined(__cplusplus) extern "C" { diff --git a/RealtimeWatchdog/AERealtimeWatchdogExt.m b/RealtimeWatchdog/AERealtimeWatchdogExt.m index 0ec8100..0fabb12 100644 --- a/RealtimeWatchdog/AERealtimeWatchdogExt.m +++ b/RealtimeWatchdog/AERealtimeWatchdogExt.m @@ -31,7 +31,7 @@ #import "AERealtimeWatchdog.h" -#if (REALTIME_WATCHDOG_ENABLED && USE_WATCHDOG_REGISTRATION_FUNCTIONS) +#if defined(REALTIME_WATCHDOG_ENABLED) && defined(USE_WATCHDOG_REGISTRATION_FUNCTIONS) extern pthread_t sAERealtimeThread; From 2084a73cf6a266ece0385ba8f0446bdbbc5be4ad Mon Sep 17 00:00:00 2001 From: Hamilton Date: Wed, 19 Mar 2025 19:19:27 -0700 Subject: [PATCH 16/16] Match spaces/tabs --- RealtimeWatchdog.xcodeproj/project.pbxproj | 4 ++-- RealtimeWatchdog/AERealtimeWatchdog.m | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/RealtimeWatchdog.xcodeproj/project.pbxproj b/RealtimeWatchdog.xcodeproj/project.pbxproj index ae4f392..f5a8f05 100644 --- a/RealtimeWatchdog.xcodeproj/project.pbxproj +++ b/RealtimeWatchdog.xcodeproj/project.pbxproj @@ -20,7 +20,7 @@ 4C636E3D1D0D87AF005A380B /* AERealtimeWatchdog-arm64.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = "AERealtimeWatchdog-arm64.s"; sourceTree = ""; }; 4C636E3E1D0D87AF005A380B /* AERealtimeWatchdog-simulator-x86_64.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = "AERealtimeWatchdog-simulator-x86_64.s"; sourceTree = ""; }; 4C636E3F1D0D87AF005A380B /* AERealtimeWatchdog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AERealtimeWatchdog.h; sourceTree = ""; }; - 4C636E401D0D87AF005A380B /* AERealtimeWatchdog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AERealtimeWatchdog.m; sourceTree = ""; }; + 4C636E401D0D87AF005A380B /* AERealtimeWatchdog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AERealtimeWatchdog.m; sourceTree = ""; usesTabs = 0; }; A40738DD271A339600C636FB /* AERealtimeWatchdogExt.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AERealtimeWatchdogExt.h; sourceTree = ""; }; A40738DE271A3EC100C636FB /* AERealtimeWatchdogExt.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AERealtimeWatchdogExt.m; sourceTree = ""; }; /* End PBXFileReference section */ @@ -103,7 +103,7 @@ 4C636E291D0D878B005A380B /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1530; + LastUpgradeCheck = 1600; ORGANIZATIONNAME = "A Tasty Pixel"; TargetAttributes = { 4C636E301D0D878B005A380B = { diff --git a/RealtimeWatchdog/AERealtimeWatchdog.m b/RealtimeWatchdog/AERealtimeWatchdog.m index 6bb9a46..b6a7e6a 100755 --- a/RealtimeWatchdog/AERealtimeWatchdog.m +++ b/RealtimeWatchdog/AERealtimeWatchdog.m @@ -73,14 +73,14 @@ static void AERealtimeWatchdogUnsafeActivityWarning(const char * activity) { char kAERealtimeWatchdogThreadName[64] = "AURemoteIO::IOThread"; #endif -// This function will be called before main() to set the thread name +// This function will be called before main() to query the process info for the current platform void InitRealtimeThreadName(void) __attribute__((constructor)); void InitRealtimeThreadName(void) { - if (@available(iOS 14.0, *)) { - if (NSProcessInfo.processInfo.isiOSAppOnMac) { - strncpy(kAERealtimeWatchdogThreadName, "com.apple.audio.IOThread.client", sizeof(kAERealtimeWatchdogThreadName)); - } - } + if (@available(iOS 14.0, *)) { + if (NSProcessInfo.processInfo.isiOSAppOnMac) { + strncpy(kAERealtimeWatchdogThreadName, "com.apple.audio.IOThread.client", sizeof(kAERealtimeWatchdogThreadName)); + } + } }