File: sanitizer_flat_map_test.cpp

package info (click to toggle)
llvm-toolchain-16 1%3A16.0.6-15~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,634,792 kB
  • sloc: cpp: 6,179,261; ansic: 1,216,205; asm: 741,319; python: 196,614; objc: 75,325; f90: 49,640; lisp: 32,396; pascal: 12,286; sh: 9,394; perl: 7,442; ml: 5,494; awk: 3,523; makefile: 2,723; javascript: 1,206; xml: 886; fortran: 581; cs: 573
file content (113 lines) | stat: -rw-r--r-- 3,338 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//===-- sanitizer_flat_map_test.cpp ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "sanitizer_common/sanitizer_flat_map.h"

#include "gtest/gtest.h"
#include "sanitizer_common/tests/sanitizer_pthread_wrappers.h"

using namespace __sanitizer;

namespace {
struct TestMapUnmapCallback1 {
  static int map_count, unmap_count;
  void OnMap(uptr p, uptr size) const { map_count++; }
  void OnUnmap(uptr p, uptr size) const { unmap_count++; }
};
int TestMapUnmapCallback1::map_count;
int TestMapUnmapCallback1::unmap_count;

struct TestStruct {
  int data[125] = {};
  TestStruct(uptr v = 0) { data[11] = v; }
  bool operator==(const TestStruct &other) const {
    return 0 == memcmp(data, other.data, sizeof(data));
  }
};

template <typename T>
class FlatMapTest : public ::testing::Test {};

using FlatMapTestTypes = ::testing::Types<u8, u64, TestStruct>;
TYPED_TEST_SUITE(FlatMapTest, FlatMapTestTypes, );

TYPED_TEST(FlatMapTest, TwoLevelByteMap) {
  const u64 kSize1 = 1 << 6, kSize2 = 1 << 12;
  const u64 n = kSize1 * kSize2;
  TwoLevelMap<TypeParam, kSize1, kSize2> m;
  m.Init();

  m[7] = {10};
  for (u64 i = 0; i < kSize2; ++i) {
    EXPECT_TRUE(m.contains(i));
  }
  EXPECT_FALSE(m.contains(kSize2));

  for (u64 i = 0; i < n; i += 7) {
    m[i] = TypeParam((i % 100) + 1);
  }
  for (u64 j = 0; j < n; j++) {
    EXPECT_TRUE(m.contains(j));
    if (j % 7)
      EXPECT_EQ(m[j], TypeParam());
    else
      EXPECT_EQ(m[j], TypeParam((j % 100) + 1));
  }

  m.TestOnlyUnmap();
}

template <typename TypeParam, typename AddressSpaceView>
using TestMapASVT = TwoLevelMap<TypeParam, 1 << 8, 1 << 7, AddressSpaceView,
                                TestMapUnmapCallback1>;
template <typename TypeParam>
using TestMap = TestMapASVT<TypeParam, LocalAddressSpaceView>;

template <typename TypeParam>
struct TestMapParam {
  TestMap<TypeParam> *m;
  size_t shard;
  size_t num_shards;
};

template <typename TypeParam>
static void *TwoLevelMapUserThread(void *param) {
  TestMapParam<TypeParam> *p = (TestMapParam<TypeParam> *)param;
  for (size_t i = p->shard; i < p->m->size(); i += p->num_shards) {
    TypeParam val = (i % 100) + 1;
    (*p->m)[i] = val;
    EXPECT_EQ((*p->m)[i], val);
  }
  return 0;
}

TYPED_TEST(FlatMapTest, ThreadedTwoLevelByteMap) {
  TestMap<TypeParam> m;
  m.Init();
  TestMapUnmapCallback1::map_count = 0;
  TestMapUnmapCallback1::unmap_count = 0;
  static const int kNumThreads = 4;
  pthread_t t[kNumThreads];
  TestMapParam<TypeParam> p[kNumThreads];
  for (int i = 0; i < kNumThreads; i++) {
    p[i].m = &m;
    p[i].shard = i;
    p[i].num_shards = kNumThreads;
    PTHREAD_CREATE(&t[i], 0, TwoLevelMapUserThread<TypeParam>, &p[i]);
  }
  for (int i = 0; i < kNumThreads; i++) {
    PTHREAD_JOIN(t[i], 0);
  }
  EXPECT_EQ((uptr)TestMapUnmapCallback1::map_count, m.size1());
  EXPECT_EQ((uptr)TestMapUnmapCallback1::unmap_count, 0UL);
  m.TestOnlyUnmap();
  EXPECT_EQ((uptr)TestMapUnmapCallback1::map_count, m.size1());
  EXPECT_EQ((uptr)TestMapUnmapCallback1::unmap_count, m.size1());
}

}  // namespace