• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: dispatch_apply() on an NSArray and Thread Sanitizer
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: dispatch_apply() on an NSArray and Thread Sanitizer


  • Subject: Re: dispatch_apply() on an NSArray and Thread Sanitizer
  • From: Sean McBride via Cocoa-dev <email@hidden>
  • Date: Tue, 19 Apr 2022 19:26:57 -0400

On 19 Apr 2022, at 18:47, Saagar Jha wrote:

If Thread Sanitizer says your code has a race, it almost certainly has a race.

Yeah, that's been my general experience until now.

Your simple code seems OK superficially, but there are a couple things that could be problematic here: either your real code is actually mutating something, or (unlikely) you are touching some internal state, perhaps a CoW optimization, that is not visible to you but is silently changing things under the hood.

In case it wasn't clear, the code snippet in my email actually reproduces the issue. I created a fresh Xcode project and it's literally just:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
        NSArray* array = @[@5, @6, @7, @8, @9, @10, @11];

[array enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSNumber* num, NSUInteger idx, BOOL* stop) {
                array[idx];
        }];
}

TSan complains with this on macOS 12.3.1 on an M1 Mac Mini with Xcode 13.3. But on an Intel Mac Pro, macOS 11.6.6 with Xcode 13.2.1, TSan does not complain.

In any case, I would generally suggest using -[NSArray enumerateObjectsAtIndexes:options:usingBlock:] with the NSEnumerationConcurrent flag, which should rule out any issues with concurrent access on the array itself.

I tried enumerateObjectsWithOptions:usingBlock: and TSan doesn't complain with it. But I was suspicious of that and added an NSLog to print the index, and even after adding random sleeps:

[array enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSNumber* nub, NSUInteger idx, BOOL* stop) {
                usleep(arc4random_uniform(1000000));
                NSLog(@"idx: %d", idx);
                array[idx];
        }];

The thing is *not* running concurrently on the M1. The indices are always printed in order. Weird.

Sean
_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Follow-Ups:
    • Re: dispatch_apply() on an NSArray and Thread Sanitizer
      • From: Rob Petrovec via Cocoa-dev <email@hidden>
References: 
 >dispatch_apply() on an NSArray and Thread Sanitizer (From: Sean McBride via Cocoa-dev <email@hidden>)
 >Re: dispatch_apply() on an NSArray and Thread Sanitizer (From: Saagar Jha via Cocoa-dev <email@hidden>)

  • Prev by Date: Re: dispatch_apply() on an NSArray and Thread Sanitizer
  • Next by Date: Re: dispatch_apply() on an NSArray and Thread Sanitizer
  • Previous by thread: Re: dispatch_apply() on an NSArray and Thread Sanitizer
  • Next by thread: Re: dispatch_apply() on an NSArray and Thread Sanitizer
  • Index(es):
    • Date
    • Thread