diff options
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.m | 138 |
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; +} |