1fce5bd4cc29fddb5e8f0cb9c12df7c10187a991dDmitry Vyukov 2603c4be006d8c53905d736bf1f19a49f5ce98276Alexey Samsonov//===-- tsan_test_util_linux.cc -------------------------------------------===// 3da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// 4da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// The LLVM Compiler Infrastructure 5da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// 6da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// This file is distributed under the University of Illinois Open Source 7da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// License. See LICENSE.TXT for details. 8da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// 9da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//===----------------------------------------------------------------------===// 10da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// 11da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// This file is a part of ThreadSanitizer (TSan), a race detector. 12da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// 13da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// Test utils, linux implementation. 14da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//===----------------------------------------------------------------------===// 15da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 16fce5bd4cc29fddb5e8f0cb9c12df7c10187a991dDmitry Vyukov#include "sanitizer_common/sanitizer_atomic.h" 17da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include "tsan_interface.h" 18da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include "tsan_test_util.h" 19da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include "tsan_report.h" 20da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 21da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include "gtest/gtest.h" 22da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 23da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include <assert.h> 24da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include <pthread.h> 25da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include <stdio.h> 26da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include <stdint.h> 27da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include <string.h> 28da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include <unistd.h> 29da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include <errno.h> 30da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 31da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyusing namespace __tsan; // NOLINT 32da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 33da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanystatic __thread bool expect_report; 34da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanystatic __thread bool expect_report_reported; 35da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanystatic __thread ReportType expect_report_type; 36da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 37d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukovextern "C" void *__interceptor_memcpy(void*, const void*, uptr); 38d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukovextern "C" void *__interceptor_memset(void*, int, uptr); 39d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov 40da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanystatic void *BeforeInitThread(void *param) { 41da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany (void)param; 42da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany return 0; 43da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 44da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 45da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanystatic void AtExit() { 46da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 47da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 48da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid TestMutexBeforeInit() { 49da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany // Mutexes must be usable before __tsan_init(); 50da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; 51da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany pthread_mutex_lock(&mtx); 52da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany pthread_mutex_unlock(&mtx); 53da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany pthread_mutex_destroy(&mtx); 54da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany pthread_t thr; 55da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany pthread_create(&thr, 0, BeforeInitThread, 0); 56da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany pthread_join(thr, 0); 57da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany atexit(AtExit); 58da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 59da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 60da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanynamespace __tsan { 61da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanybool OnReport(const ReportDesc *rep, bool suppressed) { 62da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany if (expect_report) { 63da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany if (rep->typ != expect_report_type) { 64da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany printf("Expected report of type %d, got type %d\n", 65da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany (int)expect_report_type, (int)rep->typ); 66da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany EXPECT_FALSE("Wrong report type"); 67da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany return false; 68da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } 69da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } else { 70da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany EXPECT_FALSE("Unexpected report"); 71da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany return false; 72da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } 73da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany expect_report_reported = true; 74da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany return true; 75da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 76da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 77da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 78da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanystatic void* allocate_addr(int size, int offset_from_aligned = 0) { 79da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany static uintptr_t foo; 80da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany static atomic_uintptr_t uniq = {(uintptr_t)&foo}; // Some real address. 81da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany const int kAlign = 16; 82da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK(offset_from_aligned < kAlign); 83da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany size = (size + 2 * kAlign) & ~(kAlign - 1); 84da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany uintptr_t addr = atomic_fetch_add(&uniq, size, memory_order_relaxed); 85da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany return (void*)(addr + offset_from_aligned); 86da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 87da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 88da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyMemLoc::MemLoc(int offset_from_aligned) 89da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany : loc_(allocate_addr(16, offset_from_aligned)) { 90da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 91da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 92da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyMemLoc::~MemLoc() { 93da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 94da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 95da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyMutex::Mutex(Type type) 96da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany : alive_() 97da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany , type_(type) { 98da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 99da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 100da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyMutex::~Mutex() { 101da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK(!alive_); 102da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 103da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 104da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid Mutex::Init() { 105da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK(!alive_); 106da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany alive_ = true; 107da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany if (type_ == Normal) 108da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK_EQ(pthread_mutex_init((pthread_mutex_t*)mtx_, 0), 0); 109da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany else if (type_ == Spin) 110da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK_EQ(pthread_spin_init((pthread_spinlock_t*)mtx_, 0), 0); 111da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany else if (type_ == RW) 112da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK_EQ(pthread_rwlock_init((pthread_rwlock_t*)mtx_, 0), 0); 113da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany else 114da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK(0); 115da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 116da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 117da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid Mutex::StaticInit() { 118da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK(!alive_); 119da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK(type_ == Normal); 120da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany alive_ = true; 121da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany pthread_mutex_t tmp = PTHREAD_MUTEX_INITIALIZER; 122da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany memcpy(mtx_, &tmp, sizeof(tmp)); 123da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 124da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 125da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid Mutex::Destroy() { 126da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK(alive_); 127da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany alive_ = false; 128da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany if (type_ == Normal) 129da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK_EQ(pthread_mutex_destroy((pthread_mutex_t*)mtx_), 0); 130da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany else if (type_ == Spin) 131da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK_EQ(pthread_spin_destroy((pthread_spinlock_t*)mtx_), 0); 132da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany else if (type_ == RW) 133da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK_EQ(pthread_rwlock_destroy((pthread_rwlock_t*)mtx_), 0); 134da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 135da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 136da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid Mutex::Lock() { 137da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK(alive_); 138da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany if (type_ == Normal) 139da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK_EQ(pthread_mutex_lock((pthread_mutex_t*)mtx_), 0); 140da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany else if (type_ == Spin) 141da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK_EQ(pthread_spin_lock((pthread_spinlock_t*)mtx_), 0); 142da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany else if (type_ == RW) 143da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK_EQ(pthread_rwlock_wrlock((pthread_rwlock_t*)mtx_), 0); 144da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 145da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 146da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanybool Mutex::TryLock() { 147da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK(alive_); 148da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany if (type_ == Normal) 149da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany return pthread_mutex_trylock((pthread_mutex_t*)mtx_) == 0; 150da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany else if (type_ == Spin) 151da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany return pthread_spin_trylock((pthread_spinlock_t*)mtx_) == 0; 152da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany else if (type_ == RW) 153da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany return pthread_rwlock_trywrlock((pthread_rwlock_t*)mtx_) == 0; 154da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany return false; 155da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 156da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 157da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid Mutex::Unlock() { 158da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK(alive_); 159da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany if (type_ == Normal) 160da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK_EQ(pthread_mutex_unlock((pthread_mutex_t*)mtx_), 0); 161da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany else if (type_ == Spin) 162da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK_EQ(pthread_spin_unlock((pthread_spinlock_t*)mtx_), 0); 163da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany else if (type_ == RW) 164da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK_EQ(pthread_rwlock_unlock((pthread_rwlock_t*)mtx_), 0); 165da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 166da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 167da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid Mutex::ReadLock() { 168da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK(alive_); 169da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK(type_ == RW); 170da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK_EQ(pthread_rwlock_rdlock((pthread_rwlock_t*)mtx_), 0); 171da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 172da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 173da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanybool Mutex::TryReadLock() { 174da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK(alive_); 175da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK(type_ == RW); 176da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany return pthread_rwlock_tryrdlock((pthread_rwlock_t*)mtx_) == 0; 177da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 178da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 179da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid Mutex::ReadUnlock() { 180da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK(alive_); 181da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK(type_ == RW); 182da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK_EQ(pthread_rwlock_unlock((pthread_rwlock_t*)mtx_), 0); 183da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 184da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 185da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanystruct Event { 186da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany enum Type { 187da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany SHUTDOWN, 188da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany READ, 189da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany WRITE, 190da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany VPTR_UPDATE, 191da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CALL, 192da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany RETURN, 193da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany MUTEX_CREATE, 194da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany MUTEX_DESTROY, 195da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany MUTEX_LOCK, 196da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany MUTEX_TRYLOCK, 197da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany MUTEX_UNLOCK, 198da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany MUTEX_READLOCK, 199da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany MUTEX_TRYREADLOCK, 200da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany MUTEX_READUNLOCK, 201da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany MEMCPY, 202da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany MEMSET 203da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany }; 204da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Type type; 205da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void *ptr; 206da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany uptr arg; 207da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany uptr arg2; 208da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany bool res; 209da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany bool expect_report; 210da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany ReportType report_type; 211da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 212da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Event(Type type, const void *ptr = 0, uptr arg = 0, uptr arg2 = 0) 213da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany : type(type) 214da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany , ptr(const_cast<void*>(ptr)) 215da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany , arg(arg) 216da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany , arg2(arg2) 217da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany , res() 218da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany , expect_report() 219da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany , report_type() { 220da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } 221da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 222da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void ExpectReport(ReportType type) { 223da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany expect_report = true; 224da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany report_type = type; 225da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } 226da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}; 227da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 228da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanystruct ScopedThread::Impl { 229da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany pthread_t thread; 230da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany bool main; 231da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany bool detached; 232da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany atomic_uintptr_t event; // Event* 233da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 234da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany static void *ScopedThreadCallback(void *arg); 235da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void send(Event *ev); 236da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void HandleEvent(Event *ev); 237da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}; 238da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 239da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid ScopedThread::Impl::HandleEvent(Event *ev) { 240da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK_EQ(expect_report, false); 241da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany expect_report = ev->expect_report; 242da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany expect_report_reported = false; 243da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany expect_report_type = ev->report_type; 244da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany switch (ev->type) { 245da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case Event::READ: 246da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case Event::WRITE: { 247da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void (*tsan_mop)(void *addr) = 0; 248da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany if (ev->type == Event::READ) { 249da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany switch (ev->arg /*size*/) { 250da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case 1: tsan_mop = __tsan_read1; break; 251da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case 2: tsan_mop = __tsan_read2; break; 252da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case 4: tsan_mop = __tsan_read4; break; 253da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case 8: tsan_mop = __tsan_read8; break; 254da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case 16: tsan_mop = __tsan_read16; break; 255da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } 256da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } else { 257da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany switch (ev->arg /*size*/) { 258da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case 1: tsan_mop = __tsan_write1; break; 259da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case 2: tsan_mop = __tsan_write2; break; 260da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case 4: tsan_mop = __tsan_write4; break; 261da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case 8: tsan_mop = __tsan_write8; break; 262da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case 16: tsan_mop = __tsan_write16; break; 263da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } 264da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } 265da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK_NE(tsan_mop, 0); 266da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany errno = ECHRNG; 267da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany tsan_mop(ev->ptr); 268da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK_EQ(errno, ECHRNG); // In no case must errno be changed. 269da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany break; 270da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } 271da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case Event::VPTR_UPDATE: 272da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany __tsan_vptr_update((void**)ev->ptr, (void*)ev->arg); 273da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany break; 274da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case Event::CALL: 275da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany __tsan_func_entry((void*)((uptr)ev->ptr)); 276da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany break; 277da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case Event::RETURN: 278da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany __tsan_func_exit(); 279da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany break; 280da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case Event::MUTEX_CREATE: 281da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany static_cast<Mutex*>(ev->ptr)->Init(); 282da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany break; 283da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case Event::MUTEX_DESTROY: 284da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany static_cast<Mutex*>(ev->ptr)->Destroy(); 285da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany break; 286da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case Event::MUTEX_LOCK: 287da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany static_cast<Mutex*>(ev->ptr)->Lock(); 288da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany break; 289da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case Event::MUTEX_TRYLOCK: 290da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany ev->res = static_cast<Mutex*>(ev->ptr)->TryLock(); 291da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany break; 292da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case Event::MUTEX_UNLOCK: 293da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany static_cast<Mutex*>(ev->ptr)->Unlock(); 294da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany break; 295da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case Event::MUTEX_READLOCK: 296da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany static_cast<Mutex*>(ev->ptr)->ReadLock(); 297da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany break; 298da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case Event::MUTEX_TRYREADLOCK: 299da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany ev->res = static_cast<Mutex*>(ev->ptr)->TryReadLock(); 300da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany break; 301da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case Event::MUTEX_READUNLOCK: 302da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany static_cast<Mutex*>(ev->ptr)->ReadUnlock(); 303da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany break; 304da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case Event::MEMCPY: 305d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov __interceptor_memcpy(ev->ptr, (void*)ev->arg, ev->arg2); 306da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany break; 307da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany case Event::MEMSET: 308d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov __interceptor_memset(ev->ptr, ev->arg, ev->arg2); 309da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany break; 310da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany default: CHECK(0); 311da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } 312da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany if (expect_report && !expect_report_reported) { 313da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany printf("Missed expected report of type %d\n", (int)ev->report_type); 314da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany EXPECT_FALSE("Missed expected race"); 315da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } 316da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany expect_report = false; 317da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 318da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 319da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid *ScopedThread::Impl::ScopedThreadCallback(void *arg) { 320da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany __tsan_func_entry(__builtin_return_address(0)); 321da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Impl *impl = (Impl*)arg; 322da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany for (;;) { 323da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Event* ev = (Event*)atomic_load(&impl->event, memory_order_acquire); 324da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany if (ev == 0) { 325da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany pthread_yield(); 326da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany continue; 327da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } 328da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany if (ev->type == Event::SHUTDOWN) { 329da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany atomic_store(&impl->event, 0, memory_order_release); 330da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany break; 331da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } 332da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany impl->HandleEvent(ev); 333da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany atomic_store(&impl->event, 0, memory_order_release); 334da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } 335da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany __tsan_func_exit(); 336da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany return 0; 337da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 338da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 339da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid ScopedThread::Impl::send(Event *e) { 340da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany if (main) { 341da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany HandleEvent(e); 342da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } else { 343da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK_EQ(atomic_load(&event, memory_order_relaxed), 0); 344da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany atomic_store(&event, (uintptr_t)e, memory_order_release); 345da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany while (atomic_load(&event, memory_order_acquire) != 0) 346da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany pthread_yield(); 347da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } 348da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 349da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 350da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyScopedThread::ScopedThread(bool detached, bool main) { 351da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany impl_ = new Impl; 352da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany impl_->main = main; 353da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany impl_->detached = detached; 354da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany atomic_store(&impl_->event, 0, memory_order_relaxed); 355da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany if (!main) { 356da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany pthread_attr_t attr; 357da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany pthread_attr_init(&attr); 358da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany pthread_attr_setdetachstate(&attr, detached); 3599d2ffc2ee08216f8fad9b1bd267d1f112e0d2f01Dmitry Vyukov pthread_attr_setstacksize(&attr, 64*1024); 360da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany pthread_create(&impl_->thread, &attr, 361da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany ScopedThread::Impl::ScopedThreadCallback, impl_); 362da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } 363da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 364da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 365da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyScopedThread::~ScopedThread() { 366da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany if (!impl_->main) { 367da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Event event(Event::SHUTDOWN); 368da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany impl_->send(&event); 369da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany if (!impl_->detached) 370da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany pthread_join(impl_->thread, 0); 371da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } 372da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany delete impl_; 373da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 374da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 375da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid ScopedThread::Detach() { 376da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK(!impl_->main); 377da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany CHECK(!impl_->detached); 378da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany impl_->detached = true; 379da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany pthread_detach(impl_->thread); 380da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 381da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 382da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid ScopedThread::Access(void *addr, bool is_write, 383da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany int size, bool expect_race) { 384da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Event event(is_write ? Event::WRITE : Event::READ, addr, size); 385da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany if (expect_race) 386da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany event.ExpectReport(ReportTypeRace); 387da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany impl_->send(&event); 388da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 389da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 390da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid ScopedThread::VptrUpdate(const MemLoc &vptr, 391da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany const MemLoc &new_val, 392da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany bool expect_race) { 393da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Event event(Event::VPTR_UPDATE, vptr.loc(), (uptr)new_val.loc()); 394da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany if (expect_race) 395da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany event.ExpectReport(ReportTypeRace); 396da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany impl_->send(&event); 397da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 398da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 399da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid ScopedThread::Call(void(*pc)()) { 400da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Event event(Event::CALL, (void*)pc); 401da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany impl_->send(&event); 402da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 403da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 404da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid ScopedThread::Return() { 405da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Event event(Event::RETURN); 406da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany impl_->send(&event); 407da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 408da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 409da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid ScopedThread::Create(const Mutex &m) { 410da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Event event(Event::MUTEX_CREATE, &m); 411da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany impl_->send(&event); 412da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 413da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 414da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid ScopedThread::Destroy(const Mutex &m) { 415da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Event event(Event::MUTEX_DESTROY, &m); 416da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany impl_->send(&event); 417da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 418da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 419da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid ScopedThread::Lock(const Mutex &m) { 420da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Event event(Event::MUTEX_LOCK, &m); 421da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany impl_->send(&event); 422da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 423da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 424da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanybool ScopedThread::TryLock(const Mutex &m) { 425da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Event event(Event::MUTEX_TRYLOCK, &m); 426da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany impl_->send(&event); 427da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany return event.res; 428da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 429da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 430da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid ScopedThread::Unlock(const Mutex &m) { 431da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Event event(Event::MUTEX_UNLOCK, &m); 432da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany impl_->send(&event); 433da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 434da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 435da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid ScopedThread::ReadLock(const Mutex &m) { 436da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Event event(Event::MUTEX_READLOCK, &m); 437da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany impl_->send(&event); 438da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 439da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 440da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanybool ScopedThread::TryReadLock(const Mutex &m) { 441da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Event event(Event::MUTEX_TRYREADLOCK, &m); 442da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany impl_->send(&event); 443da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany return event.res; 444da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 445da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 446da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid ScopedThread::ReadUnlock(const Mutex &m) { 447da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Event event(Event::MUTEX_READUNLOCK, &m); 448da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany impl_->send(&event); 449da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 450da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 451da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid ScopedThread::Memcpy(void *dst, const void *src, int size, 452da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany bool expect_race) { 453da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Event event(Event::MEMCPY, dst, (uptr)src, size); 454da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany if (expect_race) 455da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany event.ExpectReport(ReportTypeRace); 456da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany impl_->send(&event); 457da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 458da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 459da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid ScopedThread::Memset(void *dst, int val, int size, 460da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany bool expect_race) { 461da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Event event(Event::MEMSET, dst, val, size); 462da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany if (expect_race) 463da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany event.ExpectReport(ReportTypeRace); 464da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany impl_->send(&event); 465da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany} 466