102 lines · cpp
1//===-- tsan_clock_test.cpp -----------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file is a part of ThreadSanitizer (TSan), a race detector.10//11//===----------------------------------------------------------------------===//12#include "tsan_vector_clock.h"13 14#include "gtest/gtest.h"15#include "tsan_rtl.h"16 17namespace __tsan {18 19TEST(VectorClock, GetSet) {20 // Compiler won't ensure alignment on stack.21 VectorClock *vc = New<VectorClock>();22 for (uptr i = 0; i < kThreadSlotCount; i++)23 ASSERT_EQ(vc->Get(static_cast<Sid>(i)), kEpochZero);24 for (uptr i = 0; i < kThreadSlotCount; i++)25 vc->Set(static_cast<Sid>(i), static_cast<Epoch>(i));26 for (uptr i = 0; i < kThreadSlotCount; i++)27 ASSERT_EQ(vc->Get(static_cast<Sid>(i)), static_cast<Epoch>(i));28 vc->Reset();29 for (uptr i = 0; i < kThreadSlotCount; i++)30 ASSERT_EQ(vc->Get(static_cast<Sid>(i)), kEpochZero);31 DestroyAndFree(vc);32}33 34TEST(VectorClock, VectorOps) {35 VectorClock *vc1 = New<VectorClock>();36 VectorClock *vc2 = nullptr;37 VectorClock *vc3 = nullptr;38 39 vc1->Acquire(vc2);40 for (uptr i = 0; i < kThreadSlotCount; i++)41 ASSERT_EQ(vc1->Get(static_cast<Sid>(i)), kEpochZero);42 vc1->Release(&vc2);43 EXPECT_NE(vc2, nullptr);44 vc1->Acquire(vc2);45 for (uptr i = 0; i < kThreadSlotCount; i++)46 ASSERT_EQ(vc1->Get(static_cast<Sid>(i)), kEpochZero);47 48 for (uptr i = 0; i < kThreadSlotCount; i++) {49 vc1->Set(static_cast<Sid>(i), static_cast<Epoch>(i));50 vc2->Set(static_cast<Sid>(i), static_cast<Epoch>(kThreadSlotCount - i));51 }52 vc1->Acquire(vc2);53 for (uptr i = 0; i < kThreadSlotCount; i++) {54 ASSERT_EQ(vc1->Get(static_cast<Sid>(i)),55 static_cast<Epoch>(i < kThreadSlotCount / 2 ? kThreadSlotCount - i56 : i));57 ASSERT_EQ(vc2->Get(static_cast<Sid>(i)),58 static_cast<Epoch>(kThreadSlotCount - i));59 }60 vc2->ReleaseStore(&vc3);61 for (uptr i = 0; i < kThreadSlotCount; i++) {62 ASSERT_EQ(vc3->Get(static_cast<Sid>(i)),63 static_cast<Epoch>(kThreadSlotCount - i));64 ASSERT_EQ(vc2->Get(static_cast<Sid>(i)),65 static_cast<Epoch>(kThreadSlotCount - i));66 }67 68 vc1->Reset();69 vc2->Reset();70 for (uptr i = 0; i < kThreadSlotCount; i++) {71 vc1->Set(static_cast<Sid>(i), static_cast<Epoch>(i));72 vc2->Set(static_cast<Sid>(i), static_cast<Epoch>(kThreadSlotCount - i));73 }74 vc1->ReleaseAcquire(&vc2);75 for (uptr i = 0; i < kThreadSlotCount; i++) {76 Epoch expect =77 static_cast<Epoch>(i < kThreadSlotCount / 2 ? kThreadSlotCount - i : i);78 ASSERT_EQ(vc1->Get(static_cast<Sid>(i)), expect);79 ASSERT_EQ(vc2->Get(static_cast<Sid>(i)), expect);80 }81 82 vc1->Reset();83 vc2->Reset();84 for (uptr i = 0; i < kThreadSlotCount; i++) {85 vc1->Set(static_cast<Sid>(i), static_cast<Epoch>(i));86 vc2->Set(static_cast<Sid>(i), static_cast<Epoch>(kThreadSlotCount - i));87 }88 vc1->ReleaseStoreAcquire(&vc2);89 for (uptr i = 0; i < kThreadSlotCount; i++) {90 ASSERT_EQ(vc1->Get(static_cast<Sid>(i)),91 static_cast<Epoch>(i < kThreadSlotCount / 2 ? kThreadSlotCount - i92 : i));93 ASSERT_EQ(vc2->Get(static_cast<Sid>(i)), static_cast<Epoch>(i));94 }95 96 DestroyAndFree(vc1);97 DestroyAndFree(vc2);98 DestroyAndFree(vc3);99}100 101} // namespace __tsan102