blob: 33ea7c76c01958c3c591127048c1c1ccd8afbfce [file] [log] [blame]
#ifdef OS_darwin_10
#include <dispatch/dispatch.h>
#endif
#include <gtest/gtest.h>
#include <sys/types.h>
#include <sys/mman.h>
#import <Foundation/Foundation.h>
#include "test_utils.h"
#include "gtest_fixture_injection.h"
#ifndef OS_darwin
#error "This file should be built on Darwin only."
#endif
class Task {
public:
Task() {};
void Run() { printf("Inside Task::Run()\n"); }
};
@interface TaskOperation : NSOperation {
@private
Task *task_;
}
+ (id)taskOperationWithTask:(Task*)task;
- (id)initWithTask:(Task*)task;
@end // @interface TaskOperation
@implementation TaskOperation
+ (id)taskOperationWithTask:(Task*)task {
return [[TaskOperation alloc] initWithTask:task];
}
- (id)init {
return [self initWithTask:NULL];
}
- (id)initWithTask:(Task*)task {
if ((self = [super init])) {
task_ = task;
}
return self;
}
- (void)main {
if (!task_) {
return;
}
task_->Run();
delete task_;
task_ = NULL;
}
- (void)dealloc {
if (task_) delete task_;
[super dealloc];
}
@end // @implementation TaskOperation
namespace MacTests {
// Regression test for https://bugs.kde.org/show_bug.cgi?id=216837.
TEST(MacTests, WqthreadRegressionTest) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
Task *task = new Task();
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:[TaskOperation taskOperationWithTask:task]];
sleep(1); // wait for the worker thread to start.
// If the bug is still there, ThreadSanitizer should crash after starting
// the worker thread.
[pool release];
}
// Regression test for a bug with passing a 32-bit value instead of a 64-bit
// as the last parameter to mmap().
TEST(MacTests, ShmMmapRegressionTest) {
#ifdef OS_darwin_9
int md;
void *virt_addr;
shm_unlink("apple.shm.notification_center");
md = shm_open("apple.shm.notification_center", 0, 0);
if (md != -1) {
virt_addr = mmap(0, 4096, 1, 1, md, 0);
if (virt_addr == (void*)-1) {
shm_unlink("apple.shm.notification_center");
FAIL() << "mmap returned -1";
} else {
munmap(virt_addr, 4096);
shm_unlink("apple.shm.notification_center");
}
} else {
printf("shm_open() returned -1\n");
}
#endif
}
} // namespace MacTests
#ifdef OS_darwin_10
namespace SnowLeopardTests {
int GLOB = 0;
StealthNotification sn1, sn2;
void worker_do_add(int *var, int val,
StealthNotification *notify,
StealthNotification *waitfor) {
(*var) += val;
fprintf(stderr, "var=%d\n", *var);
notify->signal();
// Make sure that the callbacks are ran on different threads.
if (waitfor) {
waitfor->wait();
}
}
TEST(SnowLeopardTests, GCD_GlobalQueueRace) {
ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "SnowLeopardTests.GCD_GlobalQueueRace TP.");
dispatch_queue_t queue = dispatch_get_global_queue(0,0);
dispatch_block_t block_plus = ^{ worker_do_add(&GLOB, 1, &sn1, &sn2); };
dispatch_block_t block_minus = ^{ worker_do_add(&GLOB, -1, &sn2, NULL); };
dispatch_async(queue, block_plus);
dispatch_async(queue, block_minus);
sn1.wait();
sn2.wait();
}
} // namespace SnowLeopardTests
#endif