Electroneum
mlocker.cpp
Go to the documentation of this file.
1 // Copyright (c) 2018, The Monero Project
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification, are
6 // permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice, this list of
9 // conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 // of conditions and the following disclaimer in the documentation and/or other
13 // materials provided with the distribution.
14 //
15 // 3. Neither the name of the copyright holder nor the names of its contributors may be
16 // used to endorse or promote products derived from this software without specific
17 // prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 #include "gtest/gtest.h"
30 
31 #include "misc_log_ex.h"
32 #include "mlocker.h"
33 
34 #if defined __GNUC__ && !defined _WIN32
35 #define HAVE_MLOCK 1
36 #endif
37 
38 #ifdef HAVE_MLOCK
39 
40 #define BASE(data) (char*)(((uintptr_t)(data.get() + page_size - 1)) / page_size * page_size)
41 
42 TEST(mlocker, distinct_1)
43 {
44  const size_t page_size = epee::mlocker::get_page_size();
45  ASSERT_TRUE(page_size > 0);
46  const size_t base_pages = epee::mlocker::get_num_locked_pages();
47  const size_t base_objects = epee::mlocker::get_num_locked_objects();
48  std::unique_ptr<char[]> data{new char[8 * page_size]};
49  std::shared_ptr<epee::mlocker> m0{new epee::mlocker(BASE(data), 1)};
50  std::shared_ptr<epee::mlocker> m1{new epee::mlocker(BASE(data) + 2 * page_size, 1)};
51  std::shared_ptr<epee::mlocker> m2{new epee::mlocker(BASE(data) + 3 * page_size, 1)};
54  m0 = NULL;
55  m1 = NULL;
56  m2 = NULL;
59 }
60 
61 TEST(mlocker, distinct_full_page)
62 {
63  const size_t page_size = epee::mlocker::get_page_size();
64  ASSERT_TRUE(page_size > 0);
65  const size_t base_pages = epee::mlocker::get_num_locked_pages();
66  const size_t base_objects = epee::mlocker::get_num_locked_objects();
67  std::unique_ptr<char[]> data{new char[8 * page_size]};
68  std::shared_ptr<epee::mlocker> m0{new epee::mlocker(BASE(data), page_size)};
69  std::shared_ptr<epee::mlocker> m1{new epee::mlocker(BASE(data) + 2 * page_size, page_size)};
70  std::shared_ptr<epee::mlocker> m2{new epee::mlocker(BASE(data) + 3 * page_size, page_size)};
73  m0 = NULL;
74  m1 = NULL;
75  m2 = NULL;
78 }
79 
80 TEST(mlocker, identical)
81 {
82  const size_t page_size = epee::mlocker::get_page_size();
83  ASSERT_TRUE(page_size >= 32);
84  const size_t base_pages = epee::mlocker::get_num_locked_pages();
85  const size_t base_objects = epee::mlocker::get_num_locked_objects();
86  std::unique_ptr<char[]> data{new char[8 * page_size]};
87  std::shared_ptr<epee::mlocker> m0{new epee::mlocker(BASE(data) + page_size, 32)};
88  std::shared_ptr<epee::mlocker> m1{new epee::mlocker(BASE(data) + page_size, 32)};
89  std::shared_ptr<epee::mlocker> m2{new epee::mlocker(BASE(data) + page_size, 32)};
92  m1 = NULL;
95  m0 = NULL;
96  m2 = NULL;
99 }
100 
101 TEST(mlocker, overlapping_small)
102 {
103  const size_t page_size = epee::mlocker::get_page_size();
104  ASSERT_TRUE(page_size >= 64);
105  const size_t base_pages = epee::mlocker::get_num_locked_pages();
106  const size_t base_objects = epee::mlocker::get_num_locked_objects();
107  std::unique_ptr<char[]> data{new char[8 * page_size]};
108  std::shared_ptr<epee::mlocker> m0{new epee::mlocker(BASE(data), 32)};
109  std::shared_ptr<epee::mlocker> m1{new epee::mlocker(BASE(data) + 16, 32)};
110  std::shared_ptr<epee::mlocker> m2{new epee::mlocker(BASE(data) + 8, 32)};
113  m1 = NULL;
116  m2 = NULL;
117  m0 = NULL;
120 }
121 
122 TEST(mlocker, multi_page)
123 {
124  const size_t page_size = epee::mlocker::get_page_size();
125  ASSERT_TRUE(page_size > 0);
126  const size_t base_pages = epee::mlocker::get_num_locked_pages();
127  const size_t base_objects = epee::mlocker::get_num_locked_objects();
128  std::unique_ptr<char[]> data{new char[8 * page_size]};
129  std::shared_ptr<epee::mlocker> m0{new epee::mlocker(BASE(data) + page_size, page_size * 3)};
132  std::shared_ptr<epee::mlocker> m1{new epee::mlocker(BASE(data) + page_size * 7, page_size)};
135  m0 = NULL;
138  m1 = NULL;
141 }
142 
143 TEST(mlocker, cross_page)
144 {
145  const size_t page_size = epee::mlocker::get_page_size();
146  ASSERT_TRUE(page_size > 32);
147  const size_t base_pages = epee::mlocker::get_num_locked_pages();
148  const size_t base_objects = epee::mlocker::get_num_locked_objects();
149  std::unique_ptr<char[]> data{new char[2 * page_size]};
150  std::shared_ptr<epee::mlocker> m0{new epee::mlocker(BASE(data) + page_size - 1, 2)};
153  m0 = NULL;
156 }
157 
158 TEST(mlocker, redundant)
159 {
160  const size_t page_size = epee::mlocker::get_page_size();
161  ASSERT_TRUE(page_size > 0);
162  const size_t base_pages = epee::mlocker::get_num_locked_pages();
163  const size_t base_objects = epee::mlocker::get_num_locked_objects();
164  std::unique_ptr<char[]> data{new char[2 * page_size]};
167  std::shared_ptr<epee::mlocker> m0{new epee::mlocker(BASE(data), 32)};
170  std::shared_ptr<epee::mlocker> m1{new epee::mlocker(BASE(data), 32)};
173  m1 = NULL;
176  m0 = NULL;
179 }
180 
181 TEST(mlocker, mlocked)
182 {
183  const size_t base_pages = epee::mlocker::get_num_locked_pages();
184  const size_t base_objects = epee::mlocker::get_num_locked_objects();
185  {
186  struct Foo { uint64_t u; };
190  }
193 }
194 
195 #endif
Definition: fwdtest.cpp:28
static size_t get_page_size()
Definition: mlocker.cpp:107
#define TEST(test_case_name, test_name)
Definition: gtest.h:2187
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
unsigned __int64 uint64_t
Definition: stdint.h:136
static size_t get_num_locked_objects()
Definition: mlocker.cpp:167
static size_t get_num_locked_pages()
Definition: mlocker.cpp:161
#define ASSERT_TRUE(condition)
Definition: gtest.h:1865