user_buffer_test.cpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2004-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 <algorithm>
  12. #include <vector>
  13. #include <list>
  14. #include <iostream>
  15. #include <functional>
  16. #include <boost/interprocess/managed_external_buffer.hpp>
  17. #include <boost/interprocess/managed_heap_memory.hpp>
  18. #include <boost/interprocess/containers/list.hpp>
  19. #include <boost/interprocess/detail/type_traits.hpp>
  20. #include <boost/move/detail/type_traits.hpp>
  21. #include <boost/interprocess/allocators/node_allocator.hpp>
  22. #include "print_container.hpp"
  23. /******************************************************************************/
  24. /* */
  25. /* This example constructs repeats the same operations with std::list, */
  26. /* shmem_list in user provided buffer, and shmem_list in heap memory */
  27. /* */
  28. /******************************************************************************/
  29. using namespace boost::interprocess;
  30. //We will work with wide characters for user memory objects
  31. //Alias <integer> node allocator type
  32. typedef node_allocator
  33. <int, wmanaged_external_buffer::segment_manager> user_node_allocator_t;
  34. typedef node_allocator
  35. <int, wmanaged_heap_memory::segment_manager> heap_node_allocator_t;
  36. //Alias list types
  37. typedef list<int, user_node_allocator_t> MyUserList;
  38. typedef list<int, heap_node_allocator_t> MyHeapList;
  39. typedef std::list<int> MyStdList;
  40. //Function to check if both lists are equal
  41. bool CheckEqual(MyUserList *userlist, MyStdList *stdlist, MyHeapList *heaplist)
  42. {
  43. return std::equal(userlist->begin(), userlist->end(), stdlist->begin()) &&
  44. std::equal(heaplist->begin(), heaplist->end(), stdlist->begin());
  45. }
  46. int main ()
  47. {
  48. //Create the user memory who will store all objects
  49. const int size_aligner = sizeof(::boost::container::dtl::max_align_t);
  50. const int memsize = 65536/size_aligner*size_aligner;
  51. static ::boost::container::dtl::max_align_t static_buffer[memsize/size_aligner];
  52. {
  53. //Now test move semantics
  54. managed_heap_memory original(memsize);
  55. managed_heap_memory move_ctor(boost::move(original));
  56. managed_heap_memory move_assign;
  57. move_assign = boost::move(move_ctor);
  58. original.swap(move_assign);
  59. }
  60. {
  61. //Now test move semantics
  62. managed_external_buffer original(create_only, static_buffer, memsize);
  63. managed_external_buffer move_ctor(boost::move(original));
  64. managed_external_buffer move_assign;
  65. move_assign = boost::move(move_ctor);
  66. original.swap(move_assign);
  67. }
  68. //Named new capable user mem allocator
  69. wmanaged_external_buffer user_buffer(create_only, static_buffer, memsize);
  70. //Named new capable heap mem allocator
  71. wmanaged_heap_memory heap_buffer(memsize);
  72. //Test move semantics
  73. {
  74. wmanaged_external_buffer user_default;
  75. wmanaged_external_buffer temp_external(boost::move(user_buffer));
  76. user_default = boost::move(temp_external);
  77. user_buffer = boost::move(user_default);
  78. wmanaged_heap_memory heap_default;
  79. wmanaged_heap_memory temp_heap(boost::move(heap_buffer));
  80. heap_default = boost::move(temp_heap);
  81. heap_buffer = boost::move(heap_default);
  82. }
  83. //Initialize memory
  84. user_buffer.reserve_named_objects(100);
  85. heap_buffer.reserve_named_objects(100);
  86. //User memory allocator must be always be initialized
  87. //since it has no default constructor
  88. MyUserList *userlist = user_buffer.construct<MyUserList>(L"MyUserList")
  89. (user_buffer.get_segment_manager());
  90. MyHeapList *heaplist = heap_buffer.construct<MyHeapList>(L"MyHeapList")
  91. (heap_buffer.get_segment_manager());
  92. //Alias heap list
  93. MyStdList *stdlist = new MyStdList;
  94. int i;
  95. const int max = 100;
  96. for(i = 0; i < max; ++i){
  97. userlist->push_back(i);
  98. heaplist->push_back(i);
  99. stdlist->push_back(i);
  100. }
  101. if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
  102. userlist->erase(userlist->begin()++);
  103. heaplist->erase(heaplist->begin()++);
  104. stdlist->erase(stdlist->begin()++);
  105. if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
  106. userlist->pop_back();
  107. heaplist->pop_back();
  108. stdlist->pop_back();
  109. if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
  110. userlist->pop_front();
  111. heaplist->pop_front();
  112. stdlist->pop_front();
  113. if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
  114. std::vector<int> aux_vect;
  115. #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
  116. aux_vect.assign(50, -1);
  117. userlist->assign(aux_vect.begin(), aux_vect.end());
  118. heaplist->assign(aux_vect.begin(), aux_vect.end());
  119. stdlist->assign(aux_vect.begin(), aux_vect.end());
  120. if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
  121. #endif
  122. userlist->sort();
  123. heaplist->sort();
  124. stdlist->sort();
  125. if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
  126. #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
  127. aux_vect.assign(50, 0);
  128. #endif
  129. userlist->insert(userlist->begin(), aux_vect.begin(), aux_vect.end());
  130. heaplist->insert(heaplist->begin(), aux_vect.begin(), aux_vect.end());
  131. stdlist->insert(stdlist->begin(), aux_vect.begin(), aux_vect.end());
  132. userlist->unique();
  133. heaplist->unique();
  134. stdlist->unique();
  135. if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
  136. userlist->sort(std::greater<int>());
  137. heaplist->sort(std::greater<int>());
  138. stdlist->sort(std::greater<int>());
  139. if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
  140. userlist->resize(userlist->size()/2);
  141. heaplist->resize(heaplist->size()/2);
  142. stdlist->resize(stdlist->size()/2);
  143. if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
  144. userlist->remove(*userlist->begin());
  145. heaplist->remove(*heaplist->begin());
  146. stdlist->remove(*stdlist->begin());
  147. if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
  148. for(i = 0; i < max; ++i){
  149. userlist->push_back(i);
  150. heaplist->push_back(i);
  151. stdlist->push_back(i);
  152. }
  153. MyUserList otheruserlist(*userlist);
  154. MyHeapList otherheaplist(*heaplist);
  155. MyStdList otherstdlist(*stdlist);
  156. userlist->splice(userlist->begin(), otheruserlist);
  157. heaplist->splice(heaplist->begin(), otherheaplist);
  158. stdlist->splice(stdlist->begin(), otherstdlist);
  159. if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
  160. otheruserlist = *userlist;
  161. otherheaplist = *heaplist;
  162. otherstdlist = *stdlist;
  163. userlist->sort(std::greater<int>());
  164. heaplist->sort(std::greater<int>());
  165. stdlist->sort(std::greater<int>());
  166. otheruserlist.sort(std::greater<int>());
  167. otherheaplist.sort(std::greater<int>());
  168. otherstdlist.sort(std::greater<int>());
  169. userlist->merge(otheruserlist, std::greater<int>());
  170. heaplist->merge(otherheaplist, std::greater<int>());
  171. stdlist->merge(otherstdlist, std::greater<int>());
  172. if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
  173. user_buffer.destroy<MyUserList>(L"MyUserList");
  174. delete stdlist;
  175. //Fill heap buffer until is full
  176. try{
  177. while(1){
  178. heaplist->insert(heaplist->end(), 0);
  179. }
  180. }
  181. catch(boost::interprocess::bad_alloc &){}
  182. MyHeapList::size_type heap_list_size = heaplist->size();
  183. //Copy heap buffer to another
  184. const char *insert_beg = static_cast<char*>(heap_buffer.get_address());
  185. const char *insert_end = insert_beg + heap_buffer.get_size();
  186. std::vector<char> grow_copy (insert_beg, insert_end);
  187. //Destroy old list
  188. heap_buffer.destroy<MyHeapList>(L"MyHeapList");
  189. //Resize copy buffer
  190. grow_copy.resize(memsize*2);
  191. //Open Interprocess machinery in the new managed external buffer
  192. wmanaged_external_buffer user_buffer2(open_only, &grow_copy[0], memsize);
  193. //Expand old Interprocess machinery to the new size
  194. user_buffer2.grow(memsize);
  195. //Get a pointer to the full list
  196. userlist = user_buffer2.find<MyUserList>(L"MyHeapList").first;
  197. if(!userlist){
  198. return 1;
  199. }
  200. //Fill user buffer until is full
  201. try{
  202. while(1){
  203. userlist->insert(userlist->end(), 0);
  204. }
  205. }
  206. catch(boost::interprocess::bad_alloc &){}
  207. MyUserList::size_type user_list_size = userlist->size();
  208. if(user_list_size <= heap_list_size){
  209. return 1;
  210. }
  211. user_buffer2.destroy_ptr(userlist);
  212. return 0;
  213. }
  214. #include <boost/interprocess/detail/config_end.hpp>