Replace INT_MAX with INT32_MAX to avoid compile err
[novacoin.git] / src / test / allocator_tests.cpp
1 #include <boost/test/unit_test.hpp>
2
3 #include "init.h"
4 #include "main.h"
5 #include "util.h"
6
7 BOOST_AUTO_TEST_SUITE(allocator_tests)
8
9 // Dummy memory page locker for platform independent tests
10 static const void *last_lock_addr, *last_unlock_addr;
11 static size_t last_lock_len, last_unlock_len;
12 class TestLocker
13 {
14 public:
15     bool Lock(const void *addr, size_t len)
16     {
17         last_lock_addr = addr;
18         last_lock_len = len;
19         return true;
20     }
21     bool Unlock(const void *addr, size_t len)
22     {
23         last_unlock_addr = addr;
24         last_unlock_len = len;
25         return true;
26     }
27 };
28
29 BOOST_AUTO_TEST_CASE(test_LockedPageManagerBase)
30 {
31     const size_t test_page_size = 4096;
32     LockedPageManagerBase<TestLocker> lpm(test_page_size);
33     size_t addr;
34     last_lock_addr = last_unlock_addr = 0;
35     last_lock_len = last_unlock_len = 0;
36
37     /* Try large number of small objects */
38     addr = 0;
39     for(int i=0; i<1000; ++i)
40     {
41         lpm.LockRange(reinterpret_cast<void*>(addr), 33);
42         addr += 33;
43     }
44     /* Try small number of page-sized objects, straddling two pages */
45     addr = test_page_size*100 + 53;
46     for(int i=0; i<100; ++i)
47     {
48         lpm.LockRange(reinterpret_cast<void*>(addr), test_page_size);
49         addr += test_page_size;
50     }
51     /* Try small number of page-sized objects aligned to exactly one page */
52     addr = test_page_size*300;
53     for(int i=0; i<100; ++i)
54     {
55         lpm.LockRange(reinterpret_cast<void*>(addr), test_page_size);
56         addr += test_page_size;
57     }
58     /* one very large object, straddling pages */
59     lpm.LockRange(reinterpret_cast<void*>(test_page_size*600+1), test_page_size*500);
60     BOOST_CHECK(last_lock_addr == reinterpret_cast<void*>(test_page_size*(600+500)));
61     /* one very large object, page aligned */
62     lpm.LockRange(reinterpret_cast<void*>(test_page_size*1200), test_page_size*500-1);
63     BOOST_CHECK(last_lock_addr == reinterpret_cast<void*>(test_page_size*(1200+500-1)));
64
65     BOOST_CHECK(lpm.GetLockedPageCount() == (
66         (1000*33+test_page_size-1)/test_page_size + // small objects
67         101 + 100 +  // page-sized objects
68         501 + 500)); // large objects
69     BOOST_CHECK((last_lock_len & (test_page_size-1)) == 0); // always lock entire pages
70     BOOST_CHECK(last_unlock_len == 0); // nothing unlocked yet
71
72     /* And unlock again */
73     addr = 0;
74     for(int i=0; i<1000; ++i)
75     {
76         lpm.UnlockRange(reinterpret_cast<void*>(addr), 33);
77         addr += 33;
78     }
79     addr = test_page_size*100 + 53;
80     for(int i=0; i<100; ++i)
81     {
82         lpm.UnlockRange(reinterpret_cast<void*>(addr), test_page_size);
83         addr += test_page_size;
84     }
85     addr = test_page_size*300;
86     for(int i=0; i<100; ++i)
87     {
88         lpm.UnlockRange(reinterpret_cast<void*>(addr), test_page_size);
89         addr += test_page_size;
90     }
91     lpm.UnlockRange(reinterpret_cast<void*>(test_page_size*600+1), test_page_size*500);
92     lpm.UnlockRange(reinterpret_cast<void*>(test_page_size*1200), test_page_size*500-1);
93
94     /* Check that everything is released */
95     BOOST_CHECK(lpm.GetLockedPageCount() == 0);
96
97     /* A few and unlocks of size zero (should have no effect) */
98     addr = 0;
99     for(int i=0; i<1000; ++i)
100     {
101         lpm.LockRange(reinterpret_cast<void*>(addr), 0);
102         addr += 1;
103     }
104     BOOST_CHECK(lpm.GetLockedPageCount() == 0);
105     addr = 0;
106     for(int i=0; i<1000; ++i)
107     {
108         lpm.UnlockRange(reinterpret_cast<void*>(addr), 0);
109         addr += 1;
110     }
111     BOOST_CHECK(lpm.GetLockedPageCount() == 0);
112     BOOST_CHECK((last_unlock_len & (test_page_size-1)) == 0); // always unlock entire pages
113 }
114
115 BOOST_AUTO_TEST_SUITE_END()