1 //===-- bytemap_test.cpp ----------------------------------------*- C++ -*-===//
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 "bytemap.h"
10 
11 #include "gtest/gtest.h"
12 
13 #include <string.h>
14 
15 template <typename T> void testMap(T &Map, scudo::uptr Size) {
16   Map.init();
17   for (scudo::uptr I = 0; I < Size; I += 7)
18     Map.set(I, (I % 100) + 1);
19   for (scudo::uptr J = 0; J < Size; J++) {
20     if (J % 7)
21       EXPECT_EQ(Map[J], 0);
22     else
23       EXPECT_EQ(Map[J], (J % 100) + 1);
24   }
25 }
26 
27 TEST(ScudoByteMapTest, FlatByteMap) {
28   const scudo::uptr Size = 1U << 10;
29   scudo::FlatByteMap<Size> Map;
30   testMap(Map, Size);
31   Map.unmapTestOnly();
32 }
33 
34 TEST(ScudoByteMapTest, TwoLevelByteMap) {
35   const scudo::uptr Size1 = 1U << 6, Size2 = 1U << 12;
36   scudo::TwoLevelByteMap<Size1, Size2> Map;
37   testMap(Map, Size1 * Size2);
38   Map.unmapTestOnly();
39 }
40 
41 using TestByteMap = scudo::TwoLevelByteMap<1U << 12, 1U << 13>;
42 
43 struct TestByteMapParam {
44   TestByteMap *Map;
45   scudo::uptr Shard;
46   scudo::uptr NumberOfShards;
47 };
48 
49 void *populateByteMap(void *Param) {
50   TestByteMapParam *P = reinterpret_cast<TestByteMapParam *>(Param);
51   for (scudo::uptr I = P->Shard; I < P->Map->size(); I += P->NumberOfShards) {
52     scudo::u8 V = static_cast<scudo::u8>((I % 100) + 1);
53     P->Map->set(I, V);
54     EXPECT_EQ((*P->Map)[I], V);
55   }
56   return 0;
57 }
58 
59 TEST(ScudoByteMapTest, ThreadedTwoLevelByteMap) {
60   TestByteMap Map;
61   Map.init();
62   static const scudo::uptr NumberOfThreads = 16U;
63   pthread_t T[NumberOfThreads];
64   TestByteMapParam P[NumberOfThreads];
65   for (scudo::uptr I = 0; I < NumberOfThreads; I++) {
66     P[I].Map = &Map;
67     P[I].Shard = I;
68     P[I].NumberOfShards = NumberOfThreads;
69     pthread_create(&T[I], 0, populateByteMap, &P[I]);
70   }
71   for (scudo::uptr I = 0; I < NumberOfThreads; I++)
72     pthread_join(T[I], 0);
73   Map.unmapTestOnly();
74 }
75