diff --git a/compiler-rt/test/tsan/Darwin/gcd-blocks.mm b/compiler-rt/test/tsan/Darwin/gcd-blocks.mm --- a/compiler-rt/test/tsan/Darwin/gcd-blocks.mm +++ b/compiler-rt/test/tsan/Darwin/gcd-blocks.mm @@ -1,7 +1,7 @@ -// RUN: %clangxx_tsan %s -o %t -framework Foundation -// RUN: %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan %s -o %t +// RUN: %run %t 2>&1 | FileCheck %s --implicit-check-not='ThreadSanitizer' -#import +#include "runloop.h" int main() { fprintf(stderr, "start\n"); @@ -19,16 +19,13 @@ fprintf(stderr, "block_var = %ld\n", block_var); dispatch_sync(dispatch_get_main_queue(), ^{ - CFRunLoopStop(CFRunLoopGetCurrent()); + RunLoopStop(); }); }); - - CFRunLoopRun(); - fprintf(stderr, "done\n"); + + RunLoopRun(); } // CHECK: start // CHECK: block_var = 42 -// CHECK: done -// CHECK-NOT: WARNING: ThreadSanitizer -// CHECK-NOT: CHECK failed +// CHECK: Done. diff --git a/compiler-rt/test/tsan/Darwin/runloop.h b/compiler-rt/test/tsan/Darwin/runloop.h new file mode 100644 --- /dev/null +++ b/compiler-rt/test/tsan/Darwin/runloop.h @@ -0,0 +1,30 @@ +// Emulation of Foundation RunLoop functionality. +// Supports porting of libdispatch tests to platforms without Foundation. + +#include +#include // fprintf +#include // exit + +static bool runloop_exit = false; + +static inline void RunLoopStop() { + runloop_exit = true; +} + +// Start executing blocks submitted to the main queue. +// Never returns (should be the last statement in a test's main function). Loops +// indefinitely until a call to RunLoopStop is scheduled on the main queue. +// Prints "Done." to stderr before exiting. +static inline void RunLoopRun() { + __block dispatch_block_t exitBlock = ^{ + if (runloop_exit) { + fprintf(stderr, "Done.\n"); + exit(0); + } else { + dispatch_async(dispatch_get_main_queue(), exitBlock); + } + }; + + dispatch_async(dispatch_get_main_queue(), exitBlock); + dispatch_main(); // Never returns +}