Line data Source code
1 : // Copyright (c) 2012-2013 The Bitcoin Core developers
2 : // Distributed under the MIT software license, see the accompanying
3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 :
5 : #include "util.h"
6 :
7 : #include "support/allocators/secure.h"
8 : #include "test/test_bitcoin.h"
9 :
10 : #include <boost/test/unit_test.hpp>
11 :
12 1 : BOOST_FIXTURE_TEST_SUITE(allocator_tests, BasicTestingSetup)
13 :
14 : // Dummy memory page locker for platform independent tests
15 : static const void *last_lock_addr, *last_unlock_addr;
16 : static size_t last_lock_len, last_unlock_len;
17 : class TestLocker
18 : {
19 : public:
20 0 : bool Lock(const void *addr, size_t len)
21 : {
22 1211 : last_lock_addr = addr;
23 1211 : last_lock_len = len;
24 0 : return true;
25 : }
26 0 : bool Unlock(const void *addr, size_t len)
27 : {
28 1211 : last_unlock_addr = addr;
29 1211 : last_unlock_len = len;
30 0 : return true;
31 : }
32 : };
33 :
34 6 : BOOST_AUTO_TEST_CASE(test_LockedPageManagerBase)
35 : {
36 1 : const size_t test_page_size = 4096;
37 1 : LockedPageManagerBase<TestLocker> lpm(test_page_size);
38 : size_t addr;
39 1 : last_lock_addr = last_unlock_addr = 0;
40 1 : last_lock_len = last_unlock_len = 0;
41 :
42 : /* Try large number of small objects */
43 1 : addr = 0;
44 1001 : for(int i=0; i<1000; ++i)
45 : {
46 1000 : lpm.LockRange(reinterpret_cast<void*>(addr), 33);
47 1000 : addr += 33;
48 : }
49 : /* Try small number of page-sized objects, straddling two pages */
50 : addr = test_page_size*100 + 53;
51 100 : for(int i=0; i<100; ++i)
52 : {
53 100 : lpm.LockRange(reinterpret_cast<void*>(addr), test_page_size);
54 100 : addr += test_page_size;
55 : }
56 : /* Try small number of page-sized objects aligned to exactly one page */
57 : addr = test_page_size*300;
58 100 : for(int i=0; i<100; ++i)
59 : {
60 100 : lpm.LockRange(reinterpret_cast<void*>(addr), test_page_size);
61 100 : addr += test_page_size;
62 : }
63 : /* one very large object, straddling pages */
64 1 : lpm.LockRange(reinterpret_cast<void*>(test_page_size*600+1), test_page_size*500);
65 8 : BOOST_CHECK(last_lock_addr == reinterpret_cast<void*>(test_page_size*(600+500)));
66 : /* one very large object, page aligned */
67 1 : lpm.LockRange(reinterpret_cast<void*>(test_page_size*1200), test_page_size*500-1);
68 8 : BOOST_CHECK(last_lock_addr == reinterpret_cast<void*>(test_page_size*(1200+500-1)));
69 :
70 8 : BOOST_CHECK(lpm.GetLockedPageCount() == (
71 : (1000*33+test_page_size-1)/test_page_size + // small objects
72 : 101 + 100 + // page-sized objects
73 : 501 + 500)); // large objects
74 8 : BOOST_CHECK((last_lock_len & (test_page_size-1)) == 0); // always lock entire pages
75 8 : BOOST_CHECK(last_unlock_len == 0); // nothing unlocked yet
76 :
77 : /* And unlock again */
78 : addr = 0;
79 1000 : for(int i=0; i<1000; ++i)
80 : {
81 1000 : lpm.UnlockRange(reinterpret_cast<void*>(addr), 33);
82 1000 : addr += 33;
83 : }
84 : addr = test_page_size*100 + 53;
85 100 : for(int i=0; i<100; ++i)
86 : {
87 100 : lpm.UnlockRange(reinterpret_cast<void*>(addr), test_page_size);
88 100 : addr += test_page_size;
89 : }
90 : addr = test_page_size*300;
91 100 : for(int i=0; i<100; ++i)
92 : {
93 100 : lpm.UnlockRange(reinterpret_cast<void*>(addr), test_page_size);
94 100 : addr += test_page_size;
95 : }
96 1 : lpm.UnlockRange(reinterpret_cast<void*>(test_page_size*600+1), test_page_size*500);
97 1 : lpm.UnlockRange(reinterpret_cast<void*>(test_page_size*1200), test_page_size*500-1);
98 :
99 : /* Check that everything is released */
100 8 : BOOST_CHECK(lpm.GetLockedPageCount() == 0);
101 :
102 : /* A few and unlocks of size zero (should have no effect) */
103 : addr = 0;
104 1000 : for(int i=0; i<1000; ++i)
105 : {
106 1000 : lpm.LockRange(reinterpret_cast<void*>(addr), 0);
107 1000 : addr += 1;
108 : }
109 8 : BOOST_CHECK(lpm.GetLockedPageCount() == 0);
110 : addr = 0;
111 1000 : for(int i=0; i<1000; ++i)
112 : {
113 1000 : lpm.UnlockRange(reinterpret_cast<void*>(addr), 0);
114 1000 : addr += 1;
115 : }
116 8 : BOOST_CHECK(lpm.GetLockedPageCount() == 0);
117 8 : BOOST_CHECK((last_unlock_len & (test_page_size-1)) == 0); // always unlock entire pages
118 1 : }
119 :
120 3 : BOOST_AUTO_TEST_SUITE_END()
|