pool_resource_test.hpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2015-2015. Distributed under the Boost
  4. // Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/container for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. #include <boost/container/pmr/global_resource.hpp>
  11. #include <boost/core/lightweight_test.hpp>
  12. #include <boost/intrusive/detail/math.hpp>
  13. #include "derived_from_memory_resource.hpp"
  14. #include "memory_resource_logger.hpp"
  15. using namespace boost::container::pmr;
  16. template<class PoolResource>
  17. struct derived_from_pool_resource
  18. : public PoolResource
  19. {
  20. derived_from_pool_resource(const pool_options& opts, memory_resource* upstream)
  21. : PoolResource(opts, upstream)
  22. {}
  23. explicit derived_from_pool_resource(memory_resource *p)
  24. : PoolResource(p)
  25. {}
  26. explicit derived_from_pool_resource(const pool_options &opts)
  27. : PoolResource(opts)
  28. {}
  29. derived_from_pool_resource()
  30. : PoolResource()
  31. {}
  32. using PoolResource::do_allocate;
  33. using PoolResource::do_deallocate;
  34. using PoolResource::do_is_equal;
  35. };
  36. template<class PoolResource>
  37. void test_default_constructor()
  38. {
  39. //With default options/resource
  40. {
  41. derived_from_memory_resource dmr;
  42. dmr.reset();
  43. PoolResource m;
  44. //test postconditions
  45. BOOST_TEST(m.upstream_resource() == get_default_resource());
  46. BOOST_TEST(m.options().max_blocks_per_chunk == pool_options_default_max_blocks_per_chunk);
  47. BOOST_TEST(m.options().largest_required_pool_block == pool_options_default_largest_required_pool_block);
  48. //test it does not allocate any memory
  49. BOOST_TEST(dmr.do_allocate_called == false);
  50. }
  51. }
  52. template<class PoolResource>
  53. void test_upstream_constructor()
  54. {
  55. //With a resource, default options
  56. {
  57. derived_from_memory_resource dmr;
  58. dmr.reset();
  59. PoolResource m(&dmr);
  60. //test postconditions
  61. BOOST_TEST(m.upstream_resource() == &dmr);
  62. BOOST_TEST(m.options().max_blocks_per_chunk == pool_options_default_max_blocks_per_chunk);
  63. BOOST_TEST(m.options().largest_required_pool_block == pool_options_default_largest_required_pool_block);
  64. //test it does not allocate any memory
  65. BOOST_TEST(dmr.do_allocate_called == false);
  66. }
  67. }
  68. template<class PoolResource>
  69. void test_options_constructor()
  70. {
  71. //Default options
  72. {
  73. memory_resource_logger mrl;
  74. BOOST_TEST(mrl.m_info.size() == 0u);
  75. set_default_resource(&mrl);
  76. pool_options opts;
  77. PoolResource m(opts);
  78. //test postconditions
  79. BOOST_TEST(m.upstream_resource() == get_default_resource());
  80. BOOST_TEST(m.options().max_blocks_per_chunk == pool_options_default_max_blocks_per_chunk);
  81. BOOST_TEST(m.options().largest_required_pool_block == pool_options_default_largest_required_pool_block);
  82. //test it does not allocate any memory
  83. BOOST_TEST(mrl.m_info.size() == 0u);
  84. }
  85. //Too large option values
  86. {
  87. memory_resource_logger mrl;
  88. BOOST_TEST(mrl.m_info.size() == 0u);
  89. set_default_resource(&mrl);
  90. pool_options opts;
  91. opts.max_blocks_per_chunk = pool_options_default_max_blocks_per_chunk+1;
  92. opts.largest_required_pool_block = pool_options_default_largest_required_pool_block+1;
  93. PoolResource m(opts);
  94. //test postconditions
  95. BOOST_TEST(m.upstream_resource() == get_default_resource());
  96. BOOST_TEST(m.options().max_blocks_per_chunk == pool_options_default_max_blocks_per_chunk);
  97. BOOST_TEST(m.options().largest_required_pool_block == pool_options_default_largest_required_pool_block);
  98. //test it does not allocate any memory
  99. BOOST_TEST(mrl.m_info.size() == 0u);
  100. }
  101. //Too small option values
  102. {
  103. memory_resource_logger mrl;
  104. BOOST_TEST(mrl.m_info.size() == 0u);
  105. set_default_resource(&mrl);
  106. pool_options opts;
  107. opts.largest_required_pool_block = pool_options_minimum_largest_required_pool_block-1u;
  108. PoolResource m(opts);
  109. //test postconditions
  110. BOOST_TEST(m.upstream_resource() == get_default_resource());
  111. BOOST_TEST(m.options().max_blocks_per_chunk == pool_options_default_max_blocks_per_chunk);
  112. BOOST_TEST(m.options().largest_required_pool_block == pool_options_minimum_largest_required_pool_block);
  113. //test it does not allocate any memory
  114. BOOST_TEST(mrl.m_info.size() == 0u);
  115. }
  116. //In range option values
  117. {
  118. memory_resource_logger mrl;
  119. BOOST_TEST(mrl.m_info.size() == 0u);
  120. set_default_resource(&mrl);
  121. pool_options opts;
  122. opts.max_blocks_per_chunk = pool_options_default_max_blocks_per_chunk;
  123. opts.largest_required_pool_block = pool_options_minimum_largest_required_pool_block;
  124. PoolResource m(opts);
  125. //test postconditions
  126. BOOST_TEST(m.upstream_resource() == get_default_resource());
  127. BOOST_TEST(m.options().max_blocks_per_chunk == pool_options_default_max_blocks_per_chunk);
  128. BOOST_TEST(m.options().largest_required_pool_block == pool_options_minimum_largest_required_pool_block);
  129. //test it does not allocate any memory
  130. BOOST_TEST(mrl.m_info.size() == 0u);
  131. }
  132. }
  133. template<class PoolResource>
  134. void test_options_upstream_constructor()
  135. {
  136. //Default options
  137. {
  138. derived_from_memory_resource dmr;
  139. dmr.reset();
  140. pool_options opts;
  141. PoolResource m(opts, &dmr);
  142. //test postconditions
  143. BOOST_TEST(m.upstream_resource() == &dmr);
  144. BOOST_TEST(m.options().max_blocks_per_chunk == pool_options_default_max_blocks_per_chunk);
  145. BOOST_TEST(m.options().largest_required_pool_block == pool_options_default_largest_required_pool_block);
  146. //test it does not allocate any memory
  147. BOOST_TEST(dmr.do_allocate_called == false);
  148. }
  149. //Too large option values
  150. {
  151. derived_from_memory_resource dmr;
  152. dmr.reset();
  153. pool_options opts;
  154. opts.max_blocks_per_chunk = pool_options_default_max_blocks_per_chunk+1;
  155. opts.largest_required_pool_block = pool_options_default_largest_required_pool_block+1;
  156. PoolResource m(opts, &dmr);
  157. //test postconditions
  158. BOOST_TEST(m.upstream_resource() == &dmr);
  159. BOOST_TEST(m.options().max_blocks_per_chunk == pool_options_default_max_blocks_per_chunk);
  160. BOOST_TEST(m.options().largest_required_pool_block == pool_options_default_largest_required_pool_block);
  161. //test it does not allocate any memory
  162. BOOST_TEST(dmr.do_allocate_called == false);
  163. }
  164. //Too small option values
  165. {
  166. derived_from_memory_resource dmr;
  167. dmr.reset();
  168. pool_options opts;
  169. opts.largest_required_pool_block = pool_options_minimum_largest_required_pool_block-1u;
  170. PoolResource m(opts, &dmr);
  171. //test postconditions
  172. BOOST_TEST(m.upstream_resource() == &dmr);
  173. BOOST_TEST(m.options().max_blocks_per_chunk == pool_options_default_max_blocks_per_chunk);
  174. BOOST_TEST(m.options().largest_required_pool_block == pool_options_minimum_largest_required_pool_block);
  175. //test it does not allocate any memory
  176. BOOST_TEST(dmr.do_allocate_called == false);
  177. }
  178. //In range option values
  179. {
  180. derived_from_memory_resource dmr;
  181. dmr.reset();
  182. pool_options opts;
  183. opts.max_blocks_per_chunk = pool_options_default_max_blocks_per_chunk;
  184. opts.largest_required_pool_block = pool_options_minimum_largest_required_pool_block;
  185. PoolResource m(opts, &dmr);
  186. //test postconditions
  187. BOOST_TEST(m.upstream_resource() == &dmr);
  188. //max blocks is unchanged in this implementation
  189. BOOST_TEST(m.options().max_blocks_per_chunk == pool_options_default_max_blocks_per_chunk);
  190. //largest block is rounded to pow2
  191. BOOST_TEST(m.options().largest_required_pool_block == bi::detail::ceil_pow2(opts.largest_required_pool_block));
  192. //test it does not allocate any memory
  193. BOOST_TEST(dmr.do_allocate_called == false);
  194. }
  195. }
  196. template<class PoolResource>
  197. void test_options()
  198. {
  199. //In range option values
  200. {
  201. derived_from_memory_resource dmr;
  202. dmr.reset();
  203. pool_options opts;
  204. opts.max_blocks_per_chunk = pool_options_default_max_blocks_per_chunk/2u;
  205. opts.largest_required_pool_block = (pool_options_default_largest_required_pool_block
  206. - pool_options_minimum_largest_required_pool_block) | std::size_t(1); //guaranteed to be non power of 2.
  207. PoolResource m(opts, &dmr);
  208. //test postconditions
  209. BOOST_TEST(m.upstream_resource() == &dmr);
  210. //max blocks is unchanged in this implementation
  211. BOOST_TEST(m.options().max_blocks_per_chunk == opts.max_blocks_per_chunk);
  212. //largest block is rounded to pow2
  213. BOOST_TEST(m.options().largest_required_pool_block == bi::detail::ceil_pow2(opts.largest_required_pool_block));
  214. //test it does not allocate any memory
  215. BOOST_TEST(dmr.do_allocate_called == false);
  216. }
  217. }
  218. template<class PoolResource>
  219. void test_do_allocate_deallocate()
  220. {
  221. memory_resource_logger mrl;
  222. {
  223. derived_from_pool_resource<PoolResource> dmbr(&mrl);
  224. {
  225. //First block from pool 0
  226. dmbr.do_allocate(1, 1);
  227. //It should allocate the pool array plus an initial block
  228. BOOST_TEST(mrl.m_info.size() == 2u);
  229. //Second block from pool 0
  230. dmbr.do_allocate(1, 1);
  231. //It should allocate again (with 2 chunks per block)
  232. BOOST_TEST(mrl.m_info.size() == 3u);
  233. //Third block from pool 0
  234. dmbr.do_allocate(1, 1);
  235. //It should NOT allocate again (previous was a 2 block chunk)
  236. BOOST_TEST(mrl.m_info.size() == 3u);
  237. }
  238. }
  239. BOOST_TEST(mrl.m_mismatches == 0u);
  240. BOOST_TEST(mrl.m_info.size() == 0u);
  241. //Allocate and deallocate from the same chunk to test block caching
  242. {
  243. derived_from_pool_resource<PoolResource> dmbr(&mrl);
  244. {
  245. //First block from pool 0
  246. void *p = dmbr.do_allocate(1, 1);
  247. //It should allocate the pool array plus an initial block
  248. BOOST_TEST(mrl.m_info.size() == 2u);
  249. //No cached, as initial blocks per chunk is 1
  250. BOOST_TEST(dmbr.pool_cached_blocks(0u) == 0u);
  251. //Deallocate and allocate again
  252. dmbr.do_deallocate(p, 1, 1);
  253. //Cached
  254. BOOST_TEST(dmbr.pool_cached_blocks(0u) == 1u);
  255. p = dmbr.do_allocate(1, 1);
  256. //Reused
  257. BOOST_TEST(dmbr.pool_cached_blocks(0u) == 0u);
  258. //It should have NOT allocated (block reuse)
  259. BOOST_TEST(mrl.m_info.size() == 2u);
  260. //Allocate again 2 times (a 2 block chunk is exhausted)
  261. void *p2 = dmbr.do_allocate(1, 1);
  262. //1 left cached
  263. BOOST_TEST(dmbr.pool_cached_blocks(0u) == 1u);
  264. void *p3 = dmbr.do_allocate(1, 1);
  265. //Cache exhausted
  266. BOOST_TEST(dmbr.pool_cached_blocks(0u) == 0u);
  267. //Single chunk allocation happened
  268. BOOST_TEST(mrl.m_info.size() == 3u);
  269. //Now deallocate all (no memory is freed, all cached)
  270. dmbr.do_deallocate(p2, 1, 1);
  271. dmbr.do_deallocate(p3, 1, 1);
  272. dmbr.do_deallocate(p, 1, 1);
  273. BOOST_TEST(dmbr.pool_cached_blocks(0u) == 3u);
  274. BOOST_TEST(mrl.m_info.size() == 3u);
  275. }
  276. }
  277. BOOST_TEST(mrl.m_mismatches == 0u);
  278. BOOST_TEST(mrl.m_info.size() == 0u);
  279. //Now test max block per chunk
  280. {
  281. pool_options opts;
  282. //so after max_blocks_per_chunk*2-1 allocations, all new chunks must hold max_blocks_per_chunk blocks
  283. opts.max_blocks_per_chunk = 32u;
  284. derived_from_pool_resource<PoolResource> dmbr(opts, &mrl);
  285. {
  286. std::size_t loops = opts.max_blocks_per_chunk*2-1u;
  287. while(loops--){
  288. dmbr.do_allocate(1, 1);
  289. }
  290. //pool array + log2(max_blocks_per_chunk)+1 chunks (sizes [1, 2, 4, ...])
  291. const std::size_t num_chunks = bi::detail::floor_log2(opts.max_blocks_per_chunk)+1u;
  292. BOOST_TEST(mrl.m_info.size() == 1u + num_chunks);
  293. //Next allocation should allocate max_blocks_per_chunk blocks in a chunk so max_blocks_per_chunk-1 should remain free
  294. dmbr.do_allocate(1, 1);
  295. BOOST_TEST(mrl.m_info.size() == 1u + num_chunks + 1u);
  296. BOOST_TEST(dmbr.pool_cached_blocks(0u) == (opts.max_blocks_per_chunk-1u));
  297. //Exhaust the chunk and allocate a new one, test max_blocks_per_chunk is not passed again
  298. loops = opts.max_blocks_per_chunk;
  299. while(loops--){
  300. dmbr.do_allocate(1, 1);
  301. }
  302. BOOST_TEST(mrl.m_info.size() == 1u + num_chunks + 2u);
  303. BOOST_TEST(dmbr.pool_cached_blocks(0u) == (opts.max_blocks_per_chunk-1u));
  304. }
  305. }
  306. BOOST_TEST(mrl.m_mismatches == 0u);
  307. BOOST_TEST(mrl.m_info.size() == 0u);
  308. //Now test max block per chunk
  309. {
  310. pool_options opts;
  311. //so after max_blocks_per_chunk*2-1 allocations, all new chunks must hold max_blocks_per_chunk blocks
  312. opts.max_blocks_per_chunk = 32u;
  313. derived_from_pool_resource<PoolResource> dmbr(opts, &mrl);
  314. {
  315. std::size_t loops = opts.max_blocks_per_chunk*2-1u;
  316. while(loops--){
  317. dmbr.do_allocate(1, 1);
  318. }
  319. //pool array + log2(max_blocks_per_chunk)+1 chunks (sizes [1, 2, 4, ...])
  320. BOOST_TEST(dmbr.pool_next_blocks_per_chunk(0u) == opts.max_blocks_per_chunk);
  321. const std::size_t num_chunks = bi::detail::floor_log2(opts.max_blocks_per_chunk)+1u;
  322. BOOST_TEST(mrl.m_info.size() == 1u + num_chunks);
  323. //Next allocation should allocate max_blocks_per_chunk blocks in a chunk so max_blocks_per_chunk-1 should remain free
  324. dmbr.do_allocate(1, 1);
  325. BOOST_TEST(dmbr.pool_next_blocks_per_chunk(0u) == opts.max_blocks_per_chunk);
  326. BOOST_TEST(mrl.m_info.size() == 1u + num_chunks + 1u);
  327. BOOST_TEST(dmbr.pool_cached_blocks(0u) == (opts.max_blocks_per_chunk-1u));
  328. }
  329. }
  330. BOOST_TEST(mrl.m_mismatches == 0u);
  331. BOOST_TEST(mrl.m_info.size() == 0u);
  332. //Now test different pool sizes
  333. {
  334. pool_options opts;
  335. //so after max_blocks_per_chunk*2-1 allocations, all new chunks must hold max_blocks_per_chunk blocks
  336. opts.max_blocks_per_chunk = 1u;
  337. derived_from_pool_resource<PoolResource> dmbr(opts, &mrl);
  338. const pool_options &final_opts = dmbr.options();
  339. //Force pool creation
  340. dmbr.do_deallocate(dmbr.do_allocate(1, 1), 1, 1);
  341. //pool array plus first pool's chunk allocation
  342. BOOST_TEST(mrl.m_info.size() == 2u);
  343. //pool count must be:
  344. // log2(the maximum block) - log2(the minimum block) + 1. Example if minimum block is 8, and maximum 32:
  345. // log(32) - log2(8) + 1u = 3 pools (block sizes: 8, 16, and 32)
  346. const std::size_t minimum_size = dmbr.pool_block(0u);
  347. const std::size_t maximum_size = final_opts.largest_required_pool_block;
  348. BOOST_TEST(dmbr.pool_count() == (1u + bi::detail::floor_log2(maximum_size) - bi::detail::floor_log2(minimum_size)));
  349. for(std::size_t i = 0, s = minimum_size, max = dmbr.pool_count(); i != max; ++i, s*=2){
  350. //Except in the first pool, each cache should be empty
  351. BOOST_TEST(dmbr.pool_cached_blocks(i) == std::size_t(i == 0));
  352. dmbr.do_deallocate(dmbr.do_allocate(s/2+1, 1), s/2+1, 1);
  353. dmbr.do_deallocate(dmbr.do_allocate(s-1, 1), s-1, 1);
  354. dmbr.do_deallocate(dmbr.do_allocate(s, 1), s, 1);
  355. //pool array plus each previous chunk allocation
  356. BOOST_TEST(mrl.m_info.size() == (1u + i + 1u));
  357. //as we limited max_blocks_per_chunk to 1, no cached blocks should be available except one
  358. BOOST_TEST(dmbr.pool_cached_blocks(i) == 1u);
  359. }
  360. //Now test out of maximum values, which should go directly to upstream
  361. //it should be directly deallocated.
  362. void *p = dmbr.do_allocate(maximum_size+1, 1);
  363. BOOST_TEST(mrl.m_info.size() == (1u + dmbr.pool_count() + 1u));
  364. dmbr.do_deallocate(p, maximum_size+1, 1);
  365. BOOST_TEST(mrl.m_info.size() == (1u + dmbr.pool_count()));
  366. }
  367. BOOST_TEST(mrl.m_mismatches == 0u);
  368. BOOST_TEST(mrl.m_info.size() == 0u);
  369. }
  370. template<class PoolResource>
  371. void test_do_is_equal()
  372. {
  373. //`this == dynamic_cast<const PoolResource*>(&other)`.
  374. memory_resource_logger mrl;
  375. derived_from_pool_resource<PoolResource> dmbr(&mrl);
  376. derived_from_pool_resource<PoolResource> dmbr2(&mrl);
  377. BOOST_TEST(true == dmbr.do_is_equal(dmbr));
  378. BOOST_TEST(false == dmbr.do_is_equal(dmbr2));
  379. //A different type should be always different
  380. derived_from_memory_resource dmr;
  381. BOOST_TEST(false == dmbr.do_is_equal(dmr));
  382. }
  383. template<class PoolResource>
  384. void test_release()
  385. {
  386. memory_resource_logger mrl;
  387. {
  388. pool_options opts;
  389. //so after max_blocks_per_chunk*2-1 allocations, all new chunks must hold max_blocks_per_chunk blocks
  390. opts.max_blocks_per_chunk = 4u;
  391. derived_from_pool_resource<PoolResource> dmbr(opts, &mrl);
  392. const pool_options &final_opts = dmbr.options();
  393. const std::size_t minimum_size = dmbr.pool_block(0u);
  394. const std::size_t maximum_size = final_opts.largest_required_pool_block;
  395. const std::size_t pool_count = 1u + bi::detail::floor_log2(maximum_size) - bi::detail::floor_log2(minimum_size);
  396. std::size_t expected_memory_allocs = 0;
  397. for(std::size_t i = 0, imax = pool_count, s = minimum_size; i != imax; s*=2, ++i){
  398. for(std::size_t j = 0, j_max = opts.max_blocks_per_chunk*2u-1u; j != j_max; ++j){
  399. dmbr.do_allocate(s, 1);
  400. }
  401. //One due to the pool array, and for each pool, log2(max_blocks_per_chunk)+1 allocations
  402. expected_memory_allocs = 1 + (bid::floor_log2(opts.max_blocks_per_chunk) + 1u)*(i+1);
  403. //pool array plus each previous chunk allocation
  404. BOOST_TEST(mrl.m_info.size() == expected_memory_allocs);
  405. }
  406. //Now with out-of-pool sizes
  407. for(std::size_t j = 0, j_max = opts.max_blocks_per_chunk*2u-1u; j != j_max; ++j){
  408. dmbr.do_allocate(maximum_size+1, 1);
  409. BOOST_TEST(mrl.m_info.size() == ++expected_memory_allocs);
  410. }
  411. //Now release memory and check all memory allocated through do_allocate was deallocated to upstream
  412. dmbr.release();
  413. BOOST_TEST(mrl.m_info.size() == 1u);
  414. }
  415. BOOST_TEST(mrl.m_mismatches == 0u);
  416. BOOST_TEST(mrl.m_info.size() == 0u);
  417. }
  418. template<class PoolResource>
  419. void test_destructor()
  420. {
  421. memory_resource_logger mrl;
  422. {
  423. pool_options opts;
  424. //so after max_blocks_per_chunk*2-1 allocations, all new chunks must hold max_blocks_per_chunk blocks
  425. opts.max_blocks_per_chunk = 4u;
  426. derived_from_pool_resource<PoolResource> dmbr(opts, &mrl);
  427. const pool_options &final_opts = dmbr.options();
  428. const std::size_t minimum_size = dmbr.pool_block(0u);
  429. const std::size_t maximum_size = final_opts.largest_required_pool_block;
  430. const std::size_t pool_count = 1u + bi::detail::floor_log2(maximum_size) - bi::detail::floor_log2(minimum_size);
  431. std::size_t expected_memory_allocs = 0;
  432. for(std::size_t i = 0, imax = pool_count, s = minimum_size; i != imax; s*=2, ++i){
  433. for(std::size_t j = 0, j_max = opts.max_blocks_per_chunk*2u-1u; j != j_max; ++j){
  434. dmbr.do_allocate(s, 1);
  435. }
  436. //One due to the pool array, and for each pool, log2(max_blocks_per_chunk)+1 allocations
  437. expected_memory_allocs = 1 + (bid::floor_log2(opts.max_blocks_per_chunk) + 1u)*(i+1);
  438. //pool array plus each previous chunk allocation
  439. BOOST_TEST(mrl.m_info.size() == expected_memory_allocs);
  440. }
  441. //Now with out-of-pool sizes
  442. for(std::size_t j = 0, j_max = opts.max_blocks_per_chunk*2u-1u; j != j_max; ++j){
  443. dmbr.do_allocate(maximum_size+1, 1);
  444. BOOST_TEST(mrl.m_info.size() == ++expected_memory_allocs);
  445. }
  446. //Don't release, all memory, including internal allocations, should be automatically
  447. //released after the destructor is run
  448. }
  449. BOOST_TEST(mrl.m_mismatches == 0u);
  450. BOOST_TEST(mrl.m_info.size() == 0u);
  451. }
  452. template<class PoolResource>
  453. void test_pool_resource()
  454. {
  455. test_options_upstream_constructor<PoolResource>();
  456. test_default_constructor<PoolResource>();
  457. test_upstream_constructor<PoolResource>();
  458. test_options_constructor<PoolResource>();
  459. test_options<PoolResource>();
  460. test_do_allocate_deallocate<PoolResource>();
  461. test_do_is_equal<PoolResource>();
  462. test_release<PoolResource>();
  463. test_destructor<PoolResource>();
  464. }