1 //===-- tsan_sync_test.cc -------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file is a part of ThreadSanitizer (TSan), a race detector. 11 // 12 //===----------------------------------------------------------------------===// 13 #include "tsan_sync.h" 14 #include "tsan_rtl.h" 15 #include "tsan_mman.h" 16 #include "gtest/gtest.h" 17 18 #include <stdlib.h> 19 #include <stdint.h> 20 #include <map> 21 22 namespace __tsan { 23 24 TEST(Sync, Table) { 25 const uintptr_t kIters = 512*1024; 26 const uintptr_t kRange = 10000; 27 28 ScopedInRtl in_rtl; 29 ThreadState *thr = cur_thread(); 30 uptr pc = 0; 31 32 SyncTab tab; 33 SyncVar *golden[kRange] = {}; 34 unsigned seed = 0; 35 for (uintptr_t i = 0; i < kIters; i++) { 36 uintptr_t addr = rand_r(&seed) % (kRange - 1) + 1; 37 if (rand_r(&seed) % 2) { 38 // Get or add. 39 SyncVar *v = tab.GetOrCreateAndLock(thr, pc, addr, true); 40 EXPECT_TRUE(golden[addr] == 0 || golden[addr] == v); 41 EXPECT_EQ(v->addr, addr); 42 golden[addr] = v; 43 v->mtx.Unlock(); 44 } else { 45 // Remove. 46 SyncVar *v = tab.GetAndRemove(thr, pc, addr); 47 EXPECT_EQ(golden[addr], v); 48 if (v) { 49 EXPECT_EQ(v->addr, addr); 50 golden[addr] = 0; 51 DestroyAndFree(v); 52 } 53 } 54 } 55 for (uintptr_t addr = 0; addr < kRange; addr++) { 56 if (golden[addr] == 0) 57 continue; 58 SyncVar *v = tab.GetAndRemove(thr, pc, addr); 59 EXPECT_EQ(v, golden[addr]); 60 EXPECT_EQ(v->addr, addr); 61 DestroyAndFree(v); 62 } 63 } 64 65 } // namespace __tsan 66