You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm a long-time audio developer that would love to explore the use of Swift from inside a realtime audio context. Unfortunately, despite my best efforts to keep my Swift code free from allocations and other such verboten operations, I am blocked by the compiler inserting some unnecessary "danger" (in the form of swift_allocObject) into the mix…
It would appear that there is a mismatch somewhere—either in the compiler, or the API definition—that is forcing my returned @convention(swift) function to get wrapped into a @convention(block) function that invokes the unwanted object allocation.
I have also filed rdar://47260348 for the audio team at Apple, in case this can get resolved by a simple API annotation that declares @convention(block) for the return type of internalRenderBlock.
Anyway, the attached sample code demonstrates what I am talking about. It can be used as follows on a Mac w/ the Xcode 10.1 tools installed. Just launch Terminal, and run:
./compileIt.sh
That compiles the included swift file and runs the disassembled output through swift-demangle. Look for "reabstraction thunk helper"—that is the function that is invoked by the realtime audio thread instead of the "closure #1" function that you would hope is returned and invoked by the audio subsystem.
I don't know if this is an error in the API declaration, a mis-interpretation of the API by the Swift compiler, or a failure of the compiler to recognize that there is no need to wrap the returned block. I am way outside my element here, so I'll let you folks classify what's going wrong here.
The text was updated successfully, but these errors were encountered:
As you note, the compiler doesn't provide any guarantees about things like this today. However, there's a reasonable optimization in here that we are missing: don't call _Block_copy for a block created from a closure known to have no captures. (Even Objective-C will do a heap allocation for a block that has captures; you can't get around it.)
Just so we are on the same page, I expect the following conditions to hold:
The caller of internalRenderBlock makes a copy of the block that I return.
Any variables that I capture explicitly (see below) will get captured during the _Block_copy invoked by the caller of internalRenderBlock.
The block that gets returned should be equivalent to whatever closure #​1 is emitted by internalRenderBlock.
More specifically, when the audio system invokes the block that I return, the first instruction executed should be whatever code corresponds to the 1st line of the returned closure.
Regarding the capture: What I have in mind is something like this:
// The "math parts" of the audio unitfinalclassDSPKernel {
// Assume this contains:// * Statically-dispatched, thread-safe parameter updaters// * A statically-dispatched buffer reader/writer function
}
finalclassMyAudioUnit: AUAudioUnit {
varsomeDSPKernel: DSPKernelvarinternalRenderBlock: AUInternalRenderBlock {
return {
[kernel = self.someDSPKernel] // Don't capture self
(param1, param2, ...) inkernel.readAndWriteBuffers(param1, param2, ...)
}
}
}
Given my current understanding of Swift, the kernel capture above should act as any other pointer would be passed along with a block. Once the block is constructed, and returned in the getter above, I would expect:the reference is bound to the block object, and when the block is called there should be no further allocations (i.e. _swift_Alloc) required inside the closure #​1. (Provided, of course, that I take care not to allocate anything in readAndWriteBuffers and any code invoked within.)
Please let me know if I am missing (or appear to be misunderstanding) anything. Thanks!
Attachment: Download
Additional Detail from JIRA
md5: bcdbe249b340f43b9fe2c2887834b365
Issue Description:
I'm a long-time audio developer that would love to explore the use of Swift from inside a realtime audio context. Unfortunately, despite my best efforts to keep my Swift code free from allocations and other such verboten operations, I am blocked by the compiler inserting some unnecessary "danger" (in the form of swift_allocObject) into the mix…
It would appear that there is a mismatch somewhere—either in the compiler, or the API definition—that is forcing my returned @convention(swift) function to get wrapped into a @convention(block) function that invokes the unwanted object allocation.
I have also filed rdar://47260348 for the audio team at Apple, in case this can get resolved by a simple API annotation that declares @convention(block) for the return type of internalRenderBlock.
Anyway, the attached sample code demonstrates what I am talking about. It can be used as follows on a Mac w/ the Xcode 10.1 tools installed. Just launch Terminal, and run:
./compileIt.sh
That compiles the included swift file and runs the disassembled output through swift-demangle. Look for "reabstraction thunk helper"—that is the function that is invoked by the realtime audio thread instead of the "closure #1" function that you would hope is returned and invoked by the audio subsystem.
I don't know if this is an error in the API declaration, a mis-interpretation of the API by the Swift compiler, or a failure of the compiler to recognize that there is no need to wrap the returned block. I am way outside my element here, so I'll let you folks classify what's going wrong here.
The text was updated successfully, but these errors were encountered: