xref: /openbsd-src/gnu/llvm/compiler-rt/lib/sanitizer_common/tests/sanitizer_flat_map_test.cpp (revision 810390e339a5425391477d5d41c78d7cab2424ac)
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 struct TestMapUnmapCallback1 {
18   static int map_count, unmap_count;
OnMap__anond61fc3e70111::TestMapUnmapCallback119   void OnMap(uptr p, uptr size) const { map_count++; }
OnUnmap__anond61fc3e70111::TestMapUnmapCallback120   void OnUnmap(uptr p, uptr size) const { unmap_count++; }
21 };
22 int TestMapUnmapCallback1::map_count;
23 int TestMapUnmapCallback1::unmap_count;
24 
25 struct TestStruct {
26   int data[125] = {};
TestStruct__anond61fc3e70111::TestStruct27   TestStruct(uptr v = 0) { data[11] = v; }
operator ==__anond61fc3e70111::TestStruct28   bool operator==(const TestStruct &other) const {
29     return 0 == memcmp(data, other.data, sizeof(data));
30   }
31 };
32 
33 template <typename T>
34 class FlatMapTest : public ::testing::Test {};
35 
36 using FlatMapTestTypes = ::testing::Types<u8, u64, TestStruct>;
37 TYPED_TEST_SUITE(FlatMapTest, FlatMapTestTypes, );
38 
TYPED_TEST(FlatMapTest,TwoLevelByteMap)39 TYPED_TEST(FlatMapTest, TwoLevelByteMap) {
40   const u64 kSize1 = 1 << 6, kSize2 = 1 << 12;
41   const u64 n = kSize1 * kSize2;
42   TwoLevelMap<TypeParam, kSize1, kSize2> m;
43   m.Init();
44 
45   m[7] = {10};
46   for (u64 i = 0; i < kSize2; ++i) {
47     EXPECT_TRUE(m.contains(i));
48   }
49   EXPECT_FALSE(m.contains(kSize2));
50 
51   for (u64 i = 0; i < n; i += 7) {
52     m[i] = TypeParam((i % 100) + 1);
53   }
54   for (u64 j = 0; j < n; j++) {
55     EXPECT_TRUE(m.contains(j));
56     if (j % 7)
57       EXPECT_EQ(m[j], TypeParam());
58     else
59       EXPECT_EQ(m[j], TypeParam((j % 100) + 1));
60   }
61 
62   m.TestOnlyUnmap();
63 }
64 
65 template <typename TypeParam, typename AddressSpaceView>
66 using TestMapASVT = TwoLevelMap<TypeParam, 1 << 8, 1 << 7, AddressSpaceView,
67                                 TestMapUnmapCallback1>;
68 template <typename TypeParam>
69 using TestMap = TestMapASVT<TypeParam, LocalAddressSpaceView>;
70 
71 template <typename TypeParam>
72 struct TestMapParam {
73   TestMap<TypeParam> *m;
74   size_t shard;
75   size_t num_shards;
76 };
77 
78 template <typename TypeParam>
TwoLevelMapUserThread(void * param)79 static void *TwoLevelMapUserThread(void *param) {
80   TestMapParam<TypeParam> *p = (TestMapParam<TypeParam> *)param;
81   for (size_t i = p->shard; i < p->m->size(); i += p->num_shards) {
82     TypeParam val = (i % 100) + 1;
83     (*p->m)[i] = val;
84     EXPECT_EQ((*p->m)[i], val);
85   }
86   return 0;
87 }
88 
TYPED_TEST(FlatMapTest,ThreadedTwoLevelByteMap)89 TYPED_TEST(FlatMapTest, ThreadedTwoLevelByteMap) {
90   TestMap<TypeParam> m;
91   m.Init();
92   TestMapUnmapCallback1::map_count = 0;
93   TestMapUnmapCallback1::unmap_count = 0;
94   static const int kNumThreads = 4;
95   pthread_t t[kNumThreads];
96   TestMapParam<TypeParam> p[kNumThreads];
97   for (int i = 0; i < kNumThreads; i++) {
98     p[i].m = &m;
99     p[i].shard = i;
100     p[i].num_shards = kNumThreads;
101     PTHREAD_CREATE(&t[i], 0, TwoLevelMapUserThread<TypeParam>, &p[i]);
102   }
103   for (int i = 0; i < kNumThreads; i++) {
104     PTHREAD_JOIN(t[i], 0);
105   }
106   EXPECT_EQ((uptr)TestMapUnmapCallback1::map_count, m.size1());
107   EXPECT_EQ((uptr)TestMapUnmapCallback1::unmap_count, 0UL);
108   m.TestOnlyUnmap();
109   EXPECT_EQ((uptr)TestMapUnmapCallback1::map_count, m.size1());
110   EXPECT_EQ((uptr)TestMapUnmapCallback1::unmap_count, m.size1());
111 }
112 
113 }  // namespace
114