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

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.6k
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
944
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.2k
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
2k
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
981
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.2k
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.5k
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
3.9k
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.3k
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.2k
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.0k
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
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.4k
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
920
Jun ’22
Information about Multithreading and Background Task
Hi, i'm quite new to iOS Development and i'm looking for some useful informations for my project. The phone connects to a device via BLE and receives data from it at an high rate ( 4x hundreds data points per seconds) [--> Thread 1 ] and this data need to be analyzed in real time [--> Thread 2]. The app has to work for between 1 to 8 hours and all of this needs to work both when the phone is in the foreground and when is in the background (Background Task). Can you help me with any useful tips / information on how to accomplish this? Thank you
0
0
572
May ’22
Swift - get current time on Windows
Hi, I'm trying to use time measurement in a test application on Windows. Therefore I use the DispatchTime.now() function like this: let timeBefore = DispatchTime.now() While searching online all examples used the function like this. Now I'm getting an error while compiling: ←[1msrc/main.swift:115:26: ←[0m←[0;1;31merror: ←[0m←[1mcannot find 'DispatchTime' in scope ←[0m let timeBefore = DispatchTime.now() ←[0;1;32m ^~~~~~~~~~~~ ←[0mNMAKE : fatal error U1077: "swiftc": Rückgabe-Code "0x1" Is there something missing? Like an import? Or is this an issue with Windows and if that's the case, is there a workaround or other function to use?
1
0
780
Apr ’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.6k
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
944
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.2k
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
2k
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
981
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.2k
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.5k
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
3.9k
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.3k
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.2k
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.0k
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
898
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
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.4k
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
920
Activity
Jun ’22
Information about Multithreading and Background Task
Hi, i'm quite new to iOS Development and i'm looking for some useful informations for my project. The phone connects to a device via BLE and receives data from it at an high rate ( 4x hundreds data points per seconds) [--> Thread 1 ] and this data need to be analyzed in real time [--> Thread 2]. The app has to work for between 1 to 8 hours and all of this needs to work both when the phone is in the foreground and when is in the background (Background Task). Can you help me with any useful tips / information on how to accomplish this? Thank you
Replies
0
Boosts
0
Views
572
Activity
May ’22
Swift - get current time on Windows
Hi, I'm trying to use time measurement in a test application on Windows. Therefore I use the DispatchTime.now() function like this: let timeBefore = DispatchTime.now() While searching online all examples used the function like this. Now I'm getting an error while compiling: ←[1msrc/main.swift:115:26: ←[0m←[0;1;31merror: ←[0m←[1mcannot find 'DispatchTime' in scope ←[0m let timeBefore = DispatchTime.now() ←[0;1;32m ^~~~~~~~~~~~ ←[0mNMAKE : fatal error U1077: "swiftc": Rückgabe-Code "0x1" Is there something missing? Like an import? Or is this an issue with Windows and if that's the case, is there a workaround or other function to use?
Replies
1
Boosts
0
Views
780
Activity
Apr ’22