node_pool_test.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2007-2012. 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/interprocess for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. #include <boost/interprocess/detail/config_begin.hpp>
  11. #include <boost/interprocess/managed_shared_memory.hpp>
  12. #include <boost/interprocess/smart_ptr/unique_ptr.hpp>
  13. #include <boost/interprocess/smart_ptr/deleter.hpp>
  14. #include <boost/interprocess/detail/type_traits.hpp>
  15. #include <vector>
  16. #include <cstddef>
  17. #include <string>
  18. #include "get_process_id_name.hpp"
  19. namespace boost {
  20. namespace interprocess {
  21. namespace test {
  22. template <class NodePool>
  23. struct test_node_pool
  24. {
  25. static bool allocate_then_deallocate(NodePool &pool);
  26. static bool deallocate_free_blocks(NodePool &pool);
  27. };
  28. template <class NodePool>
  29. bool test_node_pool<NodePool>::allocate_then_deallocate(NodePool &pool)
  30. {
  31. const typename NodePool::size_type num_alloc = 1 + 3*pool.get_real_num_node();
  32. std::vector<void*> nodes;
  33. //Precondition, the pool must be empty
  34. if(0 != pool.num_free_nodes()){
  35. return false;
  36. }
  37. //First allocate nodes
  38. for(std::size_t i = 0; i < num_alloc; ++i){
  39. nodes.push_back(pool.allocate_node());
  40. }
  41. //Check that the free count is correct
  42. if((pool.get_real_num_node() - 1) != pool.num_free_nodes()){
  43. return false;
  44. }
  45. //Now deallocate all and check again
  46. for(std::size_t i = 0; i < num_alloc; ++i){
  47. pool.deallocate_node(nodes[i]);
  48. }
  49. //Check that the free count is correct
  50. if(4*pool.get_real_num_node() != pool.num_free_nodes()){
  51. return false;
  52. }
  53. pool.deallocate_free_blocks();
  54. if(0 != pool.num_free_nodes()){
  55. return false;
  56. }
  57. return true;
  58. }
  59. template <class NodePool>
  60. bool test_node_pool<NodePool>::deallocate_free_blocks(NodePool &pool)
  61. {
  62. const std::size_t max_blocks = 10;
  63. const std::size_t max_nodes = max_blocks*pool.get_real_num_node();
  64. const std::size_t nodes_per_block = pool.get_real_num_node();
  65. std::vector<void*> nodes;
  66. //Precondition, the pool must be empty
  67. if(0 != pool.num_free_nodes()){
  68. return false;
  69. }
  70. //First allocate nodes
  71. for(std::size_t i = 0; i < max_nodes; ++i){
  72. nodes.push_back(pool.allocate_node());
  73. }
  74. //Check that the free count is correct
  75. if(0 != pool.num_free_nodes()){
  76. return false;
  77. }
  78. //Now deallocate one of each block per iteration
  79. for(std::size_t node_i = 0; node_i < nodes_per_block; ++node_i){
  80. //Deallocate a node per block
  81. for(std::size_t i = 0; i < max_blocks; ++i){
  82. pool.deallocate_node(nodes[i*nodes_per_block + node_i]);
  83. }
  84. //Check that the free count is correct
  85. if(max_blocks*(node_i+1) != pool.num_free_nodes()){
  86. return false;
  87. }
  88. //Now try to deallocate free blocks
  89. pool.deallocate_free_blocks();
  90. //Until we don't deallocate the last node of every block
  91. //no node should be deallocated
  92. if(node_i != (nodes_per_block - 1)){
  93. if(max_blocks*(node_i+1) != pool.num_free_nodes()){
  94. return false;
  95. }
  96. }
  97. else{
  98. //If this is the last iteration, all the memory should
  99. //have been deallocated.
  100. if(0 != pool.num_free_nodes()){
  101. return false;
  102. }
  103. }
  104. }
  105. return true;
  106. }
  107. template<class node_pool_t>
  108. bool test_all_node_pool()
  109. {
  110. using namespace boost::interprocess;
  111. typedef managed_shared_memory::segment_manager segment_manager;
  112. typedef boost::interprocess::test::test_node_pool<node_pool_t> test_node_pool_t;
  113. shared_memory_object::remove(test::get_process_id_name());
  114. {
  115. managed_shared_memory shm(create_only, test::get_process_id_name(), 4*1024*sizeof(segment_manager::void_pointer));
  116. typedef deleter<node_pool_t, segment_manager> deleter_t;
  117. typedef unique_ptr<node_pool_t, deleter_t> unique_ptr_t;
  118. //Delete the pool when the tests end
  119. unique_ptr_t p
  120. (shm.construct<node_pool_t>(anonymous_instance)(shm.get_segment_manager())
  121. ,deleter_t(shm.get_segment_manager()));
  122. //Now call each test
  123. if(!test_node_pool_t::allocate_then_deallocate(*p))
  124. return false;
  125. if(!test_node_pool_t::deallocate_free_blocks(*p))
  126. return false;
  127. }
  128. shared_memory_object::remove(test::get_process_id_name());
  129. return true;
  130. }
  131. } //namespace test {
  132. } //namespace interprocess {
  133. } //namespace boost {
  134. #include <boost/interprocess/detail/config_end.hpp>