1#ifdef OS_darwin_10 2#include <dispatch/dispatch.h> 3#endif 4 5#include <gtest/gtest.h> 6#include <sys/types.h> 7#include <sys/mman.h> 8#import <Foundation/Foundation.h> 9 10#include "test_utils.h" 11#include "gtest_fixture_injection.h" 12 13#ifndef OS_darwin 14#error "This file should be built on Darwin only." 15#endif 16 17class Task { 18 public: 19 Task() {}; 20 void Run() { printf("Inside Task::Run()\n"); } 21}; 22 23@interface TaskOperation : NSOperation { 24 @private 25 Task *task_; 26} 27 28+ (id)taskOperationWithTask:(Task*)task; 29 30- (id)initWithTask:(Task*)task; 31 32@end // @interface TaskOperation 33 34@implementation TaskOperation 35 36+ (id)taskOperationWithTask:(Task*)task { 37 return [[TaskOperation alloc] initWithTask:task]; 38} 39 40- (id)init { 41 return [self initWithTask:NULL]; 42} 43 44- (id)initWithTask:(Task*)task { 45 if ((self = [super init])) { 46 task_ = task; 47 } 48 return self; 49} 50 51- (void)main { 52 if (!task_) { 53 return; 54 } 55 56 task_->Run(); 57 delete task_; 58 task_ = NULL; 59} 60 61- (void)dealloc { 62 if (task_) delete task_; 63 [super dealloc]; 64} 65 66@end // @implementation TaskOperation 67 68namespace MacTests { 69// Regression test for https://bugs.kde.org/show_bug.cgi?id=216837. 70TEST(MacTests, WqthreadRegressionTest) { 71 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 72 Task *task = new Task(); 73 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 74 [queue addOperation:[TaskOperation taskOperationWithTask:task]]; 75 76 sleep(1); // wait for the worker thread to start. 77 // If the bug is still there, ThreadSanitizer should crash after starting 78 // the worker thread. 79 [pool release]; 80} 81 82// Regression test for a bug with passing a 32-bit value instead of a 64-bit 83// as the last parameter to mmap(). 84TEST(MacTests, ShmMmapRegressionTest) { 85#ifdef OS_darwin_9 86 int md; 87 void *virt_addr; 88 shm_unlink("apple.shm.notification_center"); 89 md = shm_open("apple.shm.notification_center", 0, 0); 90 if (md != -1) { 91 virt_addr = mmap(0, 4096, 1, 1, md, 0); 92 if (virt_addr == (void*)-1) { 93 shm_unlink("apple.shm.notification_center"); 94 FAIL() << "mmap returned -1"; 95 } else { 96 munmap(virt_addr, 4096); 97 shm_unlink("apple.shm.notification_center"); 98 } 99 } else { 100 printf("shm_open() returned -1\n"); 101 } 102#endif 103} 104 105} // namespace MacTests 106 107#ifdef OS_darwin_10 108namespace SnowLeopardTests { 109 110int GLOB = 0; 111StealthNotification sn1, sn2; 112 113void worker_do_add(int *var, int val, 114 StealthNotification *notify, 115 StealthNotification *waitfor) { 116 (*var) += val; 117 fprintf(stderr, "var=%d\n", *var); 118 notify->signal(); 119 // Make sure that the callbacks are ran on different threads. 120 if (waitfor) { 121 waitfor->wait(); 122 } 123} 124 125TEST(SnowLeopardTests, GCD_GlobalQueueRace) { 126 ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "SnowLeopardTests.GCD_GlobalQueueRace TP."); 127 dispatch_queue_t queue = dispatch_get_global_queue(0,0); 128 dispatch_block_t block_plus = ^{ worker_do_add(&GLOB, 1, &sn1, &sn2); }; 129 dispatch_block_t block_minus = ^{ worker_do_add(&GLOB, -1, &sn2, NULL); }; 130 dispatch_async(queue, block_plus); 131 dispatch_async(queue, block_minus); 132 sn1.wait(); 133 sn2.wait(); 134} 135 136} // namespace SnowLeopardTests 137#endif 138