xref: /llvm-project/compiler-rt/lib/tsan/tests/unit/tsan_vector_clock_test.cpp (revision 5c2b48fdb0a6f8dd7fb3fc24bdd3c028a2e3a51a)
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-exception
6 //
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 
17 namespace __tsan {
18 
TEST(VectorClock,GetSet)19 TEST(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 
TEST(VectorClock,VectorOps)34 TEST(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 - i
56                                                           : 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 - i
92                                                           : 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 __tsan
102