1// RUN: %clang_tsan %s -o %t -framework Foundation
2// RUN: %deflake %run %t 2>&1 | FileCheck %s
3
4#import <Foundation/Foundation.h>
5
6#import "../test.h"
7
8pthread_mutex_t m1;
9pthread_mutex_t m2;
10
11int main(int argc, const char *argv[]) {
12  barrier_init(&barrier, 2);
13  fprintf(stderr, "Hello world.\n");
14
15  pthread_mutex_init(&m1, NULL);
16  pthread_mutex_init(&m2, NULL);
17
18  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
19    pthread_mutex_lock(&m1);
20    pthread_mutex_lock(&m2);
21    pthread_mutex_unlock(&m2);
22    pthread_mutex_unlock(&m1);
23
24    barrier_wait(&barrier);
25  });
26  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
27    barrier_wait(&barrier);
28
29    pthread_mutex_lock(&m2);
30    pthread_mutex_lock(&m1);
31    pthread_mutex_unlock(&m1);
32    pthread_mutex_unlock(&m2);
33
34    dispatch_sync(dispatch_get_main_queue(), ^{
35      CFRunLoopStop(CFRunLoopGetCurrent());
36    });
37  });
38
39  CFRunLoopRun();
40
41  fprintf(stderr, "Done.\n");
42  return 0;
43}
44
45// CHECK: Hello world.
46// CHECK: WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock)
47// CHECK: Done.
48