xref: /llvm-project/compiler-rt/lib/sanitizer_common/tests/sanitizer_flat_map_test.cpp (revision 42adbb1b2d8fff7dc8e495f2954ec965acf65d91)
1 //===-- sanitizer_flat_map_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 #include "sanitizer_common/sanitizer_flat_map.h"
10 
11 #include "gtest/gtest.h"
12 #include "sanitizer_common/tests/sanitizer_pthread_wrappers.h"
13 
14 using namespace __sanitizer;
15 
16 namespace {
17 
18 struct TestStruct {
19   int data[125] = {};
TestStruct__anonfb66c4830111::TestStruct20   TestStruct(uptr v = 0) { data[11] = v; }
operator ==__anonfb66c4830111::TestStruct21   bool operator==(const TestStruct &other) const {
22     return 0 == memcmp(data, other.data, sizeof(data));
23   }
24 };
25 
26 template <typename T>
27 class FlatMapTest : public ::testing::Test {};
28 
29 using FlatMapTestTypes = ::testing::Types<u8, u64, TestStruct>;
30 TYPED_TEST_SUITE(FlatMapTest, FlatMapTestTypes, );
31 
TYPED_TEST(FlatMapTest,TwoLevelByteMap)32 TYPED_TEST(FlatMapTest, TwoLevelByteMap) {
33   const u64 kSize1 = 1 << 6, kSize2 = 1 << 12;
34   const u64 n = kSize1 * kSize2;
35   TwoLevelMap<TypeParam, kSize1, kSize2> m;
36   m.Init();
37 
38   m[7] = {10};
39   for (u64 i = 0; i < kSize2; ++i) {
40     EXPECT_TRUE(m.contains(i));
41   }
42   EXPECT_FALSE(m.contains(kSize2));
43 
44   for (u64 i = 0; i < n; i += 7) {
45     m[i] = TypeParam((i % 100) + 1);
46   }
47   for (u64 j = 0; j < n; j++) {
48     EXPECT_TRUE(m.contains(j));
49     if (j % 7)
50       EXPECT_EQ(m[j], TypeParam());
51     else
52       EXPECT_EQ(m[j], TypeParam((j % 100) + 1));
53   }
54 
55   m.TestOnlyUnmap();
56 }
57 
58 template <typename TypeParam, typename AddressSpaceView>
59 using TestMapASVT = TwoLevelMap<TypeParam, 1 << 8, 1 << 7, AddressSpaceView>;
60 template <typename TypeParam>
61 using TestMap = TestMapASVT<TypeParam, LocalAddressSpaceView>;
62 
63 template <typename TypeParam>
64 struct TestMapParam {
65   TestMap<TypeParam> *m;
66   size_t shard;
67   size_t num_shards;
68 };
69 
70 template <typename TypeParam>
TwoLevelMapUserThread(void * param)71 static void *TwoLevelMapUserThread(void *param) {
72   TestMapParam<TypeParam> *p = (TestMapParam<TypeParam> *)param;
73   for (size_t i = p->shard; i < p->m->size(); i += p->num_shards) {
74     TypeParam val = (i % 100) + 1;
75     (*p->m)[i] = val;
76     EXPECT_EQ((*p->m)[i], val);
77   }
78   return 0;
79 }
80 
TYPED_TEST(FlatMapTest,ThreadedTwoLevelByteMap)81 TYPED_TEST(FlatMapTest, ThreadedTwoLevelByteMap) {
82   TestMap<TypeParam> m;
83   m.Init();
84   static const int kNumThreads = 4;
85   pthread_t t[kNumThreads];
86   TestMapParam<TypeParam> p[kNumThreads];
87   for (int i = 0; i < kNumThreads; i++) {
88     p[i].m = &m;
89     p[i].shard = i;
90     p[i].num_shards = kNumThreads;
91     PTHREAD_CREATE(&t[i], 0, TwoLevelMapUserThread<TypeParam>, &p[i]);
92   }
93   for (int i = 0; i < kNumThreads; i++) PTHREAD_JOIN(t[i], 0);
94   m.TestOnlyUnmap();
95 }
96 
97 }  // namespace
98