summaryrefslogtreecommitdiffstats
path: root/lldb/packages/Python/lldbsuite/test/functionalities/tsan/multiple/main.m
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/packages/Python/lldbsuite/test/functionalities/tsan/multiple/main.m')
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/tsan/multiple/main.m138
1 files changed, 138 insertions, 0 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/tsan/multiple/main.m b/lldb/packages/Python/lldbsuite/test/functionalities/tsan/multiple/main.m
new file mode 100644
index 00000000000..f7c48b45422
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/tsan/multiple/main.m
@@ -0,0 +1,138 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#import <Foundation/Foundation.h>
+#import <pthread.h>
+
+long my_global;
+
+void *Thread1(void *arg) {
+ my_global = 42;
+ return NULL;
+}
+
+void *Thread2(void *arg) {
+ my_global = 144;
+ return NULL;
+}
+
+void TestDataRace1() {
+ pthread_t t1, t2;
+ pthread_create(&t1, NULL, Thread1, NULL);
+ pthread_create(&t2, NULL, Thread2, NULL);
+
+ pthread_join(t1, NULL);
+ pthread_join(t2, NULL);
+}
+
+void TestInvalidMutex() {
+ pthread_mutex_t m = {0};
+ pthread_mutex_lock(&m);
+
+ pthread_mutex_init(&m, NULL);
+ pthread_mutex_lock(&m);
+ pthread_mutex_unlock(&m);
+ pthread_mutex_destroy(&m);
+ pthread_mutex_lock(&m);
+}
+
+void TestMutexWrongLock() {
+ pthread_mutex_t m = {0};
+ pthread_mutex_init(&m, NULL);
+ pthread_mutex_unlock(&m);
+}
+
+long some_global;
+
+void TestDataRaceBlocks1() {
+ dispatch_queue_t q = dispatch_queue_create("my.queue", DISPATCH_QUEUE_CONCURRENT);
+
+ for (int i = 0; i < 2; i++) {
+ dispatch_async(q, ^{
+ some_global++; // race 1
+
+ usleep(100000); // force the blocks to be on different threads
+ });
+ }
+
+ usleep(100000);
+ dispatch_barrier_sync(q, ^{ });
+}
+
+void TestDataRaceBlocks2() {
+ dispatch_queue_t q = dispatch_queue_create("my.queue2", DISPATCH_QUEUE_CONCURRENT);
+
+ char *c;
+
+ c = malloc((rand() % 1000) + 10);
+ for (int i = 0; i < 2; i++) {
+ dispatch_async(q, ^{
+ c[0] = 'x'; // race 2
+ fprintf(stderr, "tid: %p\n", pthread_self());
+ usleep(100000); // force the blocks to be on different threads
+ });
+ }
+ dispatch_barrier_sync(q, ^{ });
+
+ free(c);
+}
+
+void TestUseAfterFree() {
+ char *c;
+
+ c = malloc((rand() % 1000) + 10);
+ free(c);
+ c[0] = 'x';
+}
+
+void TestRacePipe() {
+ dispatch_queue_t q = dispatch_queue_create("my.queue3", DISPATCH_QUEUE_CONCURRENT);
+
+ int a[2];
+ pipe(a);
+ int fd = a[0];
+
+ for (int i = 0; i < 2; i++) {
+ dispatch_async(q, ^{
+ write(fd, "abc", 3);
+ usleep(100000); // force the blocks to be on different threads
+ });
+ dispatch_async(q, ^{
+ close(fd);
+ usleep(100000);
+ });
+ }
+
+ dispatch_barrier_sync(q, ^{ });
+}
+
+void TestThreadLeak() {
+ pthread_t t1;
+ pthread_create(&t1, NULL, Thread1, NULL);
+}
+
+int main(int argc, const char * argv[]) {
+ TestDataRace1();
+
+ TestInvalidMutex();
+
+ TestMutexWrongLock();
+
+ TestDataRaceBlocks1();
+
+ TestDataRaceBlocks2();
+
+ TestUseAfterFree();
+
+ TestRacePipe();
+
+ TestThreadLeak();
+
+ return 0;
+}
OpenPOWER on IntegriCloud