• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 2000, 2001 Stephen Cleary
2 * Copyright (C) 2011 Kwan Ting Chan
3 *
4 * Use, modification and distribution is subject to the
5 * Boost Software License, Version 1.0. (See accompanying
6 * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
7 */
8 
9 #ifndef BOOST_POOL_TEST_SIMP_SEG_STORE_HPP
10 #define BOOST_POOL_TEST_SIMP_SEG_STORE_HPP
11 
12 #include <boost/pool/simple_segregated_storage.hpp>
13 #include <boost/assert.hpp>
14 
15 #include <boost/detail/lightweight_test.hpp>
16 
17 #include <functional>
18 #include <set>
19 #include <utility>
20 #include <vector>
21 
22 #include <cstddef>
23 
24 class test_simp_seg_store : public boost::simple_segregated_storage<std::size_t>
25 {
26 private:
27     // ::first is the address of the start of the added block,
28     //  ::second is the size in bytes of the added block
29     std::vector<std::pair<void*, std::size_t> > allocated_blocks;
30     size_type np_sz;
31     std::set<void*> allocated_chunks;
32 
set_partition_size(const size_type sz)33     void set_partition_size(const size_type sz)
34     {
35         if(allocated_blocks.empty())
36         {
37             np_sz = sz;
38         }
39         else
40         {
41             BOOST_ASSERT(np_sz == sz);
42         }
43     }
44 
45     // Return: true if chunk is from added blocks, false otherwise
is_inside_allocated_blocks(void * const chunk) const46     bool is_inside_allocated_blocks(void* const chunk) const
47     {
48         typedef std::vector<std::pair<void*, std::size_t> >::const_iterator
49             VPIter;
50         for(VPIter iter = allocated_blocks.begin();
51             iter != allocated_blocks.end();
52             ++iter)
53         {
54             if( std::less_equal<void*>()(iter->first, chunk)
55                 && std::less_equal<void*>()(static_cast<char*>(chunk) + np_sz,
56                     static_cast<char*>(iter->first) + iter->second) )
57             {
58                 return true;
59             }
60         }
61 
62         return false;
63     }
64 
check_in(void * const chunk)65     void check_in(void* const chunk)
66     {
67         // Check that the newly allocated chunk has not already previously
68         //  been allocated, and that the memory does not overlap with
69         //  previously allocated chunks
70         for(std::set<void*>::const_iterator iter = allocated_chunks.begin();
71             iter != allocated_chunks.end();
72             ++iter)
73         {
74             BOOST_TEST( std::less_equal<void*>()(static_cast<char*>(chunk)
75                 + np_sz, *iter)
76                 || std::less_equal<void*>()(static_cast<char*>(*iter)
77                 + np_sz, chunk) );
78         }
79 
80         allocated_chunks.insert(chunk);
81     }
82 
check_out(void * const chunk)83     void check_out(void* const chunk)
84     {
85         BOOST_TEST(allocated_chunks.erase(chunk) == 1);
86     }
87 
88 public:
test_simp_seg_store()89     test_simp_seg_store()
90         : np_sz(0) {}
91 
get_first()92     void* get_first() { return first; }
get_nextof(void * const ptr)93     static void*& get_nextof(void* const ptr) { return nextof(ptr); }
94 
95     // (Test) Pre: npartition_sz of all added block is the same
96     //             different blocks of memory does not overlap
add_block(void * const block,const size_type nsz,const size_type npartition_sz)97     void add_block(void* const block,
98         const size_type nsz, const size_type npartition_sz)
99     {
100         set_partition_size(npartition_sz);
101         allocated_blocks.push_back(
102             std::pair<void*, std::size_t>(block, nsz) );
103         boost::simple_segregated_storage<std::size_t>::add_block(
104             block, nsz, npartition_sz );
105         // Post: !empty()
106         BOOST_TEST(!empty());
107     }
108 
109     // (Test) Pre: npartition_sz of all added block is the same
110     //             different blocks of memory does not overlap
add_ordered_block(void * const block,const size_type nsz,const size_type npartition_sz)111     void add_ordered_block(void* const block,
112         const size_type nsz, const size_type npartition_sz)
113     {
114         set_partition_size(npartition_sz);
115         allocated_blocks.push_back(
116             std::pair<void*, std::size_t>(block, nsz) );
117         boost::simple_segregated_storage<std::size_t>::add_ordered_block(
118             block, nsz, npartition_sz );
119         // Post: !empty()
120         BOOST_TEST(!empty());
121     }
122 
malloc()123     void* malloc()
124     {
125         void* const ret
126             = boost::simple_segregated_storage<std::size_t>::malloc();
127         // Chunk returned should actually be from added blocks
128         BOOST_TEST(is_inside_allocated_blocks(ret));
129         check_in(ret);
130         return ret;
131     }
132 
free(void * const chunk)133     void free(void* const chunk)
134     {
135         BOOST_ASSERT(chunk);
136         check_out(chunk);
137         boost::simple_segregated_storage<std::size_t>::free(chunk);
138         // Post: !empty()
139         BOOST_TEST(!empty());
140     }
141 
ordered_free(void * const chunk)142     void ordered_free(void* const chunk)
143     {
144         BOOST_ASSERT(chunk);
145         check_out(chunk);
146         boost::simple_segregated_storage<std::size_t>::ordered_free(chunk);
147         // Post: !empty()
148         BOOST_TEST(!empty());
149     }
150 
malloc_n(size_type n,size_type partition_size)151     void* malloc_n(size_type n, size_type partition_size)
152     {
153         void* const ret
154             = boost::simple_segregated_storage<std::size_t>::malloc_n(
155                 n, partition_size );
156 
157         if(ret)
158         {
159             for(std::size_t i=0; i < n; ++i)
160             {
161                 void* const chunk = static_cast<char*>(ret)
162                     + (i * partition_size);
163                 // Memory returned should actually be from added blocks
164                 BOOST_TEST(is_inside_allocated_blocks(chunk));
165                 check_in(chunk);
166             }
167         }
168 
169         return ret;
170     }
171 };
172 
173 #endif // BOOST_POOL_TEST_SIMP_SEG_STORE_HPP
174