xref: /openbsd-src/gnu/llvm/compiler-rt/lib/scudo/standalone/tests/common_test.cpp (revision 810390e339a5425391477d5d41c78d7cab2424ac)
1d89ec533Spatrick //===-- common_test.cpp -----------------------------------------*- C++ -*-===//
2d89ec533Spatrick //
3d89ec533Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4d89ec533Spatrick // See https://llvm.org/LICENSE.txt for license information.
5d89ec533Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d89ec533Spatrick //
7d89ec533Spatrick //===----------------------------------------------------------------------===//
8d89ec533Spatrick 
9d89ec533Spatrick #include "internal_defs.h"
10d89ec533Spatrick #include "tests/scudo_unit_test.h"
11d89ec533Spatrick 
12d89ec533Spatrick #include "common.h"
13d89ec533Spatrick #include <algorithm>
14d89ec533Spatrick #include <fstream>
15d89ec533Spatrick 
16d89ec533Spatrick namespace scudo {
17d89ec533Spatrick 
getResidentMemorySize()18d89ec533Spatrick static uptr getResidentMemorySize() {
19d89ec533Spatrick   if (!SCUDO_LINUX)
20d89ec533Spatrick     UNREACHABLE("Not implemented!");
21d89ec533Spatrick   uptr Size;
22d89ec533Spatrick   uptr Resident;
23d89ec533Spatrick   std::ifstream IFS("/proc/self/statm");
24d89ec533Spatrick   IFS >> Size;
25d89ec533Spatrick   IFS >> Resident;
26d89ec533Spatrick   return Resident * getPageSizeCached();
27d89ec533Spatrick }
28d89ec533Spatrick 
29d89ec533Spatrick // Fuchsia needs getResidentMemorySize implementation.
TEST(ScudoCommonTest,SKIP_ON_FUCHSIA (ResidentMemorySize))30d89ec533Spatrick TEST(ScudoCommonTest, SKIP_ON_FUCHSIA(ResidentMemorySize)) {
31d89ec533Spatrick   uptr OnStart = getResidentMemorySize();
32d89ec533Spatrick   EXPECT_GT(OnStart, 0UL);
33d89ec533Spatrick 
34d89ec533Spatrick   const uptr Size = 1ull << 30;
35d89ec533Spatrick   const uptr Threshold = Size >> 3;
36d89ec533Spatrick 
37d89ec533Spatrick   MapPlatformData Data = {};
38d89ec533Spatrick   void *P = map(nullptr, Size, "ResidentMemorySize", 0, &Data);
39d89ec533Spatrick   ASSERT_NE(nullptr, P);
40d89ec533Spatrick   EXPECT_LT(getResidentMemorySize(), OnStart + Threshold);
41d89ec533Spatrick 
42d89ec533Spatrick   memset(P, 1, Size);
43d89ec533Spatrick   EXPECT_GT(getResidentMemorySize(), OnStart + Size - Threshold);
44d89ec533Spatrick 
45d89ec533Spatrick   releasePagesToOS((uptr)P, 0, Size, &Data);
46d89ec533Spatrick   EXPECT_LT(getResidentMemorySize(), OnStart + Threshold);
47d89ec533Spatrick 
48d89ec533Spatrick   memset(P, 1, Size);
49d89ec533Spatrick   EXPECT_GT(getResidentMemorySize(), OnStart + Size - Threshold);
50d89ec533Spatrick 
51d89ec533Spatrick   unmap(P, Size, 0, &Data);
52d89ec533Spatrick }
53d89ec533Spatrick 
TEST(ScudoCommonTest,Zeros)54d89ec533Spatrick TEST(ScudoCommonTest, Zeros) {
55d89ec533Spatrick   const uptr Size = 1ull << 20;
56d89ec533Spatrick 
57d89ec533Spatrick   MapPlatformData Data = {};
58d89ec533Spatrick   uptr *P = reinterpret_cast<uptr *>(map(nullptr, Size, "Zeros", 0, &Data));
59d89ec533Spatrick   const ptrdiff_t N = Size / sizeof(*P);
60d89ec533Spatrick   ASSERT_NE(nullptr, P);
61d89ec533Spatrick   EXPECT_EQ(std::count(P, P + N, 0), N);
62d89ec533Spatrick 
63d89ec533Spatrick   memset(P, 1, Size);
64d89ec533Spatrick   EXPECT_EQ(std::count(P, P + N, 0), 0);
65d89ec533Spatrick 
66d89ec533Spatrick   releasePagesToOS((uptr)P, 0, Size, &Data);
67d89ec533Spatrick   EXPECT_EQ(std::count(P, P + N, 0), N);
68d89ec533Spatrick 
69d89ec533Spatrick   unmap(P, Size, 0, &Data);
70d89ec533Spatrick }
71d89ec533Spatrick 
72*810390e3Srobert #if SCUDO_LINUX && !defined(__powerpc__)
73*810390e3Srobert // This test fails intermediately on PPC, which is why this test is disabled
74*810390e3Srobert // for now on this platform.
TEST(ScudoCommonTest,GetRssFromBuffer)75*810390e3Srobert TEST(ScudoCommonTest, GetRssFromBuffer) {
76*810390e3Srobert   constexpr int64_t AllocSize = 10000000;
77*810390e3Srobert   constexpr int64_t Error = 3000000;
78*810390e3Srobert   constexpr size_t Runs = 10;
79*810390e3Srobert 
80*810390e3Srobert   int64_t Rss = scudo::GetRSS();
81*810390e3Srobert   EXPECT_GT(Rss, 0);
82*810390e3Srobert 
83*810390e3Srobert   std::vector<std::unique_ptr<char[]>> Allocs(Runs);
84*810390e3Srobert   for (auto &Alloc : Allocs) {
85*810390e3Srobert     Alloc.reset(new char[AllocSize]());
86*810390e3Srobert     int64_t Prev = Rss;
87*810390e3Srobert     Rss = scudo::GetRSS();
88*810390e3Srobert     EXPECT_LE(std::abs(Rss - AllocSize - Prev), Error);
89*810390e3Srobert   }
90*810390e3Srobert }
91*810390e3Srobert #endif // SCUDO_LINUX
92*810390e3Srobert 
93d89ec533Spatrick } // namespace scudo
94