diff --git a/compiler-rt/test/tsan/Darwin/dispatch_test.h b/compiler-rt/test/tsan/Darwin/dispatch_test.h new file mode 100644 --- /dev/null +++ b/compiler-rt/test/tsan/Darwin/dispatch_test.h @@ -0,0 +1,26 @@ +#include +#include +#include // Included for convenience + +static dispatch_semaphore_t completion_semaphore; + +static inline void init_completion_signaling() { + assert(dispatch_get_current_queue() == dispatch_get_main_queue()); + completion_semaphore = dispatch_semaphore_create(0); +} + +static inline void signal_completion() { + assert(dispatch_get_current_queue() != dispatch_get_main_queue()); + dispatch_semaphore_signal(completion_semaphore); +} + +static inline void wait_for_completion_n(unsigned count) { + assert(dispatch_get_current_queue() == dispatch_get_main_queue()); + for (unsigned i = 0; i < count; i++) + dispatch_semaphore_wait(completion_semaphore, DISPATCH_TIME_FOREVER); + dispatch_release(completion_semaphore); +} + +static inline void wait_for_completion() { + wait_for_completion_n(1); +} diff --git a/compiler-rt/test/tsan/Darwin/gcd-after.mm b/compiler-rt/test/tsan/Darwin/gcd-after.mm --- a/compiler-rt/test/tsan/Darwin/gcd-after.mm +++ b/compiler-rt/test/tsan/Darwin/gcd-after.mm @@ -1,7 +1,7 @@ -// RUN: %clang_tsan %s -o %t -framework Foundation +// RUN: %clang_tsan %s -o %t // RUN: %run %t 2>&1 | FileCheck %s -#import +#include "dispatch_test.h" long my_global; long my_global2; @@ -9,29 +9,26 @@ void callback(void *context) { my_global2 = 42; - dispatch_async(dispatch_get_main_queue(), ^{ - CFRunLoopStop(CFRunLoopGetMain()); - }); + signal_completion(); } int main(int argc, const char *argv[]) { fprintf(stderr, "start\n"); + init_completion_signaling(); - my_global = 10; dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + + my_global = 10; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_MSEC)), q, ^{ my_global = 42; - dispatch_async(dispatch_get_main_queue(), ^{ - CFRunLoopStop(CFRunLoopGetMain()); - }); + signal_completion(); }); - CFRunLoopRun(); my_global2 = 10; dispatch_after_f(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_MSEC)), q, NULL, &callback); - CFRunLoopRun(); + wait_for_completion_n(2); fprintf(stderr, "done\n"); return 0; } diff --git a/compiler-rt/test/tsan/Darwin/gcd-async-norace.mm b/compiler-rt/test/tsan/Darwin/gcd-async-norace.mm --- a/compiler-rt/test/tsan/Darwin/gcd-async-norace.mm +++ b/compiler-rt/test/tsan/Darwin/gcd-async-norace.mm @@ -1,24 +1,23 @@ -// RUN: %clang_tsan %s -o %t -framework Foundation +// RUN: %clang_tsan %s -o %t // RUN: %run %t 2>&1 | FileCheck %s -#import +#include "dispatch_test.h" long global; int main() { - NSLog(@"Hello world."); + fprintf(stderr, "Hello world.\n"); + init_completion_signaling(); global = 42; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ global = 43; - dispatch_sync(dispatch_get_main_queue(), ^{ - CFRunLoopStop(CFRunLoopGetCurrent()); - }); + signal_completion(); }); - CFRunLoopRun(); - NSLog(@"Done."); + wait_for_completion(); + fprintf(stderr, "Done.\n"); } // CHECK: Hello world. diff --git a/compiler-rt/test/tsan/Darwin/gcd-async-race.mm b/compiler-rt/test/tsan/Darwin/gcd-async-race.mm --- a/compiler-rt/test/tsan/Darwin/gcd-async-race.mm +++ b/compiler-rt/test/tsan/Darwin/gcd-async-race.mm @@ -1,15 +1,15 @@ -// RUN: %clang_tsan %s -o %t -framework Foundation +// RUN: %clang_tsan %s -o %t // RUN: %deflake %run %t 2>&1 | FileCheck %s -#import - -#import "../test.h" +#include "dispatch_test.h" +#include "../test.h" long global; int main() { - NSLog(@"Hello world."); + fprintf(stderr, "Hello world.\n"); print_address("addr=", 1, &global); + init_completion_signaling(); barrier_init(&barrier, 2); global = 42; @@ -22,13 +22,11 @@ barrier_wait(&barrier); global = 44; - dispatch_sync(dispatch_get_main_queue(), ^{ - CFRunLoopStop(CFRunLoopGetCurrent()); - }); + signal_completion(); }); - CFRunLoopRun(); - NSLog(@"Done."); + wait_for_completion(); + fprintf(stderr, "Done.\n"); } // CHECK: Hello world. diff --git a/compiler-rt/test/tsan/Darwin/gcd-barrier-race.mm b/compiler-rt/test/tsan/Darwin/gcd-barrier-race.mm --- a/compiler-rt/test/tsan/Darwin/gcd-barrier-race.mm +++ b/compiler-rt/test/tsan/Darwin/gcd-barrier-race.mm @@ -1,15 +1,15 @@ -// RUN: %clang_tsan %s -o %t -framework Foundation +// RUN: %clang_tsan %s -o %t // RUN: %deflake %run %t 2>&1 | FileCheck %s -#import - -#import "../test.h" +#include "dispatch_test.h" +#include "../test.h" long global; int main() { fprintf(stderr, "Hello world.\n"); print_address("addr=", 1, &global); + init_completion_signaling(); barrier_init(&barrier, 2); dispatch_queue_t q = dispatch_queue_create("my.queue", DISPATCH_QUEUE_CONCURRENT); @@ -31,13 +31,11 @@ barrier_wait(&barrier); global = 44; - dispatch_sync(dispatch_get_main_queue(), ^{ - CFRunLoopStop(CFRunLoopGetCurrent()); - }); + signal_completion(); }); }); - CFRunLoopRun(); + wait_for_completion(); fprintf(stderr, "Done.\n"); } diff --git a/compiler-rt/test/tsan/Darwin/gcd-barrier.mm b/compiler-rt/test/tsan/Darwin/gcd-barrier.mm --- a/compiler-rt/test/tsan/Darwin/gcd-barrier.mm +++ b/compiler-rt/test/tsan/Darwin/gcd-barrier.mm @@ -1,15 +1,14 @@ -// RUN: %clang_tsan %s -o %t -framework Foundation +// RUN: %clang_tsan %s -o %t // RUN: %run %t 2>&1 | FileCheck %s -#import - -#import "../test.h" +#include "dispatch_test.h" +#include "../test.h" long global; int main() { fprintf(stderr, "Hello world.\n"); - print_address("addr=", 1, &global); + init_completion_signaling(); barrier_init(&barrier, 2); dispatch_queue_t q = dispatch_queue_create("my.queue", DISPATCH_QUEUE_CONCURRENT); @@ -34,13 +33,11 @@ }); barrier_wait(&barrier); - - dispatch_sync(dispatch_get_main_queue(), ^{ - CFRunLoopStop(CFRunLoopGetCurrent()); - }); + + signal_completion(); }); - CFRunLoopRun(); + wait_for_completion(); fprintf(stderr, "Done.\n"); } 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,29 +1,29 @@ -// RUN: %clangxx_tsan %s -o %t -framework Foundation +// RUN: %clang_tsan %s -o %t // RUN: %run %t 2>&1 | FileCheck %s -#import +#include "dispatch_test.h" int main() { fprintf(stderr, "start\n"); + init_completion_signaling(); dispatch_queue_t background_q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); - dispatch_queue_t main_q = dispatch_get_main_queue(); + dispatch_queue_t serial_q = dispatch_queue_create("my.queue", DISPATCH_QUEUE_SERIAL); + assert(background_q != serial_q); dispatch_async(background_q, ^{ __block long block_var = 0; - dispatch_sync(main_q, ^{ + dispatch_sync(serial_q, ^{ block_var = 42; }); fprintf(stderr, "block_var = %ld\n", block_var); - dispatch_sync(dispatch_get_main_queue(), ^{ - CFRunLoopStop(CFRunLoopGetCurrent()); - }); + signal_completion(); }); - - CFRunLoopRun(); + + wait_for_completion(); fprintf(stderr, "done\n"); }