• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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