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: Konstantin Serebryany <opensource@google.com> 27610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 28610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov This file contains a set of unit tests for a data race detection tool. 29610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 30610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov These tests can be compiled with pthreads (default) or 31610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov with any other library that supports threads, locks, cond vars, etc. 32610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 33610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov*/ 34610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#ifdef WIN32 35610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#error "Don't build this file on Windows!" 36610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#endif 37610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 38610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#include <fcntl.h> 39610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#include <fenv.h> 40610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#include <queue> 41610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#include <signal.h> 42610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#include <stdlib.h> 43610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#include <string> 44610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#include <vector> 45610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#include <unistd.h> 46610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 47610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#ifdef OS_linux 48610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov# include <sys/epoll.h> 49610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#endif // OS_linux 50610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 51610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#include "test_utils.h" 52610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#include <gtest/gtest.h> 53610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#include "gtest_fixture_injection.h" 54610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 55610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovstatic CondVar CV; 56610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovstatic int COND = 0; 57610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 58610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// test11: FP. Synchronization via CondVar, 2 workers. {{{1 59610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// This test is properly synchronized, but currently (Dec 2007) 60610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// helgrind reports a false positive. 61610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// 62610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// Parent: Worker1, Worker2: 63610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// 1. Start(workers) a. read(GLOB) 64610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// 2. MU.Lock() b. MU.Lock() 65610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// 3. while(COND != 2) /-------- c. CV.Signal() 66610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// CV.Wait(&MU) <-------/ d. MU.Unlock() 67610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// 4. MU.Unlock() 68610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// 5. write(GLOB) 69610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// 70610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace test11 { 71610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint GLOB = 0; 72610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovMutex MU; 73610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Worker() { 74610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov usleep(200000); 75610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(GLOB != 777); 76610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 77610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MU.Lock(); 78610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov COND++; 79610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CV.Signal(); 80610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MU.Unlock(); 81610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 82610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 83610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Parent() { 84610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov COND = 0; 85610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 86610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(Worker, Worker); 87610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 88610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 89610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MU.Lock(); 90610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov while(COND != 2) { 91610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CV.Wait(&MU); 92610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 93610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MU.Unlock(); 94610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 95610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB = 2; 96610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 97610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 98610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 99610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 100610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, test11) { 101610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// ANNOTATE_EXPECT_RACE(&GLOB, "test11. FP. Fixed by MSMProp1."); 102610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("test11: negative\n"); 103610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov Parent(); 104610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("\tGLOB=%d\n", GLOB); 105610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 106610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace test11 107610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 108610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 109610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// test75: TN. Test for sem_post, sem_wait, sem_trywait. {{{1 110610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace test75 { 111610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint GLOB = 0; 112610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovsem_t sem[2]; 113610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 114610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Poster() { 115610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB = 1; 116610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sem_post(&sem[0]); 117610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sem_post(&sem[1]); 118610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 119610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 120610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Waiter() { 121610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sem_wait(&sem[0]); 122610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(GLOB==1); 123610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 124610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid TryWaiter() { 125610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov usleep(500000); 126610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sem_trywait(&sem[1]); 127610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(GLOB==1); 128610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 129610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 130610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, test75) { 131610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#ifndef NO_UNNAMED_SEM 132610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sem_init(&sem[0], 0, 0); 133610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sem_init(&sem[1], 0, 0); 134610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 135610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("test75: negative\n"); 136610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov { 137610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(Poster, Waiter); 138610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 139610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 140610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 141610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB = 2; 142610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov { 143610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(Poster, TryWaiter); 144610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 145610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 146610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 147610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("\tGLOB=%d\n", GLOB); 148610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 149610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sem_destroy(&sem[0]); 150610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sem_destroy(&sem[1]); 151610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#endif // NO_UNNAMED_SEM 152610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 153610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace test75 154610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 155610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 156610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// test98: Synchronization via read/write (or send/recv). {{{1 157610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace test98 { 158610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// The synchronization here is done by a pair of read/write calls 159610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// that create a happens-before arc. Same may be done with send/recv. 160610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// Such synchronization is quite unusual in real programs 161610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// (why would one synchronizae via a file or socket?), but 162610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// quite possible in unittests where one threads runs for producer 163610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// and one for consumer. 164610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// 165610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// A race detector has to create a happens-before arcs for 166610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// {read,send}->{write,recv} even if the file descriptors are different. 167610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// 168610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint GLOB = 0; 169610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint fd_out = -1; 170610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint fd_in = -1; 171610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 172610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Writer() { 173610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov usleep(1000); 174610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB = 1; 175610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov const char *str = "Hey there!\n"; 176610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov const int size = strlen(str) + 1; 177610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(size == write(fd_out, str, size)); 178610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 179610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 180610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Reader() { 181610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov char buff[100]; 182610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov while (read(fd_in, buff, 100) == 0) 183610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sleep(1); 184610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("read: %s\n", buff); 185610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB = 2; 186610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 187610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 188610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#ifndef __APPLE__ 189610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// Tsan for Mac OS is missing the unlink() syscall handler. 190610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// TODO(glider): add the syscall handler to Valgrind. 191610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, test98) { 192610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("test98: negative, synchronization via I/O\n"); 193610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov char in_name[100]; 194610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov char out_name[100]; 195610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // we open two files, on for reading and one for writing, 196610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // but the files are actually the same (symlinked). 197610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sprintf(in_name, "/tmp/racecheck_unittest_in.%d", getpid()); 198610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sprintf(out_name, "/tmp/racecheck_unittest_out.%d", getpid()); 199610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov fd_out = creat(out_name, O_WRONLY | S_IRWXU); 200610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(0 == symlink(out_name, in_name)); 201610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov fd_in = open(in_name, 0, O_RDONLY); 202610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(fd_out >= 0); 203610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(fd_in >= 0); 204610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(Writer, Reader); 205610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 206610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 207610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("\tGLOB=%d\n", GLOB); 208610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // cleanup 209610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov close(fd_in); 210610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov close(fd_out); 211610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov unlink(in_name); 212610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov unlink(out_name); 213610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 214610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#endif // __APPLE__ 215610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace test98 216610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 217610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 218610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace NegativeTests_PthreadOnce { // {{{1 219610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint *GLOB = NULL; 220610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovstatic pthread_once_t once = PTHREAD_ONCE_INIT; 221610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Init() { 222610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB = new int; 223610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_TRACE_MEMORY(GLOB); 224610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov *GLOB = 777; 225610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 226610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 227610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Worker0() { 228610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_once(&once, Init); 229610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 230610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Worker1() { 231610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov usleep(100000); 232610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_once(&once, Init); 233610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(*GLOB == 777); 234610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 235610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 236610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 237610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, PthreadOnceTest) { 238610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(Worker0, Worker1, Worker1, Worker1); 239610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 240610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 241610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("\tGLOB=%d\n", *GLOB); 242610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 243610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace 244610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 245610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 246610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// test110: TP. Simple races with stack, global and heap objects. {{{1 247610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace test110 { 248610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint GLOB = 0; 249610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovstatic int STATIC; 250610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 251610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovchar *STACK = 0; 252610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 253610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint *MALLOC; 254610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint *CALLOC; 255610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint *REALLOC; 256610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint *VALLOC; 257610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint *PVALLOC; 258610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint *MEMALIGN; 259610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint *POSIX_MEMALIGN; 260610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint *MMAP; 261610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 262610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint *NEW; 263610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint *NEW_ARR; 264610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 265610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Worker() { 266610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB++; 267610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov STATIC++; 268610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 269610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (*STACK)++; 270610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 271610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (*MALLOC)++; 272610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (*CALLOC)++; 273610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (*REALLOC)++; 274610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (*VALLOC)++; 275610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (*PVALLOC)++; 276610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (*MEMALIGN)++; 277610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (*POSIX_MEMALIGN)++; 278610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (*MMAP)++; 279610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 280610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (*NEW)++; 281610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (*NEW_ARR)++; 282610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 283610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(PositiveTests, test110) { 284610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("test110: positive (race on a stack object)\n"); 285610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 286610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov char x = 0; 287610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov STACK = &x; 288610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 289610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MALLOC = (int*)malloc(sizeof(int)); 290610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CALLOC = (int*)calloc(1, sizeof(int)); 291610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov REALLOC = (int*)realloc(NULL, sizeof(int)); 292610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov VALLOC = (int*)valloc(sizeof(int)); 293610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov PVALLOC = (int*)valloc(sizeof(int)); // TODO: pvalloc breaks helgrind. 294610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MEMALIGN = (int*)memalign(64, sizeof(int)); 295610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(0 == posix_memalign((void**)&POSIX_MEMALIGN, 64, sizeof(int))); 296610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MMAP = (int*)mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, 297610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MAP_PRIVATE | MAP_ANON, -1, 0); 298610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 299610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov NEW = new int; 300610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov NEW_ARR = new int[10]; 301610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 302610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 303610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE(STACK, "real race on stack object"); 304610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE(&GLOB, "real race on global object"); 305610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE(&STATIC, "real race on a static global object"); 306610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE(MALLOC, "real race on a malloc-ed object"); 307610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE(CALLOC, "real race on a calloc-ed object"); 308610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE(REALLOC, "real race on a realloc-ed object"); 309610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE(VALLOC, "real race on a valloc-ed object"); 310610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE(PVALLOC, "real race on a pvalloc-ed object"); 311610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE(MEMALIGN, "real race on a memalign-ed object"); 312610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE(POSIX_MEMALIGN, "real race on a posix_memalign-ed object"); 313610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE(MMAP, "real race on a mmap-ed object"); 314610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 315610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE(NEW, "real race on a new-ed object"); 316610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE(NEW_ARR, "real race on a new[]-ed object"); 317610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 318610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(Worker, Worker, Worker); 319610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 320610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 321610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("\tSTACK=%d\n", *STACK); 322610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(GLOB <= 3); 323610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(STATIC <= 3); 324610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 325610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov free(MALLOC); 326610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov free(CALLOC); 327610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov free(REALLOC); 328610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov free(VALLOC); 329610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov free(PVALLOC); 330610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov free(MEMALIGN); 331610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov free(POSIX_MEMALIGN); 332610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov munmap(MMAP, sizeof(int)); 333610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov delete NEW; 334610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov delete [] NEW_ARR; 335610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 336610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace test110 337610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 338610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 339610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// test115: TN. sem_open. {{{1 340610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace test115 { 341610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint tid = 0; 342610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovMutex mu; 343610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovconst char *kSemName = "drt-test-sem"; 344610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 345610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint GLOB = 0; 346610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 347610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovsem_t *DoSemOpen() { 348610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // TODO: there is some race report inside sem_open 349610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // for which suppressions do not work... (???) 350610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_IGNORE_WRITES_BEGIN(); 351610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sem_t *sem = sem_open(kSemName, O_CREAT, 0600, 3); 352610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_IGNORE_WRITES_END(); 353610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov return sem; 354610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 355610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 356610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Worker() { 357610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mu.Lock(); 358610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int my_tid = tid++; 359610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mu.Unlock(); 360610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 361610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov if (my_tid == 0) { 362610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB = 1; 363610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 364610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 365610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // if the detector observes a happens-before arc between 366610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // sem_open and sem_wait, it will be silent. 367610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sem_t *sem = DoSemOpen(); 368610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov usleep(100000); 369610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(sem != SEM_FAILED); 370610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(sem_wait(sem) == 0); 371610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 372610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov if (my_tid > 0) { 373610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(GLOB == 1); 374610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 375610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 376610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 377610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#ifndef __APPLE__ 378610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov/* This test is disabled for Darwin because of the tricky implementation of 379610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov * sem_open on that platform: subsequent attempts to open an existing semafore 380610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov * create new ones. */ 381610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, test115) { 382610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("test115: stab (sem_open())\n"); 383610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 384610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // just check that sem_open is not completely broken 385610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sem_unlink(kSemName); 386610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sem_t* sem = DoSemOpen(); 387610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(sem != SEM_FAILED); 388610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(sem_wait(sem) == 0); 389610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sem_unlink(kSemName); 390610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 391610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // check that sem_open and sem_wait create a happens-before arc. 392610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(Worker, Worker, Worker); 393610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 394610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 395610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // clean up 396610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sem_unlink(kSemName); 397610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 398610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#endif // __APPLE__ 399610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace test115 400610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 401610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 402610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// test122 TP: Simple test with RWLock {{{1 403610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace test122 { 404610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint VAR1 = 0; 405610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint VAR2 = 0; 406610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovRWLock mu; 407610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 408610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid WriteWhileHoldingReaderLock(int *p) { 409610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov usleep(100000); 410610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ReaderLockScoped lock(&mu); // Reader lock for writing. -- bug. 411610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (*p)++; 412610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 413610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 414610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid CorrectWrite(int *p) { 415610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov WriterLockScoped lock(&mu); 416610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (*p)++; 417610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 418610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 419610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Thread1() { WriteWhileHoldingReaderLock(&VAR1); } 420610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Thread2() { CorrectWrite(&VAR1); } 421610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Thread3() { CorrectWrite(&VAR2); } 422610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Thread4() { WriteWhileHoldingReaderLock(&VAR2); } 423610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 424610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 425610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(PositiveTests, test122) { 426610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("test122: positive (rw-lock)\n"); 427610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov VAR1 = 0; 428610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov VAR2 = 0; 429610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_TRACE_MEMORY(&VAR1); 430610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_TRACE_MEMORY(&VAR2); 431610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov if (!Tsan_PureHappensBefore()) { 432610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE_FOR_TSAN(&VAR1, "test122. TP. ReaderLock-ed while writing"); 433610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE_FOR_TSAN(&VAR2, "test122. TP. ReaderLock-ed while writing"); 434610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 435610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(Thread1, Thread2, Thread3, Thread4); 436610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 437610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 438610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 439610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace test122 440610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 441610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 442610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// test125 TN: Backwards lock (annotated). {{{1 443610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace test125 { 444610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// This test uses "Backwards mutex" locking protocol. 445610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// We take a *reader* lock when writing to a per-thread data 446610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// (GLOB[thread_num]) and we take a *writer* lock when we 447610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// are reading from the entire array at once. 448610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// 449610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// Such locking protocol is not understood by ThreadSanitizer's 450610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// hybrid state machine. So, you either have to use a pure-happens-before 451610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// detector ("tsan --pure-happens-before") or apply pure happens-before mode 452610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// to this particular lock by using ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&mu). 453610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 454610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovconst int n_threads = 3; 455610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovRWLock mu; 456610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint GLOB[n_threads]; 457610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 458610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint adder_num; // updated atomically. 459610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 460610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Adder() { 461610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int my_num = AtomicIncrement(&adder_num, 1) - 1; 462610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(my_num >= 0); 463610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(my_num < n_threads); 464610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 465610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ReaderLockScoped lock(&mu); 466610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB[my_num]++; 467610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 468610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 469610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Aggregator() { 470610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int sum = 0; 471610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov { 472610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov WriterLockScoped lock(&mu); 473610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov for (int i = 0; i < n_threads; i++) { 474610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sum += GLOB[i]; 475610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 476610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 477610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("sum=%d\n", sum); 478610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 479610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 480610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, test125) { 481610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("test125: negative\n"); 482610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 483610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&mu); 484610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 485610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // run Adders, then Aggregator 486610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov adder_num = 0; 487610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov { 488610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(Adder, Adder, Adder, Aggregator); 489610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 490610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 491610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 492610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 493610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // Run Aggregator first. 494610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov adder_num = 0; 495610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov { 496610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(Aggregator, Adder, Adder, Adder); 497610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 498610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 499610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 500610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 501610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 502610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace test125 503610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 504610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 505610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace MmapTest { // {{{1 506610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 507610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovconst int kMmapSize = 65536; 508610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 509610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid SubWorker() { 510610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov for (int i = 0; i < 500; i++) { 511610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int *ptr = (int*)mmap(NULL, kMmapSize, PROT_READ | PROT_WRITE, 512610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MAP_PRIVATE | MAP_ANON, -1, 0); 513610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov *ptr = 42; 514610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov munmap(ptr, kMmapSize); 515610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 516610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 517610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 518610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Worker1() { 519610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(SubWorker, SubWorker, SubWorker, SubWorker); 520610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 521610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 522610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 523610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Worker() { 524610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(Worker1, Worker1, Worker1, Worker1); 525610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 526610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 527610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 528610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 529610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, MmapTest) { 530610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(Worker, Worker, Worker, Worker); 531610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 532610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 533610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 534610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace 535610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 536610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 537610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// A regression test for mmap/munmap handling in Pin. 538610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// If the tool misses munmap() calls it may report a false positive if two 539610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// threads map the same memory region. 540610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace MmapRegressionTest { // {{{1 541610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 542610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovconst int kMmapSize = 65536; 543610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovconst uintptr_t kStartAddress = 0x10000; 544610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 545610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovStealthNotification n1; 546610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 547610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Worker() { 548610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int *ptr = (int*)mmap((void*)kStartAddress, kMmapSize, 549610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov PROT_READ | PROT_WRITE, 550610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MAP_PRIVATE | MAP_ANON, -1, 0); 551610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov *ptr = 42; 552610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov munmap(ptr, kMmapSize); 553610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 554610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 555610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, MmapRegressionTest) { 556610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(Worker, Worker); 557610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 558610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 559610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 560610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 561610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace 562610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 563610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// test136. Unlock twice. {{{1 564610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace test136 { 565610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(LockTests, UnlockTwice) { 566610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_mutexattr_t attr; 567610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(0 == pthread_mutexattr_init(&attr)); 568610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(0 == pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK)); 569610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 570610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_mutex_t mu; 571610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(0 == pthread_mutex_init(&mu, &attr)); 572610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(0 == pthread_mutex_lock(&mu)); 573610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(0 == pthread_mutex_unlock(&mu)); 574610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int ret_unlock = pthread_mutex_unlock(&mu); // unlocking twice. 575610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int ret_destroy = pthread_mutex_destroy(&mu); 576610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf(" pthread_mutex_unlock returned %d\n", ret_unlock); 577610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf(" pthread_mutex_destroy returned %d\n", ret_destroy); 578610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 579610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace test136 580610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 581610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 582610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// test141 FP. unlink/fopen, rmdir/opendir. {{{1 583610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace test141 { 584610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint GLOB1 = 0, 585610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB2 = 0; 586610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovchar *dir_name = NULL, 587610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov *filename = NULL; 588610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 589610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Waker1() { 590610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov usleep(100000); 591610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB1 = 1; // Write 592610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // unlink deletes a file 'filename' 593610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // which exits spin-loop in Waiter1(). 594610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf(" Deleting file...\n"); 595610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(unlink(filename) == 0); 596610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 597610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 598610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Waiter1() { 599610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov FILE *tmp; 600610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov while ((tmp = fopen(filename, "r")) != NULL) { 601610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov fclose(tmp); 602610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov usleep(10000); 603610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 604610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf(" ...file has been deleted\n"); 605610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB1 = 2; // Write 606610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 607610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 608610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Waker2() { 609610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov usleep(100000); 610610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB2 = 1; // Write 611610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // rmdir deletes a directory 'dir_name' 612610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // which exit spin-loop in Waker(). 613610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf(" Deleting directory...\n"); 614610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(rmdir(dir_name) == 0); 615610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 616610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 617610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Waiter2() { 618610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov DIR *tmp; 619610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov while ((tmp = opendir(dir_name)) != NULL) { 620610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov closedir(tmp); 621610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov usleep(10000); 622610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 623610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf(" ...directory has been deleted\n"); 624610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB2 = 2; 625610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 626610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 627610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, test141) { 628610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("test141: FP. unlink/fopen, rmdir/opendir.\n"); 629610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 630610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov dir_name = strdup("/tmp/tsan-XXXXXX"); 631610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(mkdtemp(dir_name) != 0); 632610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 633610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov filename = strdup((std::string() + dir_name + "/XXXXXX").c_str()); 634610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov const int fd = mkstemp(filename); 635610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(fd >= 0); 636610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov close(fd); 637610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 638610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray mta1(Waker1, Waiter1); 639610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mta1.Start(); 640610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mta1.Join(); 641610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 642610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray mta2(Waker2, Waiter2); 643610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mta2.Start(); 644610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mta2.Join(); 645610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 646610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov free(filename); 647610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov filename = 0; 648610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov free(dir_name); 649610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov dir_name = 0; 650610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 651610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace test141 652610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 653610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 654610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// test146: TP. Unit test for RWLock::TryLock and RWLock::ReaderTryLock. {{{1 655610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace test146 { 656610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// Worker1 locks the globals for writing for a long time. 657610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// Worker2 tries to write to globals twice: without a writer lock and with it. 658610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// Worker3 tries to read from globals twice: without a reader lock and with it. 659610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint GLOB1 = 0; 660610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovchar padding1[64]; 661610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint GLOB2 = 0; 662610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovchar padding2[64]; 663610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint GLOB3 = 0; 664610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovchar padding3[64]; 665610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint GLOB4 = 0; 666610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovRWLock MU; 667610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovStealthNotification n1, n2, n3, n4, n5; 668610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 669610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Worker1() { 670610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MU.Lock(); 671610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB1 = 1; 672610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB2 = 1; 673610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB3 = 1; 674610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB4 = 1; 675610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n1.signal(); 676610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n2.wait(); 677610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n3.wait(); 678610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MU.Unlock(); 679610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n4.signal(); 680610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 681610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 682610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Worker2() { 683610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n1.wait(); 684610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov if (MU.TryLock()) CHECK(0); 685610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov else 686610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB1 = 2; 687610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n2.signal(); 688610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n5.wait(); 689610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov if (MU.TryLock()) { 690610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB2 = 2; 691610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MU.Unlock(); 692610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } else { 693610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(0); 694610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 695610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 696610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 697610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Worker3() { 698610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n1.wait(); 699610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov if (MU.ReaderTryLock()) CHECK(0); 700610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov else 701610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("\treading GLOB3: %d\n", GLOB3); 702610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n3.signal(); 703610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n4.wait(); 704610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov if (MU.ReaderTryLock()) { 705610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("\treading GLOB4: %d\n", GLOB4); 706610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MU.ReaderUnlock(); 707610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } else { 708610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(0); 709610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 710610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n5.signal(); 711610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 712610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 713610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(PositiveTests, test146) { 714610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB1, "test146. TP: a data race on GLOB1."); 715610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB3, "test146. TP: a data race on GLOB3."); 716610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_TRACE_MEMORY(&GLOB1); 717610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_TRACE_MEMORY(&GLOB2); 718610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_TRACE_MEMORY(&GLOB3); 719610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_TRACE_MEMORY(&GLOB4); 720610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("test146: positive\n"); 721610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(Worker1, Worker2, Worker3); 722610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 723610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 724610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("\tGLOB1=%d\n", GLOB1); 725610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("\tGLOB2=%d\n", GLOB2); 726610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("\tGLOB3=%d\n", GLOB3); 727610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("\tGLOB4=%d\n", GLOB4); 728610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 729610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace test146 730610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 731610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace PositiveTests_CyclicBarrierTest { // {{{1 732610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#ifndef NO_BARRIER 733610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// regression test for correct support of cyclic barrier. 734610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// This test was suggested by Julian Seward. 735610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// There is a race on L here between a1 and b1, 736610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// but a naive support of barrier makes us miss this race. 737610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovpthread_barrier_t B; 738610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint L; 739610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 740610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// A1/A2: write L, then wait for barrier, then sleep 741610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid a1() { 742610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov L = 1; 743610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_barrier_wait(&B); 744610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sleep(1); 745610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 746610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid a2() { 747610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_barrier_wait(&B); 748610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sleep(1); 749610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 750610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 751610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// B1/B2: sleep, wait for barrier, then write L 752610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid b1() { 753610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sleep(1); 754610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_barrier_wait(&B); 755610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov L = 1; 756610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 757610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid b2() { 758610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sleep(1); 759610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_barrier_wait(&B); 760610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 761610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 762610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(PositiveTests, CyclicBarrierTest) { 763610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE_FOR_TSAN(&L, "real race, may be hidden" 764610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov " by incorrect implementation of barrier"); 765610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_barrier_init(&B, NULL, 3); 766610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t1(a1, a2, a2), 767610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t2(b1, b2, b2); 768610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t1.Start(); 769610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t2.Start(); 770610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t1.Join(); 771610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t2.Join(); 772610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 773610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 774610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 775610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint *G = NULL; 776610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 777610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Worker() { 778610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_barrier_wait(&B); 779610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (*G) = 1; 780610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_barrier_wait(&B); 781610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 782610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 783610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(PositiveTests, CyclicBarrierTwoCallsTest) { 784610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_barrier_init(&B, NULL, 2); 785610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov G = new int(0); 786610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_TRACE_MEMORY(G); 787610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE_FOR_TSAN(G, "real race, may be hidden" 788610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov " by incorrect implementation of barrier"); 789610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t1(Worker, Worker); 790610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t1.Start(); 791610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t1.Join(); 792610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(*G == 1); 793610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov delete G; 794610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 795610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 796610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 797610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 798610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#endif // NO_BARRIER 799610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace 800610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 801610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, Mmap84GTest) { // {{{1 802610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#ifdef ARCH_amd64 803610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#ifdef OS_linux 804610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // test that we can mmap 84G and can do it fast. 805610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov size_t size = (1ULL << 32) * 21; // 21 * 4G 806610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov void *mem_ptr = mmap((void *) 0, 807610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov size, 808610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov PROT_EXEC | PROT_READ | PROT_WRITE, 809610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, 810610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov -1, 811610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov (off_t) 0); 812610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("res=%p\n", mem_ptr); 813610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#endif 814610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#endif 815610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 816610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 817610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace NegativeTests_PthreadCreateFailureTest { // {{{1 818610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#ifdef OS_linux 819610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid* ThreadRoutine(void *) { 820610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov return NULL; 821610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 822610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 823610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, PthreadCreateFailureTest) { 824610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_attr_t attributes; 825610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_attr_init(&attributes); 826610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_attr_setstacksize(&attributes, -1); 827610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_t handle; 828610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(pthread_create(&handle, &attributes, ThreadRoutine, NULL) != 0); 829610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_attr_destroy(&attributes); 830610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 831610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#endif // OS_linux 832610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace NegativeTests_PthreadCreateFailureTest 833610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 834610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace Signals { // {{{1 835610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 836610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovtypedef void (*Sigaction)(int, siginfo_t *, void *); 837610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 838610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint GLOB = 0; 839610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 840610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovstatic void EnableSigprof(Sigaction SignalHandler) { 841610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov struct sigaction sa; 842610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sa.sa_sigaction = SignalHandler; 843610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sa.sa_flags = SA_RESTART | SA_SIGINFO; 844610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sigemptyset(&sa.sa_mask); 845610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov if (sigaction(SIGPROF, &sa, NULL) != 0) { 846610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov perror("sigaction"); 847610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov abort(); 848610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 849610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov struct itimerval timer; 850610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov timer.it_interval.tv_sec = 0; 851610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov timer.it_interval.tv_usec = 1000000 / 10000; 852610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov timer.it_value = timer.it_interval; 853610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov if (setitimer(ITIMER_PROF, &timer, 0) != 0) { 854610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov perror("setitimer"); 855610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov abort(); 856610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 857610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 858610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 859610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovstatic void DisableSigprof() { 860610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // Disable the profiling timer. 861610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov struct itimerval timer; 862610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov timer.it_interval.tv_sec = 0; 863610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov timer.it_interval.tv_usec = 0; 864610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov timer.it_value = timer.it_interval; 865610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov if (setitimer(ITIMER_PROF, &timer, 0) != 0) { 866610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov perror("setitimer"); 867610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov abort(); 868610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 869610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // Ignore SIGPROFs from now on. 870610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov struct sigaction sa; 871610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sa.sa_handler = SIG_IGN; 872610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sa.sa_flags = SA_RESTART | SA_SIGINFO; 873610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sigemptyset(&sa.sa_mask); 874610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov if (sigaction(SIGPROF, &sa, NULL) != 0) { 875610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov perror("sigaction"); 876610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov abort(); 877610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 878610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 879610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 880610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid MallocTestWorker() { 881610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov for (int i = 0; i < 100000; i++) { 882610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov void *x = malloc((i % 64) + 1); 883610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov free (x); 884610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 885610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 886610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 887610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// Regression test for 888610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// http://code.google.com/p/data-race-test/issues/detail?id=13 . 889610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// Make sure that locking events are handled in signal handlers. 890610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// 891610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// For some reason, invoking the signal handlers causes deadlocks on Mac OS. 892610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#ifndef __APPLE__ 893610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovMutex mu; 894610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 895610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid SignalHandlerWithMutex(int, siginfo_t*, void*) { 896610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mu.Lock(); 897610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB++; 898610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mu.Unlock(); 899610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 900610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 901610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(Signals, SignalsAndMallocTestWithMutex) { 902610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EnableSigprof(SignalHandlerWithMutex); 903610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(MallocTestWorker, MallocTestWorker, MallocTestWorker); 904610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 905610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 906610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("\tGLOB=%d\n", GLOB); 907610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov DisableSigprof(); 908610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 909610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#endif 910610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 911610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// Another regression test for 912610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// http://code.google.com/p/data-race-test/issues/detail?id=13 . 913610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// Make sure that locking events are handled in signal handlers. 914610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovSpinLock sl; 915610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 916610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid SignalHandlerWithSpinlock(int, siginfo_t*, void*) { 917610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sl.Lock(); 918610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB++; 919610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov sl.Unlock(); 920610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 921610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 922610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(Signals, DISABLED_SignalsAndMallocTestWithSpinlock) { 923610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EnableSigprof(SignalHandlerWithSpinlock); 924610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(MallocTestWorker, MallocTestWorker, MallocTestWorker); 925610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 926610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 927610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("\tGLOB=%d\n", GLOB); 928610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov DisableSigprof(); 929610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 930610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 931610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// Regression test for 932610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// http://code.google.com/p/data-race-test/issues/detail?id=14. 933610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovstatic void WaitTestSignalHandler(int, siginfo_t*, void*) { 934610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_HAPPENS_AFTER((void*)0x1234); 935610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 936610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 937610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid WaitTestWorker() { 938610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov for (int i = 0; i < 1000000; i++) { 939610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_HAPPENS_AFTER((void*)0x1234); 940610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 941610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 942610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 943610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(Signals, SignalsAndWaitTest) { 944610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov EnableSigprof(WaitTestSignalHandler); 945610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(WaitTestWorker, WaitTestWorker, WaitTestWorker); 946610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 947610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 948610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov DisableSigprof(); 949610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 950610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 951610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#ifndef __APPLE__ 952610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// this test crashes on Mac in debug TSan build, see 953610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// http://code.google.com/p/data-race-test/issues/detail?id=47 954610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovpid_t child_pid = 0; 955610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 956610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid child_handler(int signum) { 957610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov if (signum == SIGCHLD && child_pid == 0) { 958610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov printf("Whoops, PID shouldn't be 0!\n"); 959610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 960610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 961610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 962610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(Signals, PositiveTests_RaceInSignal) { 963610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // Currently the data race on child_pid can't be found, 964610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // see http://code.google.com/p/data-race-test/issues/detail?id=46 965610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov //ANNOTATE_EXPECT_RACE(&child_pid, "Race on pid: fork vs signal handler"); 966610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov signal(SIGCHLD, child_handler); 967610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov child_pid = fork(); 968610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov if (child_pid == 0) { 969610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // in child 970610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov exit(0); 971610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 972610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov wait(NULL); 973610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 974610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#endif // __APPLE__ 975610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 976610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace; 977610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 978610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(WeirdSizesTests, FegetenvTest) { 979610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // http://code.google.com/p/data-race-test/issues/detail?id=36 980610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov fenv_t tmp; 981610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov if (fegetenv(&tmp) != 0) 982610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov FAIL() << "fegetenv failed"; 983610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 984610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 985610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace NegativeTests_epoll { // {{{1 986610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#ifdef OS_linux 987610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint GLOB; 988610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 989610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// Currently, ThreadSanitizer should create hb arcs between 990610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// epoll_ctl and epoll_wait regardless of the parameters. Check that. 991610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 992610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Worker1() { 993610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB++; 994610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov struct epoll_event event; 995610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov epoll_ctl(0, 0, 0, &event); 996610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 997610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Worker2() { 998610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov struct epoll_event event; 999610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov epoll_wait(0, &event, 0, 0); 1000610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB++; 1001610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 1002610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1003610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests,epollTest) { 1004610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray mta(Worker1, Worker2); 1005610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mta.Start(); 1006610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mta.Join(); 1007610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 1008610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#endif // OS_linux 1009610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 1010610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace NegativeTests_LockfTest { // {{{1 1011610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1012610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovclass ShmMutex { 1013610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov public: 1014610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ShmMutex() : fd_(-1) { } 1015610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov void set_fd(int fd) { 1016610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(fd_ == -1); 1017610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov fd_ = fd; 1018610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 1019610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov void Lock() { 1020610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov LockOrUnlockInternal(true); 1021610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 1022610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov void Unlock() { 1023610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov LockOrUnlockInternal(false); 1024610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 1025610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov private: 1026610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov void LockOrUnlockInternal(bool lock) { 1027610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(fd_ >= 0); 1028610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov while (lockf(fd_, lock ? F_LOCK : F_ULOCK, 0) < 0) { 1029610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov if (errno == EINTR) { 1030610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov continue; 1031610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } else if (errno == ENOLCK) { 1032610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov usleep(5000); 1033610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov continue; 1034610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 1035610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(0); 1036610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 1037610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1038610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 1039610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1040610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int fd_; 1041610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} mu; 1042610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1043610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint GLOB; 1044610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1045610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Worker() { 1046610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mu.Lock(); 1047610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB++; 1048610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mu.Unlock(); 1049610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 1050610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1051610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests,DISABLED_LockfTest) { 1052610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mu.set_fd(1 /* stdout */); 1053610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray mta(Worker, Worker); 1054610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mta.Start(); 1055610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mta.Join(); 1056610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 1057610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1058610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 1059610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace PositiveTests_LockThenNoLock { // {{{1 1060610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// Regression test for a bug fixed by r2312 1061610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint GLOB; 1062610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovpthread_mutex_t mu; 1063610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovStealthNotification n1, n2; 1064610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1065610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Worker1() { 1066610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_mutex_lock(&mu); 1067610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB = 1; 1068610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_mutex_unlock(&mu); 1069610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n1.signal(); 1070610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n2.wait(); 1071610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB = 2; 1072610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 1073610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1074610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Worker2() { 1075610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_mutex_lock(&mu); 1076610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB = 3; 1077610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_mutex_unlock(&mu); 1078610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n2.signal(); 1079610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n1.wait(); 1080610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB = 4; 1081610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 1082610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1083610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(PositiveTests, LockThenNoLock) { 1084610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_mutex_init(&mu, NULL); 1085610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_TRACE_MEMORY(&GLOB); 1086610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE(&GLOB, "race"); 1087610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_NOT_HAPPENS_BEFORE_MUTEX(&mu); 1088610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(Worker1, Worker2); 1089610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 1090610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 1091610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_mutex_destroy(&mu); 1092610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 1093610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace 1094610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1095610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#ifdef __APPLE__ 1096610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace NegativeTests_PthreadCondWaitRelativeNp { // {{{1 1097610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint GLOB = 0; 1098610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovpthread_mutex_t mu; 1099610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovpthread_cond_t cv; 1100610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1101610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Waiter() { 1102610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov struct timespec tv = {1000, 1000}; 1103610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_mutex_lock(&mu); 1104610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_cond_timedwait_relative_np(&cv, &mu, &tv); 1105610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB = 2; 1106610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_mutex_unlock(&mu); 1107610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 1108610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1109610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Waker() { 1110610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_mutex_lock(&mu); 1111610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB = 1; 1112610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_cond_signal(&cv); 1113610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_mutex_unlock(&mu); 1114610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 1115610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1116610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(NegativeTests, PthreadCondWaitRelativeNpTest) { 1117610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_mutex_init(&mu, NULL); 1118610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_cond_init(&cv, NULL); 1119610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(Waiter, Waker); 1120610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 1121610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 1122610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_mutex_destroy(&mu); 1123610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_cond_destroy(&cv); 1124610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 1125610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace 1126610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov#endif // __APPLE__ 1127610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1128610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace PositiveTests_RWLockVsRWLockTest { // {{{1 1129610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// Test that reader lock/unlock do not create a hb-arc. 1130610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovRWLock mu; 1131610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint GLOB; 1132610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovStealthNotification n; 1133610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1134610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Thread1() { 1135610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB = 1; 1136610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mu.ReaderLock(); 1137610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mu.ReaderUnlock(); 1138610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n.signal(); 1139610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 1140610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1141610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Thread2() { 1142610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov n.wait(); 1143610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mu.ReaderLock(); 1144610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov mu.ReaderUnlock(); 1145610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov GLOB = 1; 1146610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 1147610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1148610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(PositiveTests, RWLockVsRWLockTest) { 1149610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&mu); 1150610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov ANNOTATE_EXPECT_RACE(&GLOB, "rwunlock/rwlock is not a hb-arc"); 1151610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(Thread1, Thread2); 1152610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 1153610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 1154610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 1155610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1156610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} // namespace 1157610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1158610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovnamespace TSDTests { 1159610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// Test the support for libpthread TSD destructors. 1160610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovpthread_key_t key; 1161610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovconst int kInitialValue = 0xfeedface; 1162610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovint tsd_array[2]; 1163610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1164610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Destructor(void *ptr) { 1165610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int *write = (int*) ptr; 1166610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov *write = kInitialValue; 1167610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 1168610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1169610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid DoWork(int index) { 1170610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int *value = &(tsd_array[index]); 1171610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov *value = 42; 1172610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_setspecific(key, value); 1173610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov int *read = (int*) pthread_getspecific(key); 1174610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(read == value); 1175610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 1176610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1177610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Worker0() { DoWork(0); } 1178610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanovvoid Worker1() { DoWork(1); } 1179610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1180610969f87667a485b9207086b3ff475bab909f95Evgeniy StepanovTEST(TSDTests, TSDDestructorTest) { 1181610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov pthread_key_create(&key, Destructor); 1182610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov MyThreadArray t(Worker0, Worker1); 1183610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Start(); 1184610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov t.Join(); 1185610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov for (int i = 0; i < 2; ++i) { 1186610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov CHECK(tsd_array[i] == kInitialValue); 1187610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov } 1188610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 1189610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1190610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov} 1191610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov 1192610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov// End {{{1 1193610969f87667a485b9207086b3ff475bab909f95Evgeniy Stepanov // vim:shiftwidth=2:softtabstop=2:expandtab:foldmethod=marker 1194