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