16435ca4eSVitaly Buka //===-- common_test.cpp -----------------------------------------*- C++ -*-===//
20bccdf82SVitaly Buka //
30bccdf82SVitaly Buka // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40bccdf82SVitaly Buka // See https://llvm.org/LICENSE.txt for license information.
50bccdf82SVitaly Buka // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60bccdf82SVitaly Buka //
70bccdf82SVitaly Buka //===----------------------------------------------------------------------===//
80bccdf82SVitaly Buka 
90bccdf82SVitaly Buka #include "internal_defs.h"
100bccdf82SVitaly Buka #include "tests/scudo_unit_test.h"
110bccdf82SVitaly Buka 
120bccdf82SVitaly Buka #include "common.h"
130bccdf82SVitaly Buka #include <algorithm>
140bccdf82SVitaly Buka #include <fstream>
150bccdf82SVitaly Buka 
160bccdf82SVitaly Buka namespace scudo {
170bccdf82SVitaly Buka 
getResidentMemorySize()180bccdf82SVitaly Buka static uptr getResidentMemorySize() {
196435ca4eSVitaly Buka   if (!SCUDO_LINUX)
206435ca4eSVitaly Buka     UNREACHABLE("Not implemented!");
210bccdf82SVitaly Buka   uptr Size;
220bccdf82SVitaly Buka   uptr Resident;
230bccdf82SVitaly Buka   std::ifstream IFS("/proc/self/statm");
240bccdf82SVitaly Buka   IFS >> Size;
250bccdf82SVitaly Buka   IFS >> Resident;
260bccdf82SVitaly Buka   return Resident * getPageSizeCached();
270bccdf82SVitaly Buka }
280bccdf82SVitaly Buka 
290bccdf82SVitaly Buka // Fuchsia needs getResidentMemorySize implementation.
TEST(ScudoCommonTest,SKIP_ON_FUCHSIA (ResidentMemorySize))300bccdf82SVitaly Buka TEST(ScudoCommonTest, SKIP_ON_FUCHSIA(ResidentMemorySize)) {
310bccdf82SVitaly Buka   uptr OnStart = getResidentMemorySize();
32bec6b022SJinsong Ji   EXPECT_GT(OnStart, 0UL);
330bccdf82SVitaly Buka 
340bccdf82SVitaly Buka   const uptr Size = 1ull << 30;
350bccdf82SVitaly Buka   const uptr Threshold = Size >> 3;
360bccdf82SVitaly Buka 
376435ca4eSVitaly Buka   MapPlatformData Data = {};
38c261edb2SVitaly Buka   void *P = map(nullptr, Size, "ResidentMemorySize", 0, &Data);
390bccdf82SVitaly Buka   ASSERT_NE(nullptr, P);
40*b40908e6SVitaly Buka   EXPECT_LT(getResidentMemorySize(), OnStart + Threshold);
410bccdf82SVitaly Buka 
420bccdf82SVitaly Buka   memset(P, 1, Size);
43*b40908e6SVitaly Buka   EXPECT_GT(getResidentMemorySize(), OnStart + Size - Threshold);
440bccdf82SVitaly Buka 
450bccdf82SVitaly Buka   releasePagesToOS((uptr)P, 0, Size, &Data);
46*b40908e6SVitaly Buka   EXPECT_LT(getResidentMemorySize(), OnStart + Threshold);
470bccdf82SVitaly Buka 
480bccdf82SVitaly Buka   memset(P, 1, Size);
49*b40908e6SVitaly Buka   EXPECT_GT(getResidentMemorySize(), OnStart + Size - Threshold);
50e14696bfSVitaly Buka 
51e14696bfSVitaly Buka   unmap(P, Size, 0, &Data);
520bccdf82SVitaly Buka }
530bccdf82SVitaly Buka 
TEST(ScudoCommonTest,Zeros)54c261edb2SVitaly Buka TEST(ScudoCommonTest, Zeros) {
55c261edb2SVitaly Buka   const uptr Size = 1ull << 20;
56c261edb2SVitaly Buka 
57c261edb2SVitaly Buka   MapPlatformData Data = {};
58c261edb2SVitaly Buka   uptr *P = reinterpret_cast<uptr *>(map(nullptr, Size, "Zeros", 0, &Data));
59c261edb2SVitaly Buka   const ptrdiff_t N = Size / sizeof(*P);
60c261edb2SVitaly Buka   ASSERT_NE(nullptr, P);
61c261edb2SVitaly Buka   EXPECT_EQ(std::count(P, P + N, 0), N);
62c261edb2SVitaly Buka 
63c261edb2SVitaly Buka   memset(P, 1, Size);
64c261edb2SVitaly Buka   EXPECT_EQ(std::count(P, P + N, 0), 0);
65c261edb2SVitaly Buka 
66c261edb2SVitaly Buka   releasePagesToOS((uptr)P, 0, Size, &Data);
67c261edb2SVitaly Buka   EXPECT_EQ(std::count(P, P + N, 0), N);
68c261edb2SVitaly Buka 
69c261edb2SVitaly Buka   unmap(P, Size, 0, &Data);
70c261edb2SVitaly Buka }
71c261edb2SVitaly Buka 
720bccdf82SVitaly Buka } // namespace scudo
73