brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.6 KiB · 0e986c4 Raw
130 lines · plain
1#import <Foundation/Foundation.h>2#import <pthread.h>3 4long my_global;5 6void *Thread1(void *arg) {7    my_global = 42;8    return NULL;9}10 11void *Thread2(void *arg) {12    my_global = 144;13    return NULL;14}15 16void TestDataRace1() {17    pthread_t t1, t2;18    pthread_create(&t1, NULL, Thread1, NULL);19    pthread_create(&t2, NULL, Thread2, NULL);20    21    pthread_join(t1, NULL);22    pthread_join(t2, NULL);23}24 25void TestInvalidMutex() {26    pthread_mutex_t m = {0};27    pthread_mutex_lock(&m);28    29    pthread_mutex_init(&m, NULL);30    pthread_mutex_lock(&m);31    pthread_mutex_unlock(&m);32    pthread_mutex_destroy(&m);33    pthread_mutex_lock(&m);34}35 36void TestMutexWrongLock() {37    pthread_mutex_t m = {0};38    pthread_mutex_init(&m, NULL);39    pthread_mutex_unlock(&m);40}41 42long some_global;43 44void TestDataRaceBlocks1() {45    dispatch_queue_t q = dispatch_queue_create("my.queue", DISPATCH_QUEUE_CONCURRENT);46    47    for (int i = 0; i < 2; i++) {48        dispatch_async(q, ^{49            some_global++;  // race 150            51            usleep(100000);  // force the blocks to be on different threads52        });53    }54    55    usleep(100000);56    dispatch_barrier_sync(q, ^{ });57}58 59void TestDataRaceBlocks2() {60    dispatch_queue_t q = dispatch_queue_create("my.queue2", DISPATCH_QUEUE_CONCURRENT);61    62    char *c;63    64    c = malloc((rand() % 1000) + 10);65    for (int i = 0; i < 2; i++) {66        dispatch_async(q, ^{67            c[0] = 'x';  // race 268            fprintf(stderr, "tid: %p\n", pthread_self());69            usleep(100000);  // force the blocks to be on different threads70        });71    }72    dispatch_barrier_sync(q, ^{ });73    74    free(c);75}76 77void TestUseAfterFree() {78    char *c;79    80    c = malloc((rand() % 1000) + 10);81    free(c);82    c[0] = 'x';83}84 85void TestRacePipe() {86    dispatch_queue_t q = dispatch_queue_create("my.queue3", DISPATCH_QUEUE_CONCURRENT);87    88    int a[2];89    pipe(a);90    int fd = a[0];91    92    for (int i = 0; i < 2; i++) {93        dispatch_async(q, ^{94            write(fd, "abc", 3);95            usleep(100000);  // force the blocks to be on different threads96        });97        dispatch_async(q, ^{98            close(fd);99            usleep(100000);100        });101    }102    103    dispatch_barrier_sync(q, ^{ });104}105 106void TestThreadLeak() {107    pthread_t t1;108    pthread_create(&t1, NULL, Thread1, NULL);109}110 111int main(int argc, const char * argv[]) {112    TestDataRace1();113    114    TestInvalidMutex();115    116    TestMutexWrongLock();117    118    TestDataRaceBlocks1();119    120    TestDataRaceBlocks2();121    122    TestUseAfterFree();123    124    TestRacePipe();125    126    TestThreadLeak();127 128    return 0;129}130