Dispatch

RSS for tag

Execute code concurrently on multicore hardware by submitting work to dispatch queues managed by the system using Dispatch.

Posts under Dispatch tag

113 Posts

Post

Replies

Boosts

Views

Activity

BUG IN CLIENT OF LIBDISPATCH
There is a bug of libdispatch on my APP, which is similar to this post, but it's on iOS across versions from 13.x to 16.x. Now I downloaded the opensource code of libdispatch from here, and I want to look into the details of source code to figure out the root cause. How can I know the branch or commit of the libdispatch code the specific iOS version (like 15.6.1) uses. crash_info_0 BUG IN CLIENT OF LIBDISPATCH: Unexpected EV_VANISHED (do not destroy random mach ports or file descriptors) fault_address 0x0000000001a37b9bc4 mach_code 0x000000000000000001 mach_subcode 0x0000000001a37b9bc4 name EXC_BREAKPOINT (SIGTRAP) reason EXC_BREAKPOINT EXC_ARM_BREAKPOINT fault_address:0x00000001a37b9bc4 type MACH_Exception 0 libdispatch.dylib __dispatch_source_merge_evt.cold.1 (in libdispatch.dylib) +36 1 libdispatch.dylib __dispatch_source_merge_evt (in libdispatch.dylib) +192 2 libdispatch.dylib __dispatch_event_loop_merge (in libdispatch.dylib) +144 3 libdispatch.dylib __dispatch_workloop_worker_thread (in libdispatch.dylib) +392 4 libsystem_pthread.dylib __pthread_wqthread (in libsystem_pthread.dylib) +284 5 libsystem_pthread.dylib _start_wqthread (in libsystem_pthread.dylib) +4 By the way, what's the difference between "__dispatch_source_merge_evt.cold.1" and "__dispatch_source_merge_evt"
1
0
3.8k
Nov ’22
Getting the current queue and thread name?
The Xcode console logs an identifier indicating the current thread that's running when a message is print()ed from Swift. Some more complex logging systems (e.g. swift-log and console-kit) don't provide that information, and I'm trying to write a logging back-end for swift-log that will. Thing is, I don't see any way to get the current queue name in Swift. I tried dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL) But I get "cannot convert value of type '()' to expected argument type 'DispatchQueue?'". Passing nil instead results in "'dispatch_queue_get_label' has been replaced by property 'DispatchQueue.label'". This is not an unreasonable thing to want to do, and it poses no safety concerns.
4
0
5.8k
Nov ’22
Is beginBackgroundTask() expected to dispatch to main?
The name of the function beginBackgroundTask appears to imply that it is safe to call from a background thread. However, because this is part of the UIApplication class, it causes a dispatch to the main thread first. This dispatch can prove problematic as it can introduce resource contention, or at worst deadlocks, if you're not very careful about how you're starting your task. Example: Main thread calls a lower layer of code, which is using a dispatch queue to process operations An item in that queue is already processing an item which happens to call beginBackgroundTask() If the operation being performed on the main thread is synchronous, you get a deadlock. If the operation is asynchronous, you can still run into a delay if your background queue performs a lot of operations, as each one briefly is blocking the main queue each time. The docs for beginBackgroundTask() claim that invoking the API is asynchronous, or that you can call this method at any time, but that doesn't appear to actually be the case. Was this by design? Is beginBackgroundTask() intended to be used very sparingly?
2
0
1.7k
Nov ’22
NSSharingServicePicker is not async
Hey, I noticed that the NSSharingServicePicker is not running asynchronously in the main thread. Even if you call it inside a DispatchQueue.main.async block, the UI will be freezing. Is this behavior intentional? It would be really nice if the UI could update in the background. Since we're using Flutter, we can't outsource the UI stuff asynchronously during the picker presentation. Greetings from Germany, Leon
0
0
978
Oct ’22
Why use dispatch_semaphore to explicitly synchronize MTLbuffer updates?
Hi. I'm new to Metal(actually any type of software development run on apple products). I have many questions about using MTL::Buffer and dispatch_semaphore, and drawInMTKView(). I read README.md, but I need some more help understanding it. Full code of 03-animation in metal-cpp sample This is sample code in metal-cpp sample code by apple(I downloaded here). In this code, _pFrameData is an array of MTLBuffer, and kMaxFramesInFlight is the size of this array. Its type is static const int, and the value is 3. When Renderer is created, _pFrameData are initialized like that. void Renderer::buildFrameData() {     for ( int i = 0; i < Renderer::kMaxFramesInFlight; ++i )     {         _pFrameData[ i ]= _pDevice->newBuffer( sizeof( FrameData ), MTL::ResourceStorageModeManaged );     } } draw method, call by drawInMTKView. void Renderer::draw( MTK::View* pView ) {     NS::AutoreleasePool* pPool = NS::AutoreleasePool::alloc()->init();     _frame = (_frame + 1) % Renderer::kMaxFramesInFlight; MTL::Buffer* pFrameDataBuffer = _pFrameData[ _frame ];     MTL::CommandBuffer* pCmd = _pCommandQueue->commandBuffer();     dispatch_semaphore_wait( _semaphore, DISPATCH_TIME_FOREVER );     Renderer* pRenderer = this;     pCmd->addCompletedHandler( ^void( MTL::CommandBuffer* pCmd ){         dispatch_semaphore_signal( pRenderer->_semaphore );     });     reinterpret_cast< FrameData * >( pFrameDataBuffer->contents() )->angle = (_angle += 0.01f);     pFrameDataBuffer->didModifyRange( NS::Range::Make( 0, sizeof( FrameData ) ) );     MTL::RenderPassDescriptor* pRpd = pView->currentRenderPassDescriptor();     MTL::RenderCommandEncoder* pEnc = pCmd->renderCommandEncoder( pRpd );     pEnc->setRenderPipelineState( _pPSO );     pEnc->setVertexBuffer( _pArgBuffer, 0, 0 );     pEnc->useResource( _pVertexPositionsBuffer, MTL::ResourceUsageRead );     pEnc->useResource( _pVertexColorsBuffer, MTL::ResourceUsageRead );     pEnc->setVertexBuffer( pFrameDataBuffer, 0, 1 );     pEnc->drawPrimitives( MTL::PrimitiveType::PrimitiveTypeTriangle, NS::UInteger(0), NS::UInteger(3) );     pEnc->endEncoding();     pCmd->presentDrawable( pView->currentDrawable() );     pCmd->commit();     pPool->release(); } Q1. what is the meaning of kMaxFramesInFlight's name and value? Q2. how are dispatch_semaphore_wait() and drawInMTKView() working? At first, I guess if the count of dispatch_semaphore change 0, the Renderer::draw are blocked by dispatch_semaphore_wait() until GPU read the buffer and execute dispatch_semaphore_signal. But now I think it's not a correct understanding because I don't know about drawInMTKView. How much drawInMTKView is called in 1 second and when? Q3. and.... why use dispatch_semaphore for here? I try to change my code to use a single MTLBuffer for the same work. Just changing some code(add a single buffer, remove code for dispatch_semaphore), the changed code works same.
1
0
1.3k
Oct ’22
Delayed Return in Swift
So I have an app that users can create utilities with some shell script I have a feature that the user can experiment with their scripts (a shell REPL) But if I type zsh in the REPL the whole app went stuck and the zsh shell outputs in Xcode: (This is my zsh theme) I've added detection for these: But what I really want is to let the process run in the background while the REPL output "Time out waiting for pipeline output after xxx secs" after xxx secs I've thought about letting them run in two separate asynchronous tasks so that if one task was completed it could first return the function but I just can't manage it: func run(launchPath: String? = nil, command: String) -> String { let task = Process() let pipe = Pipe() task.standardOutput = pipe task.standardError = pipe task.arguments = ["-c", command] task.launchPath = launchPath ?? "/bin/zsh/" task.launch() Task { let data = try? pipe.fileHandleForReading.readToEnd()! return String(data: data!, encoding: .utf8)! } DispatchQueue.main.asyncAfter(deadline: .now + 30) { return "Time out" // ERROR } } So How can I create two separate asynchronous tasks, one receiving the pipe output, and one, after a few seconds, returns the function?
3
0
2.1k
Sep ’22
What does DispatchQueue.AutoreleaseFrequency.workItem mean?
The documentation for DispatchQueue.AutoreleaseFrequency.workItem says , "The queue configures an autorelease pool before the execution of a block, and releases the objects in that pool after the block finishes executing." Does this mean that the dispatch queue releases each work item or each code in ()->Void after each one finishes executing? When it says, "releases the objects in that pool er the block finishes executing", it makes it sound like there is only one block executing and then the entire pool is released. I'm making sure I verify that I understand this correctly.
1
0
1.1k
Sep ’22
Is there an equivalent of DispatchQueue.concurrentPerform() with the new async/await?
Just wondering if there is an equivalent of DispatchQueue.concurrentPerform() with the new async/await pattern introduced with Swift 5.5? I'm using concurrentPerform to iterate through all the pixels of an image and was wondering if this is possible with the new async/await pattern too. Would love to do some comparisons on performance.
2
0
5.6k
Sep ’22
Swift Array was deallocated when used in dispatch_apply_f function (introduced in iOS 16)
When passing Swift array to initialize Buffer, obj-C bridging creates DeferredNSArray, which defers creating of obj-c BridgingBuffer till the first access to the elements of array is made. Since we are initializing our Buffer’s internal storage in parallel, we end up in a situation where BridgingBuffer is created from several threads and we have got the crash. Please see attached screenshot and files. Can you help me to fix this issue? ViewController.swift Buffer.mm Buffer.h
3
1
1k
Sep ’22
Serial Queue not executing serially
I don't understand why the code is not executing serially. I have called the closures syncronously so that the next closure will be called only after the completion of previous one. On terminal, the last closure is printed first which I was expecting to execute in the end, then the second one & then the first one at last. Any help on this ? func getLocation(from address: String, completion: @escaping (_ location: CLLocationCoordinate2D?)-> Void) { let geocoder = CLGeocoder()   geocoder.geocodeAddressString(address) { (placemarks, error) in guard let placemarks = placemarks, let location = placemarks.first?.location?.coordinate else { completion(nil) return } completion(location) } } let queue = DispatchQueue(label: "queue") queue.sync { self.getLocation(from: self.sourceString) { location in     if(location != nil){         self.source = MKPlacemark(coordinate: location!) print("Source found") }          else{             print("Source not found") } } } queue.sync { self.getLocation(from: self.sourceString) { location in     if(location != nil){         self.destination = MKPlacemark(coordinate: location!) print("Destination found") }          else{             print("Destination not found") } } } queue.sync { if(self.source.coordinate.latitude != 0.0 && self.destination.coordinate.latitude != 0.0 ){ self.bringMap = true } else{ print("coordinates not updated yet") } }
2
0
1.3k
Aug ’22
Why use serial queue over NSLock or os_unfair_lock?
I have the following 2 thread safe wrappers implementation for a boolean: 1 - Using NSLock class ThreadSafeBool { private let lock = NSLock() private var wrappedValue: Bool var value: Bool { get { lock.lock() defer { lock.unlock() } return wrappedValue } set { lock.lock() defer { lock.unlock() } wrappedValue = newValue } } init(_ initialValue: Bool) { wrappedValue = initialValue } } 2 - Using DispatchQueue and sync class ThreadSafeBoolQueue { private let queue = DispatchQueue(label: "my.queue") private var wrappedValue: Bool var value: Bool { get { self.queue.sync { return wrappedValue } } set { self.queue.sync { wrappedValue = newValue } } } init(_ initialValue: Bool) { wrappedValue = initialValue } } Even though the NSLock it is much more faster then the sync queues, os_unfair_lock is even faster. Could someone please let me know why in lots of example is prefer the second locking mode, including Apple presentation? PS: Please keep in mind that the classes are just examples, so the main question is why queue over NSLock/os_unfair_lock? Thank you very much
2
2
4.6k
Aug ’22
Avoid Dispatch Global Concurrent Queues
I regularly see folks write code like this: DispatchQueue.global().async { … do stuff … } This relies on a Dispatch global concurrent queue. Using such queues directly is almost always a mistake. That’s because a global concurrent queue might [1] overcommit — that is, start more threads than there are CPU cores — resulting in needless inefficiency. In the worse case this can trigger a phenomenon known as thread explosion, which is about as much fun as it sounds. My general advice is that you avoid concurrent queues in almost all circumstances. For more background on this, see: WWDC 2015 Session 718 Building Responsive and Efficient Apps with GCD WWDC 2017 Session 706 Modernizing Grand Central Dispatch Usage If you have any follow comments or questions, please start a new thread, tagging it with Dispatch, and I’ll respond there. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" [1] Whether it will overcommit is a more complex question (-: (r. 98175345)
0
0
4k
Aug ’22
How to Debug psort_r(3)/dispatch_group Stall on MacStudio?
We've recently noticed an issue on our new MacStudios where calls to psort_r(3) stall forever. We haven't changed our HPC (particle simulation) code at all, and sampling the app shows psort_r is stuck in dispatch_group_wait(3). Taking the code from Libc 1439.141.1, we've assembled our own implementation which allows us to pass a dispatch_queue_t, dispatch_group_t, and specify a wait time. After 10 seconds (a very long time in our case) the call returns with a non-zero exit code and shows the group and queue are in agreement: four additional blocks are waiting to dispatch, but haven't. This still takes more than two hours of simulation to achieve, where calls to psort_r must be succeeding to make forward progress. Prior to this code change we've seen dispatch_group_wait stuck for hours. What else could we do to diagnose/debug this? We only see it on our M1 Ultra MacStudios, and the comparator passed to psort_r is simple C code (constant time). FB10893202
4
0
1.4k
Aug ’22
When can I run a synchronous code by executing DispatchQueue.main.sync { }?
I tried running the following code and it raises the following error every time: DispatchQueue.main.sync { } Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) I found this post on stackoverflow that says to never run synchronous code on the main queue: DispatchQueue crashing with main.sync in Swift I had assumed that because the sync { } method is there that means there is some context that it can be used. Is there absolutely no use for executing synchronous code on the main queue?
1
0
1.3k
Jul ’22
Overuse of DispatchQueue.main.async?
I have code that I inherited - and there is very liberal use of DispatchQueue.main.async because they were concerned the UI code there wasn't on the main thread - but it already was on the main queue. The bug I saw, was that if the calling code was already on the main thread, and the function they called also called the DispatchQueue.main.async, it seems like that call was delayed/not-called, and being requeued on the run loop for the next call. Here's kind of a general - very stripped down - version of what I was experiencing:     var result = 1     override func viewDidLoad() {         super.viewDidLoad()         DispatchQueue.main.async {             print("Before : result = \(self.result)")             self.doStuff()             print("After  : result = \(self.result)")         }     }     func doStuff() {         self.result += 1         self.doStuff2()     }     func doStuff2() {         DispatchQueue.main.async {             self.result += 1             self.doStuff3()         }     }     func doStuff3() {         result += 1     } } The output is: Before : result = 1 After  : result = 2 So it enters doStuff2() but that function also calls DispatchQueue.main.async - and therefore, that code never gets executed. I cleaned it up by removing these extraneous calls - but it took A LONG TIME tracking all of them down. Is there any better way to debug this? Also - they said this code worked in iOS 12. Thanks, Scott
3
0
3.1k
Jul ’22
Apple SDKs concurrency-readiness
I've been trying to use the Xcode 14 beta and the -warn-concurrency flag to make some of our library code concurrency-safe, and I've hit just… too many problems to manage. A smattering of random data points: Foundation types that I think should be Sendable, are not: URL Notification ... UIKit constants that should not be @MainActor, are: UIApplication.willEnterForegroundNotification (it's just a string constant, and NotificationCenter itself is thread-safe) UIKit types and methods that I think should not be @MainActor, are: UIDevice, or at least I should be able to do UIDevice.current.systemVersion from any actor Dispatch is completely concurrency-unaware — I kinda expected it to be unavailable, but instead it's available but doesn't understand swift concurrency It'd at least be nice if DispatchQueue.main.[a]sync understood that its closure can be @MainActor (perhaps main could return a subclass of DispatchQueue with stronger guarantees?) SwiftUI Button etc. callbacks aren't marked @MainActor, even though (AFAIK) they are — certainly it's always been legal to update @State vars from them — so it's not legal to call UIKit from them (eg. to present a UIViewController in response to a button press) When can we expect Apple's SDKs to actually be usable with concurrency checking?
1
1
1.1k
Jun ’22
How do I wait for a task to finish before proceeding with the program flow?
Hi, So I am using this function getListAtFIRStore() which is fetching data from firestore and returning it. But the fetching takes some time and before that happens the function already returns back the array which is empty at that moment. How do I wait for the fetching task to be completed before the function returns the array back? class CheckForDownloads {          var userName = String()          func refreshResources(forUser username: String) {         self.userName = username         let listOfImagesAtFirestore =  getListAtFIRStore()         print(listOfImagesAtFirestore)     }               func getListAtFIRStore() -> [String]{         let root = Storage.storage().reference()         var str3 = [String]()                  root.child("MagicFrame/\(userName)/images").listAll { (result, error) in             if let error = error {                 print("Error in fetching list from firestore \(error.localizedDescription)")             }else{                 for item in result.items{                     if let str1 = (item.description.components(separatedBy: ["/"]).last) {                         if let str2 = (str1.components(separatedBy: ["."])).first{                             print(str2)                             str3.append(str2)                         }                                              }                 }             }         }         return str3     }      }
5
0
5.5k
Jun ’22
How does async/await work?
Hi folks, I am downloading some images from Firebase and adding them to main bundle resources, after which I use them. I am having trouble with making my code to wait for the downloads to get complete before it executes the next statement. I tried completion handlers, async/await but still the same. Not sure if I am doing it the right way. Can anyone help what is the correct approach for this scenario. override func viewWillAppear(_ animated: Bool) {         super.viewWillAppear(animated)         // Create a session configuration          let configuration = ARImageTrackingConfiguration()             Task{                 await self.checkForDownloads.refreshResources(forUser: self.username)             }             if let trackedImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: Bundle.main){                 configuration.trackingImages = trackedImages                 configuration.maximumNumberOfTrackedImages = 1                 print("Images Found: \(trackedImages.count)")             }         sceneView.session.run(configuration)     }     func refreshResources(forUser username: String) async { //.. } I am expecting checkForDownloads.refreshResources to finish downloading first, then proceed to next statement.
1
0
974
Jun ’22
BUG IN CLIENT OF LIBDISPATCH
There is a bug of libdispatch on my APP, which is similar to this post, but it's on iOS across versions from 13.x to 16.x. Now I downloaded the opensource code of libdispatch from here, and I want to look into the details of source code to figure out the root cause. How can I know the branch or commit of the libdispatch code the specific iOS version (like 15.6.1) uses. crash_info_0 BUG IN CLIENT OF LIBDISPATCH: Unexpected EV_VANISHED (do not destroy random mach ports or file descriptors) fault_address 0x0000000001a37b9bc4 mach_code 0x000000000000000001 mach_subcode 0x0000000001a37b9bc4 name EXC_BREAKPOINT (SIGTRAP) reason EXC_BREAKPOINT EXC_ARM_BREAKPOINT fault_address:0x00000001a37b9bc4 type MACH_Exception 0 libdispatch.dylib __dispatch_source_merge_evt.cold.1 (in libdispatch.dylib) +36 1 libdispatch.dylib __dispatch_source_merge_evt (in libdispatch.dylib) +192 2 libdispatch.dylib __dispatch_event_loop_merge (in libdispatch.dylib) +144 3 libdispatch.dylib __dispatch_workloop_worker_thread (in libdispatch.dylib) +392 4 libsystem_pthread.dylib __pthread_wqthread (in libsystem_pthread.dylib) +284 5 libsystem_pthread.dylib _start_wqthread (in libsystem_pthread.dylib) +4 By the way, what's the difference between "__dispatch_source_merge_evt.cold.1" and "__dispatch_source_merge_evt"
Replies
1
Boosts
0
Views
3.8k
Activity
Nov ’22
Getting the current queue and thread name?
The Xcode console logs an identifier indicating the current thread that's running when a message is print()ed from Swift. Some more complex logging systems (e.g. swift-log and console-kit) don't provide that information, and I'm trying to write a logging back-end for swift-log that will. Thing is, I don't see any way to get the current queue name in Swift. I tried dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL) But I get "cannot convert value of type '()' to expected argument type 'DispatchQueue?'". Passing nil instead results in "'dispatch_queue_get_label' has been replaced by property 'DispatchQueue.label'". This is not an unreasonable thing to want to do, and it poses no safety concerns.
Replies
4
Boosts
0
Views
5.8k
Activity
Nov ’22
Is beginBackgroundTask() expected to dispatch to main?
The name of the function beginBackgroundTask appears to imply that it is safe to call from a background thread. However, because this is part of the UIApplication class, it causes a dispatch to the main thread first. This dispatch can prove problematic as it can introduce resource contention, or at worst deadlocks, if you're not very careful about how you're starting your task. Example: Main thread calls a lower layer of code, which is using a dispatch queue to process operations An item in that queue is already processing an item which happens to call beginBackgroundTask() If the operation being performed on the main thread is synchronous, you get a deadlock. If the operation is asynchronous, you can still run into a delay if your background queue performs a lot of operations, as each one briefly is blocking the main queue each time. The docs for beginBackgroundTask() claim that invoking the API is asynchronous, or that you can call this method at any time, but that doesn't appear to actually be the case. Was this by design? Is beginBackgroundTask() intended to be used very sparingly?
Replies
2
Boosts
0
Views
1.7k
Activity
Nov ’22
NSSharingServicePicker is not async
Hey, I noticed that the NSSharingServicePicker is not running asynchronously in the main thread. Even if you call it inside a DispatchQueue.main.async block, the UI will be freezing. Is this behavior intentional? It would be really nice if the UI could update in the background. Since we're using Flutter, we can't outsource the UI stuff asynchronously during the picker presentation. Greetings from Germany, Leon
Replies
0
Boosts
0
Views
978
Activity
Oct ’22
Why use dispatch_semaphore to explicitly synchronize MTLbuffer updates?
Hi. I'm new to Metal(actually any type of software development run on apple products). I have many questions about using MTL::Buffer and dispatch_semaphore, and drawInMTKView(). I read README.md, but I need some more help understanding it. Full code of 03-animation in metal-cpp sample This is sample code in metal-cpp sample code by apple(I downloaded here). In this code, _pFrameData is an array of MTLBuffer, and kMaxFramesInFlight is the size of this array. Its type is static const int, and the value is 3. When Renderer is created, _pFrameData are initialized like that. void Renderer::buildFrameData() {     for ( int i = 0; i < Renderer::kMaxFramesInFlight; ++i )     {         _pFrameData[ i ]= _pDevice->newBuffer( sizeof( FrameData ), MTL::ResourceStorageModeManaged );     } } draw method, call by drawInMTKView. void Renderer::draw( MTK::View* pView ) {     NS::AutoreleasePool* pPool = NS::AutoreleasePool::alloc()->init();     _frame = (_frame + 1) % Renderer::kMaxFramesInFlight; MTL::Buffer* pFrameDataBuffer = _pFrameData[ _frame ];     MTL::CommandBuffer* pCmd = _pCommandQueue->commandBuffer();     dispatch_semaphore_wait( _semaphore, DISPATCH_TIME_FOREVER );     Renderer* pRenderer = this;     pCmd->addCompletedHandler( ^void( MTL::CommandBuffer* pCmd ){         dispatch_semaphore_signal( pRenderer->_semaphore );     });     reinterpret_cast< FrameData * >( pFrameDataBuffer->contents() )->angle = (_angle += 0.01f);     pFrameDataBuffer->didModifyRange( NS::Range::Make( 0, sizeof( FrameData ) ) );     MTL::RenderPassDescriptor* pRpd = pView->currentRenderPassDescriptor();     MTL::RenderCommandEncoder* pEnc = pCmd->renderCommandEncoder( pRpd );     pEnc->setRenderPipelineState( _pPSO );     pEnc->setVertexBuffer( _pArgBuffer, 0, 0 );     pEnc->useResource( _pVertexPositionsBuffer, MTL::ResourceUsageRead );     pEnc->useResource( _pVertexColorsBuffer, MTL::ResourceUsageRead );     pEnc->setVertexBuffer( pFrameDataBuffer, 0, 1 );     pEnc->drawPrimitives( MTL::PrimitiveType::PrimitiveTypeTriangle, NS::UInteger(0), NS::UInteger(3) );     pEnc->endEncoding();     pCmd->presentDrawable( pView->currentDrawable() );     pCmd->commit();     pPool->release(); } Q1. what is the meaning of kMaxFramesInFlight's name and value? Q2. how are dispatch_semaphore_wait() and drawInMTKView() working? At first, I guess if the count of dispatch_semaphore change 0, the Renderer::draw are blocked by dispatch_semaphore_wait() until GPU read the buffer and execute dispatch_semaphore_signal. But now I think it's not a correct understanding because I don't know about drawInMTKView. How much drawInMTKView is called in 1 second and when? Q3. and.... why use dispatch_semaphore for here? I try to change my code to use a single MTLBuffer for the same work. Just changing some code(add a single buffer, remove code for dispatch_semaphore), the changed code works same.
Replies
1
Boosts
0
Views
1.3k
Activity
Oct ’22
Delayed Return in Swift
So I have an app that users can create utilities with some shell script I have a feature that the user can experiment with their scripts (a shell REPL) But if I type zsh in the REPL the whole app went stuck and the zsh shell outputs in Xcode: (This is my zsh theme) I've added detection for these: But what I really want is to let the process run in the background while the REPL output "Time out waiting for pipeline output after xxx secs" after xxx secs I've thought about letting them run in two separate asynchronous tasks so that if one task was completed it could first return the function but I just can't manage it: func run(launchPath: String? = nil, command: String) -> String { let task = Process() let pipe = Pipe() task.standardOutput = pipe task.standardError = pipe task.arguments = ["-c", command] task.launchPath = launchPath ?? "/bin/zsh/" task.launch() Task { let data = try? pipe.fileHandleForReading.readToEnd()! return String(data: data!, encoding: .utf8)! } DispatchQueue.main.asyncAfter(deadline: .now + 30) { return "Time out" // ERROR } } So How can I create two separate asynchronous tasks, one receiving the pipe output, and one, after a few seconds, returns the function?
Replies
3
Boosts
0
Views
2.1k
Activity
Sep ’22
What does DispatchQueue.AutoreleaseFrequency.workItem mean?
The documentation for DispatchQueue.AutoreleaseFrequency.workItem says , "The queue configures an autorelease pool before the execution of a block, and releases the objects in that pool after the block finishes executing." Does this mean that the dispatch queue releases each work item or each code in ()->Void after each one finishes executing? When it says, "releases the objects in that pool er the block finishes executing", it makes it sound like there is only one block executing and then the entire pool is released. I'm making sure I verify that I understand this correctly.
Replies
1
Boosts
0
Views
1.1k
Activity
Sep ’22
Is there an equivalent of DispatchQueue.concurrentPerform() with the new async/await?
Just wondering if there is an equivalent of DispatchQueue.concurrentPerform() with the new async/await pattern introduced with Swift 5.5? I'm using concurrentPerform to iterate through all the pixels of an image and was wondering if this is possible with the new async/await pattern too. Would love to do some comparisons on performance.
Replies
2
Boosts
0
Views
5.6k
Activity
Sep ’22
Swift Array was deallocated when used in dispatch_apply_f function (introduced in iOS 16)
When passing Swift array to initialize Buffer, obj-C bridging creates DeferredNSArray, which defers creating of obj-c BridgingBuffer till the first access to the elements of array is made. Since we are initializing our Buffer’s internal storage in parallel, we end up in a situation where BridgingBuffer is created from several threads and we have got the crash. Please see attached screenshot and files. Can you help me to fix this issue? ViewController.swift Buffer.mm Buffer.h
Replies
3
Boosts
1
Views
1k
Activity
Sep ’22
Serial Queue not executing serially
I don't understand why the code is not executing serially. I have called the closures syncronously so that the next closure will be called only after the completion of previous one. On terminal, the last closure is printed first which I was expecting to execute in the end, then the second one & then the first one at last. Any help on this ? func getLocation(from address: String, completion: @escaping (_ location: CLLocationCoordinate2D?)-> Void) { let geocoder = CLGeocoder()   geocoder.geocodeAddressString(address) { (placemarks, error) in guard let placemarks = placemarks, let location = placemarks.first?.location?.coordinate else { completion(nil) return } completion(location) } } let queue = DispatchQueue(label: "queue") queue.sync { self.getLocation(from: self.sourceString) { location in     if(location != nil){         self.source = MKPlacemark(coordinate: location!) print("Source found") }          else{             print("Source not found") } } } queue.sync { self.getLocation(from: self.sourceString) { location in     if(location != nil){         self.destination = MKPlacemark(coordinate: location!) print("Destination found") }          else{             print("Destination not found") } } } queue.sync { if(self.source.coordinate.latitude != 0.0 && self.destination.coordinate.latitude != 0.0 ){ self.bringMap = true } else{ print("coordinates not updated yet") } }
Replies
2
Boosts
0
Views
1.3k
Activity
Aug ’22
Why use serial queue over NSLock or os_unfair_lock?
I have the following 2 thread safe wrappers implementation for a boolean: 1 - Using NSLock class ThreadSafeBool { private let lock = NSLock() private var wrappedValue: Bool var value: Bool { get { lock.lock() defer { lock.unlock() } return wrappedValue } set { lock.lock() defer { lock.unlock() } wrappedValue = newValue } } init(_ initialValue: Bool) { wrappedValue = initialValue } } 2 - Using DispatchQueue and sync class ThreadSafeBoolQueue { private let queue = DispatchQueue(label: "my.queue") private var wrappedValue: Bool var value: Bool { get { self.queue.sync { return wrappedValue } } set { self.queue.sync { wrappedValue = newValue } } } init(_ initialValue: Bool) { wrappedValue = initialValue } } Even though the NSLock it is much more faster then the sync queues, os_unfair_lock is even faster. Could someone please let me know why in lots of example is prefer the second locking mode, including Apple presentation? PS: Please keep in mind that the classes are just examples, so the main question is why queue over NSLock/os_unfair_lock? Thank you very much
Replies
2
Boosts
2
Views
4.6k
Activity
Aug ’22
Avoid Dispatch Global Concurrent Queues
I regularly see folks write code like this: DispatchQueue.global().async { … do stuff … } This relies on a Dispatch global concurrent queue. Using such queues directly is almost always a mistake. That’s because a global concurrent queue might [1] overcommit — that is, start more threads than there are CPU cores — resulting in needless inefficiency. In the worse case this can trigger a phenomenon known as thread explosion, which is about as much fun as it sounds. My general advice is that you avoid concurrent queues in almost all circumstances. For more background on this, see: WWDC 2015 Session 718 Building Responsive and Efficient Apps with GCD WWDC 2017 Session 706 Modernizing Grand Central Dispatch Usage If you have any follow comments or questions, please start a new thread, tagging it with Dispatch, and I’ll respond there. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" [1] Whether it will overcommit is a more complex question (-: (r. 98175345)
Replies
0
Boosts
0
Views
4k
Activity
Aug ’22
How to Debug psort_r(3)/dispatch_group Stall on MacStudio?
We've recently noticed an issue on our new MacStudios where calls to psort_r(3) stall forever. We haven't changed our HPC (particle simulation) code at all, and sampling the app shows psort_r is stuck in dispatch_group_wait(3). Taking the code from Libc 1439.141.1, we've assembled our own implementation which allows us to pass a dispatch_queue_t, dispatch_group_t, and specify a wait time. After 10 seconds (a very long time in our case) the call returns with a non-zero exit code and shows the group and queue are in agreement: four additional blocks are waiting to dispatch, but haven't. This still takes more than two hours of simulation to achieve, where calls to psort_r must be succeeding to make forward progress. Prior to this code change we've seen dispatch_group_wait stuck for hours. What else could we do to diagnose/debug this? We only see it on our M1 Ultra MacStudios, and the comparator passed to psort_r is simple C code (constant time). FB10893202
Replies
4
Boosts
0
Views
1.4k
Activity
Aug ’22
When can I run a synchronous code by executing DispatchQueue.main.sync { }?
I tried running the following code and it raises the following error every time: DispatchQueue.main.sync { } Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) I found this post on stackoverflow that says to never run synchronous code on the main queue: DispatchQueue crashing with main.sync in Swift I had assumed that because the sync { } method is there that means there is some context that it can be used. Is there absolutely no use for executing synchronous code on the main queue?
Replies
1
Boosts
0
Views
1.3k
Activity
Jul ’22
Overuse of DispatchQueue.main.async?
I have code that I inherited - and there is very liberal use of DispatchQueue.main.async because they were concerned the UI code there wasn't on the main thread - but it already was on the main queue. The bug I saw, was that if the calling code was already on the main thread, and the function they called also called the DispatchQueue.main.async, it seems like that call was delayed/not-called, and being requeued on the run loop for the next call. Here's kind of a general - very stripped down - version of what I was experiencing:     var result = 1     override func viewDidLoad() {         super.viewDidLoad()         DispatchQueue.main.async {             print("Before : result = \(self.result)")             self.doStuff()             print("After  : result = \(self.result)")         }     }     func doStuff() {         self.result += 1         self.doStuff2()     }     func doStuff2() {         DispatchQueue.main.async {             self.result += 1             self.doStuff3()         }     }     func doStuff3() {         result += 1     } } The output is: Before : result = 1 After  : result = 2 So it enters doStuff2() but that function also calls DispatchQueue.main.async - and therefore, that code never gets executed. I cleaned it up by removing these extraneous calls - but it took A LONG TIME tracking all of them down. Is there any better way to debug this? Also - they said this code worked in iOS 12. Thanks, Scott
Replies
3
Boosts
0
Views
3.1k
Activity
Jul ’22
precompiler test for cpu count
I use as many cpu's as I can get with DispatchQueue. How do I test the Mac for cpu count in my code?
Replies
6
Boosts
0
Views
1.6k
Activity
Jul ’22
How does the performance of MTLIOCommandQueue compare to GCD?
I am implementing asset pipelines for a metal app and am deciding between the new Metal IO support and more traditional approaches like dispatch_io. Does the MTLCommandQueue use GCD as its backend, or how do the approaches compare?
Replies
0
Boosts
0
Views
935
Activity
Jul ’22
Apple SDKs concurrency-readiness
I've been trying to use the Xcode 14 beta and the -warn-concurrency flag to make some of our library code concurrency-safe, and I've hit just… too many problems to manage. A smattering of random data points: Foundation types that I think should be Sendable, are not: URL Notification ... UIKit constants that should not be @MainActor, are: UIApplication.willEnterForegroundNotification (it's just a string constant, and NotificationCenter itself is thread-safe) UIKit types and methods that I think should not be @MainActor, are: UIDevice, or at least I should be able to do UIDevice.current.systemVersion from any actor Dispatch is completely concurrency-unaware — I kinda expected it to be unavailable, but instead it's available but doesn't understand swift concurrency It'd at least be nice if DispatchQueue.main.[a]sync understood that its closure can be @MainActor (perhaps main could return a subclass of DispatchQueue with stronger guarantees?) SwiftUI Button etc. callbacks aren't marked @MainActor, even though (AFAIK) they are — certainly it's always been legal to update @State vars from them — so it's not legal to call UIKit from them (eg. to present a UIViewController in response to a button press) When can we expect Apple's SDKs to actually be usable with concurrency checking?
Replies
1
Boosts
1
Views
1.1k
Activity
Jun ’22
How do I wait for a task to finish before proceeding with the program flow?
Hi, So I am using this function getListAtFIRStore() which is fetching data from firestore and returning it. But the fetching takes some time and before that happens the function already returns back the array which is empty at that moment. How do I wait for the fetching task to be completed before the function returns the array back? class CheckForDownloads {          var userName = String()          func refreshResources(forUser username: String) {         self.userName = username         let listOfImagesAtFirestore =  getListAtFIRStore()         print(listOfImagesAtFirestore)     }               func getListAtFIRStore() -> [String]{         let root = Storage.storage().reference()         var str3 = [String]()                  root.child("MagicFrame/\(userName)/images").listAll { (result, error) in             if let error = error {                 print("Error in fetching list from firestore \(error.localizedDescription)")             }else{                 for item in result.items{                     if let str1 = (item.description.components(separatedBy: ["/"]).last) {                         if let str2 = (str1.components(separatedBy: ["."])).first{                             print(str2)                             str3.append(str2)                         }                                              }                 }             }         }         return str3     }      }
Replies
5
Boosts
0
Views
5.5k
Activity
Jun ’22
How does async/await work?
Hi folks, I am downloading some images from Firebase and adding them to main bundle resources, after which I use them. I am having trouble with making my code to wait for the downloads to get complete before it executes the next statement. I tried completion handlers, async/await but still the same. Not sure if I am doing it the right way. Can anyone help what is the correct approach for this scenario. override func viewWillAppear(_ animated: Bool) {         super.viewWillAppear(animated)         // Create a session configuration          let configuration = ARImageTrackingConfiguration()             Task{                 await self.checkForDownloads.refreshResources(forUser: self.username)             }             if let trackedImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: Bundle.main){                 configuration.trackingImages = trackedImages                 configuration.maximumNumberOfTrackedImages = 1                 print("Images Found: \(trackedImages.count)")             }         sceneView.session.run(configuration)     }     func refreshResources(forUser username: String) async { //.. } I am expecting checkForDownloads.refreshResources to finish downloading first, then proceed to next statement.
Replies
1
Boosts
0
Views
974
Activity
Jun ’22