1610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov/* 2610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov This file is part of Valgrind, a dynamic binary instrumentation 3610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov framework. 4610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 5610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov Copyright (C) 2008-2008 Google Inc 6610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov opensource@google.com 7610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 8610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov This program is free software; you can redistribute it and/or 9610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov modify it under the terms of the GNU General Public License as 10610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov published by the Free Software Foundation; either version 2 of the 11610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov License, or (at your option) any later version. 12610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 13610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov This program is distributed in the hope that it will be useful, but 14610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov WITHOUT ANY WARRANTY; without even the implied warranty of 15610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov General Public License for more details. 17610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 18610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov You should have received a copy of the GNU General Public License 19610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov along with this program; if not, write to the Free Software 20610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 21610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 02111-1307, USA. 22610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 23610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov The GNU General Public License is contained in the file COPYING. 24610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov*/ 25610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 26610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov/* Author: Timur Iskhodzhanov <opensource@google.com> 27610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 28610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov This file contains a set of Windows-specific unit tests for 29610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov a data race detection tool. 30610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov*/ 31610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 32610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#include <gtest/gtest.h> 33610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#include "test_utils.h" 34610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#include "gtest_fixture_injection.h" 35610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 36610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid DummyWorker() { 37610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 38610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 39610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid LongWorker() { 40610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov Sleep(1); 41610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov volatile int i = 1 << 20; 42610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov while(i--); 43610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 44610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 45610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid WriteWorker(int *var) { 46610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov LongWorker(); 47610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov *var = 42; 48610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 49610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 50610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid VeryLongWriteWorker(int *var) { 51610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov Sleep(1000); 52610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov *var = 42; 53610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 54610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 55610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, WindowsCreateThreadFailureTest) { // {{{1 56610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov HANDLE t = ::CreateThread(0, -1, 57610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (LPTHREAD_START_ROUTINE)DummyWorker, 0, 0, 0); 58610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(t == 0); 59610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 60610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 61610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, DISABLED_WindowsCreateThreadSuspendedTest) { // {{{1 62610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // Hangs under TSan, see 63610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // http://code.google.com/p/data-race-test/issues/detail?id=61 64610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int *var = new int; 65610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov HANDLE t = ::CreateThread(0, 0, 66610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (LPTHREAD_START_ROUTINE)WriteWorker, var, 67610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CREATE_SUSPENDED, 0); 68610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(t > 0); 69610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(t, 200)); 70610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov *var = 1; 71610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_EQ(1, ResumeThread(t)); 72610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(t, INFINITE)); 73610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_EQ(42, *var); 74610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov delete var; 75610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 76610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 77610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, WindowsThreadStackSizeTest) { // {{{1 78610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// Just spawn few threads with different stack sizes. 79610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int sizes[3] = {1 << 19, 1 << 21, 1 << 22}; 80610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov for (int i = 0; i < 3; i++) { 81610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov HANDLE t = ::CreateThread(0, sizes[i], 82610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (LPTHREAD_START_ROUTINE)DummyWorker, 0, 0, 0); 83610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(t > 0); 84610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(t, INFINITE)); 85610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CloseHandle(t); 86610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 87610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 88610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 89610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, WindowsJoinWithTimeout) { // {{{1 90610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov HANDLE t = ::CreateThread(0, 0, 91610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (LPTHREAD_START_ROUTINE)LongWorker, 0, 0, 0); 92610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ASSERT_TRUE(t > 0); 93610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(t, 1)); 94610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(t, INFINITE)); 95610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CloseHandle(t); 96610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 97610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 98610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, HappensBeforeOnThreadJoin) { // {{{1 99610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int *var = new int; 100610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov HANDLE t = ::CreateThread(0, 0, 101610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (LPTHREAD_START_ROUTINE)WriteWorker, var, 0, 0); 102610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ASSERT_TRUE(t > 0); 103610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // Calling WaitForSingleObject two times to make sure the H-B arc 104610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // is created on the second call. There was a bug that the thread handle 105610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // was deleted even when WaitForSingleObject timed out. 106610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(t, 1)); 107610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(t, INFINITE)); 108610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_EQ(*var, 42); 109610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CloseHandle(t); 110610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov delete var; 111610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 112610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 113610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, HappensBeforeOnThreadJoinTidReuse) { // {{{1 114610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov HANDLE t1 = ::CreateThread(0, 0, (LPTHREAD_START_ROUTINE)DummyWorker, 0, 0, 0); 115610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CloseHandle(t1); 116610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov Sleep(1000); 117610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 118610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int *var = new int; 119610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov HANDLE t2 = ::CreateThread(0, 0, 120610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (LPTHREAD_START_ROUTINE)WriteWorker, var, 0, 0); 121610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("t1 = %d, t2 = %d\n"); 122610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(t2 > 0); 123610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(WAIT_OBJECT_0 == ::WaitForSingleObject(t2, INFINITE)); 124610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(*var == 42); 125610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov delete var; 126610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 127610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 128610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, WaitForMultipleObjectsWaitAllTest) { 129610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int var1 = 13, 130610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov var2 = 13; 131610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov HANDLE t1 = ::CreateThread(0, 0, 132610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (LPTHREAD_START_ROUTINE)WriteWorker, &var1, 0, 0), 133610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t2 = ::CreateThread(0, 0, 134610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (LPTHREAD_START_ROUTINE)WriteWorker, &var2, 0, 0); 135610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ASSERT_TRUE(t1 > 0); 136610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ASSERT_TRUE(t2 > 0); 137610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 138610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov HANDLE handles[2] = {t1, t2}; 139610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // Calling WaitForMultipleObjectsTest two times to make sure the H-B arc 140610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // are created on the second call. 141610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_EQ(WAIT_TIMEOUT, ::WaitForMultipleObjects(2, handles, TRUE, 1)); 142610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_EQ(WAIT_OBJECT_0, ::WaitForMultipleObjects(2, handles, TRUE, INFINITE)); 143610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_EQ(var1, 42); 144610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_EQ(var2, 42); 145610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CloseHandle(t1); 146610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CloseHandle(t2); 147610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 148610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 149610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, WaitForMultipleObjectsWaitOneTest) { 150610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int var1 = 13, 151610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov var2 = 13; 152610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov HANDLE t1 = ::CreateThread(0, 0, 153610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (LPTHREAD_START_ROUTINE)VeryLongWriteWorker, &var1, 0, 0), 154610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t2 = ::CreateThread(0, 0, 155610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (LPTHREAD_START_ROUTINE)WriteWorker, &var2, 0, 0); 156610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ASSERT_TRUE(t1 > 0); 157610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ASSERT_TRUE(t2 > 0); 158610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 159610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov HANDLE handles[2] = {t1, t2}; 160610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // Calling WaitForMultipleObjectsTest two times to make sure the H-B arc 161610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // are created on the second call. 162610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_EQ(WAIT_TIMEOUT, ::WaitForMultipleObjects(2, handles, FALSE, 1)); 163610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_EQ(WAIT_OBJECT_0 + 1, ::WaitForMultipleObjects(2, handles, FALSE, INFINITE)); 164610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_EQ(var2, 42); 165610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_EQ(WAIT_OBJECT_0, ::WaitForMultipleObjects(1, handles, FALSE, INFINITE)); 166610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_EQ(var1, 42); 167610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CloseHandle(t1); 168610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CloseHandle(t2); 169610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 170610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 171610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace RegisterWaitForSingleObjectTest { // {{{1 172610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovStealthNotification *n = NULL; 173610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovHANDLE monitored_object = NULL; 174610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 175610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid SignalStealthNotification() { 176610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n->wait(); 177610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov SetEvent(monitored_object); 178610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 179610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 180610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid foo() { } 181610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 182610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid CALLBACK DoneWaiting(void *param, BOOLEAN timed_out) { 183610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int *i = (int*)param; 184610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov foo(); // make sure this function has a call. See issue 24. 185610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (*i)++; 186610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 187610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 188610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, WindowsRegisterWaitForSingleObjectTest) { // {{{1 189610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // These are very tricky false positive found while testing Chromium. 190610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // 191610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // Report #1: 192610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // Everything after UnregisterWaitEx(*, INVALID_HANDLE_VALUE) happens-after 193610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // execution of DoneWaiting callback. Currently, we don't catch this h-b. 194610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // 195610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // Report #2: 196610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // The callback thread is re-used between Registet/Unregister/Register calls 197610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // so we miss h-b between "int *obj = ..." and DoneWaiting on the second 198610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // iteration. 199610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov for (int i = 0; i < 2; i++) { 200610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n = new StealthNotification(); 201610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int *obj = new int(0); 202610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov HANDLE wait_object = NULL; 203610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 204610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov monitored_object = ::CreateEvent(NULL, false, false, NULL); 205610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("monitored_object = %p\n", monitored_object); 206610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThread mt(SignalStealthNotification); 207610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mt.Start(); 208610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_TRACE_MEMORY(obj); 209610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(0 != ::RegisterWaitForSingleObject(&wait_object, monitored_object, 210610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov DoneWaiting, obj, INFINITE, 211610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)); 212610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("wait_object = %p\n", wait_object); 213610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n->signal(); 214610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mt.Join(); 215610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov Sleep(1000); 216610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(0 != ::UnregisterWaitEx(wait_object, INVALID_HANDLE_VALUE)); 217610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (*obj)++; 218610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(*obj == 2); 219610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CloseHandle(monitored_object); 220610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov delete n; 221610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov delete obj; 222610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 223610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 224610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 225610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 226610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace QueueUserWorkItemTests { 227610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovDWORD CALLBACK Callback(void *param) { 228610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int *ptr = (int*)param; 229610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (*ptr)++; 230610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov delete ptr; 231610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov return 0; 232610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 233610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 234610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, WindowsQueueUserWorkItemTest) { 235610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // False positive: 236610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // The callback thread is allocated from a thread pool and can be re-used. 237610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // As a result, we may miss h-b between "int *obj = ..." and Callback execution. 238610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov for (int i = 0; i < 5; i++) { 239610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int *obj = new int(0); 240610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_TRACE_MEMORY(obj); 241610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(QueueUserWorkItem(Callback, obj, i % 2 ? WT_EXECUTELONGFUNCTION : 0)); 242610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov Sleep(500); 243610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 244610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 245610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 246610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint GLOB = 42; 247610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 248610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovDWORD CALLBACK Callback2(void *param) { 249610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov StealthNotification *ptr = (StealthNotification*)param; 250610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB++; 251610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov Sleep(100); 252610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ptr->signal(); 253610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov return 0; 254610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 255610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 256610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(PositiveTests, WindowsQueueUserWorkItemTest) { 257610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "PositiveTests.WindowsQueueUserWorkItemTest"); 258610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 259610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov const int N_THREAD = 5; 260610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov StealthNotification n[N_THREAD]; 261610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 262610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov for (int i = 0; i < N_THREAD; i++) 263610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(QueueUserWorkItem(Callback2, &n[i], i % 2 ? WT_EXECUTELONGFUNCTION : 0)); 264610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 265610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov for (int i = 0; i < N_THREAD; i++) 266610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n[i].wait(); 267610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 268610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 269610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 270610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace WindowsCriticalSectionTest { // {{{1 271610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovCRITICAL_SECTION cs; 272610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 273610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, WindowsCriticalSectionTest) { 274610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov InitializeCriticalSection(&cs); 275610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EnterCriticalSection(&cs); 276610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov TryEnterCriticalSection(&cs); 277610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov LeaveCriticalSection(&cs); 278610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov DeleteCriticalSection(&cs); 279610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 280610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace 281610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 282610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 283610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace WindowsSRWLockTest { // {{{1 284610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#if WINVER >= 0x0600 // Vista or Windows Server 2000 285610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovSRWLOCK SRWLock; 286610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint *obj; 287610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 288610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Reader() { 289610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov AcquireSRWLockShared(&SRWLock); 290610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(*obj <= 2 && *obj >= 0); 291610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ReleaseSRWLockShared(&SRWLock); 292610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 293610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 294610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Writer() { 295610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov AcquireSRWLockExclusive(&SRWLock); 296610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (*obj)++; 297610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ReleaseSRWLockExclusive(&SRWLock); 298610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 299610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 300610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#if 0 // This doesn't work in older versions of Windows. 301610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid TryReader() { 302610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov if (TryAcquireSRWLockShared(&SRWLock)) { 303610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(*obj <= 2 && *obj >= 0); 304610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ReleaseSRWLockShared(&SRWLock); 305610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 306610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 307610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 308610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid TryWriter() { 309610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov if (TryAcquireSRWLockExclusive(&SRWLock)) { 310610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (*obj)++; 311610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ReleaseSRWLockExclusive(&SRWLock); 312610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 313610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 314610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#endif 315610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 316610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, WindowsSRWLockTest) { 317610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov InitializeSRWLock(&SRWLock); 318610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov obj = new int(0); 319610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_TRACE_MEMORY(obj); 320610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(Reader, Writer, Reader, Writer); 321610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 322610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 323610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov AcquireSRWLockShared(&SRWLock); 324610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ReleaseSRWLockShared(&SRWLock); 325610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(*obj == 2); 326610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov delete obj; 327610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 328610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 329610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, WindowsSRWLockHackyInitializationTest) { 330610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // A similar pattern has been found on Chromium media_unittests 331610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov InitializeSRWLock(&SRWLock); 332610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov AcquireSRWLockExclusive(&SRWLock); 333610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // Leave the lock acquired 334610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 335610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // Reset the lock 336610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov InitializeSRWLock(&SRWLock); 337610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov obj = new int(0); 338610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(Reader, Writer, Reader, Writer); 339610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 340610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 341610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov delete obj; 342610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 343610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#endif // WINVER >= 0x0600 344610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace 345610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 346610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace WindowsConditionVariableSRWTest { // {{{1 347610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#if WINVER >= 0x0600 // Vista or Windows Server 2000 348610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovSRWLOCK SRWLock; 349610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovCONDITION_VARIABLE cv; 350610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovbool cond; 351610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint *obj; 352610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 353610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovStealthNotification n; 354610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 355610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid WaiterSRW() { 356610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov *obj = 1; 357610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n.wait(); 358610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov AcquireSRWLockExclusive(&SRWLock); 359610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov cond = true; 360610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov WakeConditionVariable(&cv); 361610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ReleaseSRWLockExclusive(&SRWLock); 362610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 363610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 364610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid WakerSRW() { 365610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov AcquireSRWLockExclusive(&SRWLock); 366610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n.signal(); 367610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov while (!cond) { 368610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov SleepConditionVariableSRW(&cv, &SRWLock, 10, 0); 369610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 370610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ReleaseSRWLockExclusive(&SRWLock); 371610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(*obj == 1); 372610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov *obj = 2; 373610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 374610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 375610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, WindowsConditionVariableSRWTest) { 376610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov InitializeSRWLock(&SRWLock); 377610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov InitializeConditionVariable(&cv); 378610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov obj = new int(0); 379610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov cond = false; 380610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_TRACE_MEMORY(obj); 381610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(WaiterSRW, WakerSRW); 382610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 383610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 384610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(*obj == 2); 385610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov delete obj; 386610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 387610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#endif // WINVER >= 0x0600 388610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace 389610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 390610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 391610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace WindowsInterlockedListTest { // {{{1 392610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovSLIST_HEADER list; 393610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 394610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovstruct Item { 395610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov SLIST_ENTRY entry; 396610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int foo; 397610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov}; 398610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 399610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Push() { 400610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov Item *item = new Item; 401610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov item->foo = 42; 402610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov InterlockedPushEntrySList(&list, (PSINGLE_LIST_ENTRY)item); 403610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 404610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 405610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Pop() { 406610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov Item *item; 407610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov while (0 == (item = (Item*)InterlockedPopEntrySList(&list))) { 408610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov Sleep(1); 409610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 410610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(item->foo == 42); 411610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov delete item; 412610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 413610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 414610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, WindowsInterlockedListTest) { 415610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov InitializeSListHead(&list); 416610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(Push, Pop); 417610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 418610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 419610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 420610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 421610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace 422610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 423610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace FileSystemReports { // {{{1 424610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 425610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// This is a test for the flaky report found in 426610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// Chromium net_unittests. 427610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// 428610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// Looks like the test is sensitive to memory allocations / scheduling order, 429610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// so you shouldn't run other tests while investigating the issue. 430610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// The report is ~50% flaky. 431610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 432610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovHANDLE hDone = NULL; 433610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 434610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid CreateFileJob() { 435610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov HANDLE hFile = CreateFileA("ZZZ\\tmpfile", GENERIC_READ | GENERIC_WRITE, 436610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov FILE_SHARE_READ, NULL, CREATE_ALWAYS, 437610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov FILE_ATTRIBUTE_NORMAL, NULL); 438610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CloseHandle(hFile); 439610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov DWORD attr1 = GetFileAttributes("ZZZ"); // "Concurrent write" is here. 440610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 441610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 442610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovDWORD CALLBACK PrintDirectoryListingJob(void *param) { 443610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov Sleep(500); 444610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov WIN32_FIND_DATAA data; 445610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 446610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // "Current write" is here. 447610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov HANDLE hFind = FindFirstFileA("ZZZ/*", &data); 448610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(hFind != INVALID_HANDLE_VALUE); 449610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 450610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CloseHandle(hFind); 451610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov SetEvent(hDone); 452610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov return 0; 453610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 454610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 455610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// This test is not very friendly to bots environment, so you should only 456610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// run it manually. 457610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, DISABLED_CreateFileVsFindFirstFileTest) { 458610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov hDone = ::CreateEvent(NULL, false, false, NULL); 459610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 460610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ::CreateDirectory("ZZZ", NULL); 461610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 462610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // Run PrintDirectoryListingJob in a concurrent thread. 463610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(::QueueUserWorkItem(PrintDirectoryListingJob, NULL, 464610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov WT_EXECUTELONGFUNCTION)); 465610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CreateFileJob(); 466610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 467610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ::WaitForSingleObject(hDone, INFINITE); 468610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ::CloseHandle(hDone); 469610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(::DeleteFile("ZZZ\\tmpfile")); 470610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(::RemoveDirectory("ZZZ")); 471610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 472610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 473610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} //namespace 474610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 475610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace WindowsAtomicsTests { // {{{1 476610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// This test should not give us any reports if compiled with proper MSVS flags. 477610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// The Atomic_{Read,Write} functions are ignored in racecheck_unittest.ignore 478610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 479610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint GLOB = 42; 480610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 481610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovinline int Atomic_Read(volatile const int* ptr) { 482610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // MSVS volatile gives us atomicity. 483610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int value = *ptr; 484610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov return value; 485610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 486610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 487610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovinline void Atomic_Write(volatile int* ptr, int value) { 488610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // MSVS volatile gives us atomicity. 489610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov *ptr = value; 490610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 491610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 492610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Worker() { 493610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int value = Atomic_Read(&GLOB); 494610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov Atomic_Write(&GLOB, ~value); 495610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 496610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 497610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, WindowsAtomicsTests) { 498610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray mta(Worker, Worker); 499610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mta.Start(); 500610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mta.Join(); 501610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 502610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 503610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace 504610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 505610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace WindowsSemaphoreTests { 506610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Poster(int *var, HANDLE sem) { 507610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov *var = 1; 508610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ReleaseSemaphore(sem, 1, NULL); 509610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 510610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 511610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Waiter(int *var, HANDLE sem) { 512610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov DWORD ret = ::WaitForSingleObject(sem, INFINITE); 513610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ASSERT_EQ(ret, WAIT_OBJECT_0); 514610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_EQ(*var, 1); 515610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 516610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 517610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, SimpleSemaphoreTest) { 518610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov HANDLE sem = CreateSemaphore(NULL, 519610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 0 /* initial count */, 520610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 20 /* max count */, 521610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov NULL); 522610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ASSERT_TRUE(sem != NULL); 523610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 524610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov { 525610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int VAR = 0; 526610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ThreadPool tp(2); 527610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov tp.StartWorkers(); 528610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov tp.Add(NewCallback(Waiter, &VAR, sem)); 529610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov tp.Add(NewCallback(Poster, &VAR, sem)); 530610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 531610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 532610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CloseHandle(sem); 533610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 534610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 535610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, DISABLED_SemaphoreNameReuseTest) { 536610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // TODO(timurrrr): Semaphore reuse is not yet understood by TSan. 537610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov const char NAME[] = "SemaphoreZZZ"; 538610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov HANDLE h1 = CreateSemaphore(NULL, 0, 10, NAME), 539610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov h2 = CreateSemaphore(NULL, 0, 15, NAME); 540610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ASSERT_TRUE(h1 != NULL); 541610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ASSERT_TRUE(h2 != NULL); 542610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 543610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // h1 and h2 refer to the same semaphore but are not equal. 544610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_NE(h1, h2); 545610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 546610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov { 547610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int VAR = 0; 548610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ThreadPool tp(2); 549610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov tp.StartWorkers(); 550610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov tp.Add(NewCallback(Waiter, &VAR, h1)); 551610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov tp.Add(NewCallback(Poster, &VAR, h2)); 552610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 553610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 554610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CloseHandle(h1); 555610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CloseHandle(h2); 556610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 557610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 558610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 559610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 560610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace HandleReuseTests { 561610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 562610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Waker(int *var, HANDLE h) { 563610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov *var = 1; 564610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov SetEvent(h); 565610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 566610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 567610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Waiter(int *var, HANDLE h) { 568610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov DWORD ret = ::WaitForSingleObject(h, INFINITE); 569610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ASSERT_EQ(ret, WAIT_OBJECT_0); 570610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_EQ(*var, 1); 571610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 572610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 573610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, DISABLED_EventHandleReuseTest) { 574610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // TODO(timurrrr): DuplicateHandle is not yet understood by TSan. 575610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov HANDLE h1 = CreateEvent(NULL, false, false, NULL); 576610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ASSERT_TRUE(h1 != NULL); 577610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov HANDLE h2 = NULL; 578610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov DuplicateHandle(GetCurrentProcess(), h1, 579610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GetCurrentProcess(), &h2, 580610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 0 /* access */, FALSE /* inherit*/, DUPLICATE_SAME_ACCESS); 581610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ASSERT_TRUE(h2 != NULL); 582610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 583610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // h1 and h2 refer to the same Event but are not equal. 584610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EXPECT_NE(h1, h2); 585610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 586610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov { 587610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int VAR = 0; 588610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ThreadPool tp(2); 589610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov tp.StartWorkers(); 590610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov tp.Add(NewCallback(Waiter, &VAR, h1)); 591610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov tp.Add(NewCallback(Waker, &VAR, h2)); 592610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 593610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 594610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CloseHandle(h1); 595610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CloseHandle(h2); 596610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 597610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 598610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 599610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// End {{{1 600610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // vim:shiftwidth=2:softtabstop=2:expandtab:foldmethod=marker 601