blob: 2daa877962ea25662a36e92d1ee30676033dcb79 [file] [edit]
// Check that dispatch_apply() does not report a false data race when the
// dispatched block's copy helper retains the captures into the heap block.
// NOTE: this test may spuriously pass, but is a best effort to reproduce
// the problem, which relies on OS thread scheduling mechanics.
// RUN: %clang_tsan %s -o %t -framework Foundation
// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
#import <dispatch/dispatch.h>
int main() {
// Strong capture -> non-trivial copy helper. Enough iterations that
// libdispatch fans out to worker threads (captures read off-thread).
const size_t n = 1024;
NSMutableArray *items = [NSMutableArray array];
for (size_t i = 0; i < n; i++)
[items addObject:@(i)];
dispatch_apply(n, dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0),
^(size_t idx) {
(void)[items objectAtIndex:idx];
});
NSLog(@"Done.");
return 0;
}
// CHECK-NOT: WARNING: ThreadSanitizer
// CHECK: Done.