alloc_full_test.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2007-2013. 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. #ifdef _MSC_VER
  11. #pragma warning (disable:4702)
  12. #endif
  13. #include <vector>
  14. #include <iostream>
  15. #include <cstring>
  16. #include <algorithm> //std::remove
  17. #include <boost/container/detail/dlmalloc.hpp>
  18. namespace boost { namespace container { namespace test {
  19. static const int NumIt = 200;
  20. enum deallocation_type { DirectDeallocation, InverseDeallocation, MixedDeallocation, EndDeallocationType };
  21. //This test allocates until there is no more memory
  22. //and after that deallocates all in the inverse order
  23. bool test_allocation()
  24. {
  25. if(!dlmalloc_all_deallocated())
  26. return false;
  27. dlmalloc_malloc_check();
  28. for( deallocation_type t = DirectDeallocation
  29. ; t != EndDeallocationType
  30. ; t = (deallocation_type)((int)t + 1)){
  31. std::vector<void*> buffers;
  32. //std::size_t free_memory = a.get_free_memory();
  33. for(int i = 0; i != NumIt; ++i){
  34. void *ptr = dlmalloc_malloc(i);
  35. if(!ptr)
  36. break;
  37. buffers.push_back(ptr);
  38. }
  39. switch(t){
  40. case DirectDeallocation:
  41. {
  42. for(int j = 0, max = (int)buffers.size()
  43. ;j < max
  44. ;++j){
  45. dlmalloc_free(buffers[j]);
  46. }
  47. }
  48. break;
  49. case InverseDeallocation:
  50. {
  51. for(int j = (int)buffers.size()
  52. ;j--
  53. ;){
  54. dlmalloc_free(buffers[j]);
  55. }
  56. }
  57. break;
  58. case MixedDeallocation:
  59. {
  60. for(int j = 0, max = (int)buffers.size()
  61. ;j < max
  62. ;++j){
  63. int pos = (j%4)*((int)buffers.size())/4;
  64. dlmalloc_free(buffers[pos]);
  65. buffers.erase(buffers.begin()+pos);
  66. }
  67. }
  68. break;
  69. default:
  70. break;
  71. }
  72. if(!dlmalloc_all_deallocated())
  73. return false;
  74. //bool ok = free_memory == a.get_free_memory() &&
  75. //a.all_memory_deallocated() && a.check_sanity();
  76. //if(!ok) return ok;
  77. }
  78. dlmalloc_malloc_check();
  79. return 0 != dlmalloc_all_deallocated();
  80. }
  81. //This test allocates until there is no more memory
  82. //and after that tries to shrink all the buffers to the
  83. //half of the original size
  84. bool test_allocation_shrink()
  85. {
  86. dlmalloc_malloc_check();
  87. std::vector<void*> buffers;
  88. //Allocate buffers with extra memory
  89. for(int i = 0; i != NumIt; ++i){
  90. void *ptr = dlmalloc_malloc(i*2);
  91. if(!ptr)
  92. break;
  93. buffers.push_back(ptr);
  94. }
  95. //Now shrink to half
  96. for(int i = 0, max = (int)buffers.size()
  97. ;i < max
  98. ; ++i){
  99. std::size_t try_received_size = 0;
  100. void* try_result = dlmalloc_allocation_command
  101. ( BOOST_CONTAINER_TRY_SHRINK_IN_PLACE, 1, i*2
  102. , i, &try_received_size, (char*)buffers[i]).first;
  103. std::size_t received_size = 0;
  104. void* result = dlmalloc_allocation_command
  105. ( BOOST_CONTAINER_SHRINK_IN_PLACE, 1, i*2
  106. , i, &received_size, (char*)buffers[i]).first;
  107. if(result != try_result)
  108. return false;
  109. if(received_size != try_received_size)
  110. return false;
  111. if(result){
  112. if(received_size > std::size_t(i*2)){
  113. return false;
  114. }
  115. if(received_size < std::size_t(i)){
  116. return false;
  117. }
  118. }
  119. }
  120. //Deallocate it in non sequential order
  121. for(int j = 0, max = (int)buffers.size()
  122. ;j < max
  123. ;++j){
  124. int pos = (j%4)*((int)buffers.size())/4;
  125. dlmalloc_free(buffers[pos]);
  126. buffers.erase(buffers.begin()+pos);
  127. }
  128. dlmalloc_malloc_check();
  129. return 0 != dlmalloc_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
  130. }
  131. //This test allocates until there is no more memory
  132. //and after that tries to expand all the buffers to
  133. //avoid the wasted internal fragmentation
  134. bool test_allocation_expand()
  135. {
  136. dlmalloc_malloc_check();
  137. std::vector<void*> buffers;
  138. //Allocate buffers with extra memory
  139. for(int i = 0; i != NumIt; ++i){
  140. void *ptr = dlmalloc_malloc(i);
  141. if(!ptr)
  142. break;
  143. buffers.push_back(ptr);
  144. }
  145. //Now try to expand to the double of the size
  146. for(int i = 0, max = (int)buffers.size()
  147. ;i < max
  148. ;++i){
  149. std::size_t received_size = 0;
  150. std::size_t min_size = i+1;
  151. std::size_t preferred_size = i*2;
  152. preferred_size = min_size > preferred_size ? min_size : preferred_size;
  153. while(dlmalloc_allocation_command
  154. ( BOOST_CONTAINER_EXPAND_FWD, 1, min_size
  155. , preferred_size, &received_size, (char*)buffers[i]).first){
  156. //Check received size is bigger than minimum
  157. if(received_size < min_size){
  158. return false;
  159. }
  160. //Now, try to expand further
  161. min_size = received_size+1;
  162. preferred_size = min_size*2;
  163. }
  164. }
  165. //Deallocate it in non sequential order
  166. for(int j = 0, max = (int)buffers.size()
  167. ;j < max
  168. ;++j){
  169. int pos = (j%4)*((int)buffers.size())/4;
  170. dlmalloc_free(buffers[pos]);
  171. buffers.erase(buffers.begin()+pos);
  172. }
  173. dlmalloc_malloc_check();
  174. return 0 != dlmalloc_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
  175. }
  176. //This test allocates until there is no more memory
  177. //and after that tries to expand all the buffers to
  178. //avoid the wasted internal fragmentation
  179. bool test_allocation_shrink_and_expand()
  180. {
  181. std::vector<void*> buffers;
  182. std::vector<std::size_t> received_sizes;
  183. std::vector<bool> size_reduced;
  184. //Allocate buffers wand store received sizes
  185. for(int i = 0; i != NumIt; ++i){
  186. std::size_t received_size = 0;
  187. void *ptr = dlmalloc_allocation_command
  188. (BOOST_CONTAINER_ALLOCATE_NEW, 1, i, i*2, &received_size, 0).first;
  189. if(!ptr){
  190. ptr = dlmalloc_allocation_command
  191. ( BOOST_CONTAINER_ALLOCATE_NEW, 1, 1, i*2, &received_size, 0).first;
  192. if(!ptr)
  193. break;
  194. }
  195. buffers.push_back(ptr);
  196. received_sizes.push_back(received_size);
  197. }
  198. //Now shrink to half
  199. for(int i = 0, max = (int)buffers.size()
  200. ; i < max
  201. ; ++i){
  202. std::size_t received_size = 0;
  203. bool size_reduced_flag;
  204. if(true == (size_reduced_flag = !!
  205. dlmalloc_allocation_command
  206. ( BOOST_CONTAINER_SHRINK_IN_PLACE, 1, received_sizes[i]
  207. , i, &received_size, (char*)buffers[i]).first)){
  208. if(received_size > std::size_t(received_sizes[i])){
  209. return false;
  210. }
  211. if(received_size < std::size_t(i)){
  212. return false;
  213. }
  214. }
  215. size_reduced.push_back(size_reduced_flag);
  216. }
  217. //Now try to expand to the original size
  218. for(int i = 0, max = (int)buffers.size()
  219. ;i < max
  220. ;++i){
  221. if(!size_reduced[i]) continue;
  222. std::size_t received_size = 0;
  223. std::size_t request_size = received_sizes[i];
  224. if(dlmalloc_allocation_command
  225. ( BOOST_CONTAINER_EXPAND_FWD, 1, request_size
  226. , request_size, &received_size, (char*)buffers[i]).first){
  227. if(received_size != request_size){
  228. return false;
  229. }
  230. }
  231. else{
  232. return false;
  233. }
  234. }
  235. //Deallocate it in non sequential order
  236. for(int j = 0, max = (int)buffers.size()
  237. ;j < max
  238. ;++j){
  239. int pos = (j%4)*((int)buffers.size())/4;
  240. dlmalloc_free(buffers[pos]);
  241. buffers.erase(buffers.begin()+pos);
  242. }
  243. return 0 != dlmalloc_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
  244. }
  245. //This test allocates until there is no more memory
  246. //and after that deallocates the odd buffers to
  247. //make room for expansions. The expansion will probably
  248. //success since the deallocation left room for that.
  249. bool test_allocation_deallocation_expand()
  250. {
  251. dlmalloc_malloc_check();
  252. std::vector<void*> buffers;
  253. //Allocate buffers with extra memory
  254. for(int i = 0; i != NumIt; ++i){
  255. void *ptr = dlmalloc_malloc(i);
  256. if(!ptr)
  257. break;
  258. buffers.push_back(ptr);
  259. }
  260. //Now deallocate the half of the blocks
  261. //so expand maybe can merge new free blocks
  262. for(int i = 0, max = (int)buffers.size()
  263. ;i < max
  264. ;++i){
  265. if(i%2){
  266. dlmalloc_free(buffers[i]);
  267. buffers[i] = 0;
  268. }
  269. }
  270. //Now try to expand to the double of the size
  271. for(int i = 0, max = (int)buffers.size()
  272. ;i < max
  273. ;++i){
  274. //
  275. if(buffers[i]){
  276. std::size_t received_size = 0;
  277. std::size_t min_size = i+1;
  278. std::size_t preferred_size = i*2;
  279. preferred_size = min_size > preferred_size ? min_size : preferred_size;
  280. while(dlmalloc_allocation_command
  281. ( BOOST_CONTAINER_EXPAND_FWD, 1, min_size
  282. , preferred_size, &received_size, (char*)buffers[i]).first){
  283. //Check received size is bigger than minimum
  284. if(received_size < min_size){
  285. return false;
  286. }
  287. //Now, try to expand further
  288. min_size = received_size+1;
  289. preferred_size = min_size*2;
  290. }
  291. }
  292. }
  293. //Now erase null values from the vector
  294. buffers.erase(std::remove(buffers.begin(), buffers.end(), (void*)0)
  295. ,buffers.end());
  296. //Deallocate it in non sequential order
  297. for(int j = 0, max = (int)buffers.size()
  298. ;j < max
  299. ;++j){
  300. int pos = (j%4)*((int)buffers.size())/4;
  301. dlmalloc_free(buffers[pos]);
  302. buffers.erase(buffers.begin()+pos);
  303. }
  304. dlmalloc_malloc_check();
  305. return 0 != dlmalloc_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
  306. }
  307. //This test allocates until there is no more memory
  308. //and after that deallocates all except the last.
  309. //If the allocation algorithm is a bottom-up algorithm
  310. //the last buffer will be in the end of the segment.
  311. //Then the test will start expanding backwards, until
  312. //the buffer fills all the memory
  313. bool test_allocation_with_reuse()
  314. {
  315. dlmalloc_malloc_check();
  316. //We will repeat this test for different sized elements
  317. for(int sizeof_object = 1; sizeof_object < 20; ++sizeof_object){
  318. std::vector<void*> buffers;
  319. //Allocate buffers with extra memory
  320. for(int i = 0; i != NumIt; ++i){
  321. void *ptr = dlmalloc_malloc(i*sizeof_object);
  322. if(!ptr)
  323. break;
  324. buffers.push_back(ptr);
  325. }
  326. //Now deallocate all except the latest
  327. //Now try to expand to the double of the size
  328. for(int i = 0, max = (int)buffers.size() - 1
  329. ;i < max
  330. ;++i){
  331. dlmalloc_free(buffers[i]);
  332. }
  333. //Save the unique buffer and clear vector
  334. void *ptr = buffers.back();
  335. buffers.clear();
  336. //Now allocate with reuse
  337. std::size_t received_size = 0;
  338. for(int i = 0; i != NumIt; ++i){
  339. std::size_t min_size = (received_size/sizeof_object + 1)*sizeof_object;
  340. std::size_t prf_size = (received_size/sizeof_object + (i+1)*2)*sizeof_object;
  341. dlmalloc_command_ret_t ret = dlmalloc_allocation_command
  342. ( BOOST_CONTAINER_EXPAND_BWD, sizeof_object, min_size
  343. , prf_size, &received_size, (char*)ptr);
  344. //If we have memory, this must be a buffer reuse
  345. if(!ret.first)
  346. break;
  347. //If we have memory, this must be a buffer reuse
  348. if(!ret.second)
  349. return false;
  350. if(received_size < min_size)
  351. return false;
  352. ptr = ret.first;
  353. }
  354. //There should be only a single block so deallocate it
  355. dlmalloc_free(ptr);
  356. dlmalloc_malloc_check();
  357. if(!dlmalloc_all_deallocated())
  358. return false;
  359. }
  360. return true;
  361. }
  362. //This test allocates memory with different alignments
  363. //and checks returned memory is aligned.
  364. bool test_aligned_allocation()
  365. {
  366. dlmalloc_malloc_check();
  367. //Allocate aligned buffers in a loop
  368. //and then deallocate it
  369. for(unsigned int i = 1; i != (1 << (sizeof(int)/2)); i <<= 1){
  370. for(unsigned int j = 1; j != 512; j <<= 1){
  371. void *ptr = dlmalloc_memalign(i-1, j);
  372. if(!ptr){
  373. return false;
  374. }
  375. if(((std::size_t)ptr & (j - 1)) != 0)
  376. return false;
  377. dlmalloc_free(ptr);
  378. //if(!a.all_memory_deallocated() || !a.check_sanity()){
  379. // return false;
  380. //}
  381. }
  382. }
  383. dlmalloc_malloc_check();
  384. return 0 != dlmalloc_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
  385. }
  386. //This test allocates memory with different alignments
  387. //and checks returned memory is aligned.
  388. bool test_continuous_aligned_allocation()
  389. {
  390. dlmalloc_malloc_check();
  391. std::vector<void*> buffers;
  392. //Allocate aligned buffers in a loop
  393. //and then deallocate it
  394. bool continue_loop = true;
  395. unsigned int MaxAlign = 4096;
  396. unsigned int MaxSize = 4096;
  397. for(unsigned i = 1; i < MaxSize; i <<= 1){
  398. for(unsigned int j = 1; j < MaxAlign; j <<= 1){
  399. for(int k = 0; k != NumIt; ++k){
  400. void *ptr = dlmalloc_memalign(i-1, j);
  401. buffers.push_back(ptr);
  402. if(!ptr){
  403. continue_loop = false;
  404. break;
  405. }
  406. if(((std::size_t)ptr & (j - 1)) != 0)
  407. return false;
  408. }
  409. //Deallocate all
  410. for(int k = (int)buffers.size(); k--;){
  411. dlmalloc_free(buffers[k]);
  412. }
  413. buffers.clear();
  414. //if(!a.all_memory_deallocated() && a.check_sanity())
  415. // return false;
  416. if(!continue_loop)
  417. break;
  418. }
  419. }
  420. dlmalloc_malloc_check();
  421. return 0 != dlmalloc_all_deallocated();//a.all_memory_deallocated() && a.check_sanity();
  422. }
  423. //This test allocates multiple values until there is no more memory
  424. //and after that deallocates all in the inverse order
  425. bool test_many_equal_allocation()
  426. {
  427. dlmalloc_malloc_check();
  428. for( deallocation_type t = DirectDeallocation
  429. ; t != EndDeallocationType
  430. ; t = (deallocation_type)((int)t + 1)){
  431. //std::size_t free_memory = a.get_free_memory();
  432. std::vector<void*> buffers2;
  433. //Allocate buffers with extra memory
  434. for(int i = 0; i != NumIt; ++i){
  435. void *ptr = dlmalloc_malloc(i);
  436. if(!ptr)
  437. break;
  438. //if(!a.check_sanity())
  439. //return false;
  440. buffers2.push_back(ptr);
  441. }
  442. //Now deallocate the half of the blocks
  443. //so expand maybe can merge new free blocks
  444. for(int i = 0, max = (int)buffers2.size()
  445. ;i < max
  446. ;++i){
  447. if(i%2){
  448. dlmalloc_free(buffers2[i]);
  449. buffers2[i] = 0;
  450. }
  451. }
  452. //if(!a.check_sanity())
  453. //return false;
  454. std::vector<void*> buffers;
  455. for(int i = 0; i != NumIt/10; ++i){
  456. dlmalloc_memchain chain;
  457. BOOST_CONTAINER_MEMCHAIN_INIT(&chain);
  458. dlmalloc_multialloc_nodes((i+1)*2, i+1, DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
  459. dlmalloc_memchain_it it = BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(&chain);
  460. if(BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it))
  461. break;
  462. std::size_t n = 0;
  463. for(; !BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it); ++n){
  464. buffers.push_back(BOOST_CONTAINER_MEMIT_ADDR(it));
  465. BOOST_CONTAINER_MEMIT_NEXT(it);
  466. }
  467. if(n != std::size_t((i+1)*2))
  468. return false;
  469. }
  470. //if(!a.check_sanity())
  471. //return false;
  472. switch(t){
  473. case DirectDeallocation:
  474. {
  475. for(int j = 0, max = (int)buffers.size()
  476. ;j < max
  477. ;++j){
  478. dlmalloc_free(buffers[j]);
  479. }
  480. }
  481. break;
  482. case InverseDeallocation:
  483. {
  484. for(int j = (int)buffers.size()
  485. ;j--
  486. ;){
  487. dlmalloc_free(buffers[j]);
  488. }
  489. }
  490. break;
  491. case MixedDeallocation:
  492. {
  493. for(int j = 0, max = (int)buffers.size()
  494. ;j < max
  495. ;++j){
  496. int pos = (j%4)*((int)buffers.size())/4;
  497. dlmalloc_free(buffers[pos]);
  498. buffers.erase(buffers.begin()+pos);
  499. }
  500. }
  501. break;
  502. default:
  503. break;
  504. }
  505. //Deallocate the rest of the blocks
  506. //Deallocate it in non sequential order
  507. for(int j = 0, max = (int)buffers2.size()
  508. ;j < max
  509. ;++j){
  510. int pos = (j%4)*((int)buffers2.size())/4;
  511. dlmalloc_free(buffers2[pos]);
  512. buffers2.erase(buffers2.begin()+pos);
  513. }
  514. //bool ok = free_memory == a.get_free_memory() &&
  515. //a.all_memory_deallocated() && a.check_sanity();
  516. //if(!ok) return ok;
  517. }
  518. dlmalloc_malloc_check();
  519. return 0 != dlmalloc_all_deallocated();
  520. }
  521. //This test allocates multiple values until there is no more memory
  522. //and after that deallocates all in the inverse order
  523. bool test_many_different_allocation()
  524. {
  525. dlmalloc_malloc_check();
  526. const std::size_t ArraySize = 11;
  527. std::size_t requested_sizes[ArraySize];
  528. for(std::size_t i = 0; i < ArraySize; ++i){
  529. requested_sizes[i] = 4*i;
  530. }
  531. for( deallocation_type t = DirectDeallocation
  532. ; t != EndDeallocationType
  533. ; t = (deallocation_type)((int)t + 1)){
  534. //std::size_t free_memory = a.get_free_memory();
  535. std::vector<void*> buffers2;
  536. //Allocate buffers with extra memory
  537. for(int i = 0; i != NumIt; ++i){
  538. void *ptr = dlmalloc_malloc(i);
  539. if(!ptr)
  540. break;
  541. buffers2.push_back(ptr);
  542. }
  543. //Now deallocate the half of the blocks
  544. //so expand maybe can merge new free blocks
  545. for(int i = 0, max = (int)buffers2.size()
  546. ;i < max
  547. ;++i){
  548. if(i%2){
  549. dlmalloc_free(buffers2[i]);
  550. buffers2[i] = 0;
  551. }
  552. }
  553. std::vector<void*> buffers;
  554. for(int i = 0; i != NumIt; ++i){
  555. dlmalloc_memchain chain;
  556. BOOST_CONTAINER_MEMCHAIN_INIT(&chain);
  557. dlmalloc_multialloc_arrays(ArraySize, requested_sizes, 1, DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
  558. dlmalloc_memchain_it it = BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(&chain);
  559. if(BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it))
  560. break;
  561. std::size_t n = 0;
  562. for(; !BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it); ++n){
  563. buffers.push_back(BOOST_CONTAINER_MEMIT_ADDR(it));
  564. BOOST_CONTAINER_MEMIT_NEXT(it);
  565. }
  566. if(n != ArraySize)
  567. return false;
  568. }
  569. switch(t){
  570. case DirectDeallocation:
  571. {
  572. for(int j = 0, max = (int)buffers.size()
  573. ;j < max
  574. ;++j){
  575. dlmalloc_free(buffers[j]);
  576. }
  577. }
  578. break;
  579. case InverseDeallocation:
  580. {
  581. for(int j = (int)buffers.size()
  582. ;j--
  583. ;){
  584. dlmalloc_free(buffers[j]);
  585. }
  586. }
  587. break;
  588. case MixedDeallocation:
  589. {
  590. for(int j = 0, max = (int)buffers.size()
  591. ;j < max
  592. ;++j){
  593. int pos = (j%4)*((int)buffers.size())/4;
  594. dlmalloc_free(buffers[pos]);
  595. buffers.erase(buffers.begin()+pos);
  596. }
  597. }
  598. break;
  599. default:
  600. break;
  601. }
  602. //Deallocate the rest of the blocks
  603. //Deallocate it in non sequential order
  604. for(int j = 0, max = (int)buffers2.size()
  605. ;j < max
  606. ;++j){
  607. int pos = (j%4)*((int)buffers2.size())/4;
  608. dlmalloc_free(buffers2[pos]);
  609. buffers2.erase(buffers2.begin()+pos);
  610. }
  611. //bool ok = free_memory == a.get_free_memory() &&
  612. //a.all_memory_deallocated() && a.check_sanity();
  613. //if(!ok) return ok;
  614. }
  615. dlmalloc_malloc_check();
  616. return 0 != dlmalloc_all_deallocated();
  617. }
  618. bool test_many_deallocation()
  619. {
  620. const std::size_t ArraySize = 11;
  621. std::vector<dlmalloc_memchain> buffers;
  622. std::size_t requested_sizes[ArraySize];
  623. for(std::size_t i = 0; i < ArraySize; ++i){
  624. requested_sizes[i] = 4*i;
  625. }
  626. for(int i = 0; i != NumIt; ++i){
  627. dlmalloc_memchain chain;
  628. BOOST_CONTAINER_MEMCHAIN_INIT(&chain);
  629. dlmalloc_multialloc_arrays(ArraySize, requested_sizes, 1, DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
  630. dlmalloc_memchain_it it = BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(&chain);
  631. if(BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it))
  632. return false;
  633. buffers.push_back(chain);
  634. }
  635. for(int i = 0; i != NumIt; ++i){
  636. dlmalloc_multidealloc(&buffers[i]);
  637. }
  638. buffers.clear();
  639. dlmalloc_malloc_check();
  640. if(!dlmalloc_all_deallocated())
  641. return false;
  642. for(int i = 0; i != NumIt; ++i){
  643. dlmalloc_memchain chain;
  644. BOOST_CONTAINER_MEMCHAIN_INIT(&chain);
  645. dlmalloc_multialloc_nodes(ArraySize, i*4+1, DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
  646. dlmalloc_memchain_it it = BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(&chain);
  647. if(BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it))
  648. return false;
  649. buffers.push_back(chain);
  650. }
  651. for(int i = 0; i != NumIt; ++i){
  652. dlmalloc_multidealloc(&buffers[i]);
  653. }
  654. buffers.clear();
  655. dlmalloc_malloc_check();
  656. if(!dlmalloc_all_deallocated())
  657. return false;
  658. return true;
  659. }
  660. //This function calls all tests
  661. bool test_all_allocation()
  662. {
  663. std::cout << "Starting test_allocation"
  664. << std::endl;
  665. if(!test_allocation()){
  666. std::cout << "test_allocation_direct_deallocation failed"
  667. << std::endl;
  668. return false;
  669. }
  670. std::cout << "Starting test_many_equal_allocation"
  671. << std::endl;
  672. if(!test_many_equal_allocation()){
  673. std::cout << "test_many_equal_allocation failed"
  674. << std::endl;
  675. return false;
  676. }
  677. std::cout << "Starting test_many_different_allocation"
  678. << std::endl;
  679. if(!test_many_different_allocation()){
  680. std::cout << "test_many_different_allocation failed"
  681. << std::endl;
  682. return false;
  683. }
  684. std::cout << "Starting test_allocation_shrink"
  685. << std::endl;
  686. if(!test_allocation_shrink()){
  687. std::cout << "test_allocation_shrink failed"
  688. << std::endl;
  689. return false;
  690. }
  691. if(!test_allocation_shrink_and_expand()){
  692. std::cout << "test_allocation_shrink_and_expand failed"
  693. << std::endl;
  694. return false;
  695. }
  696. std::cout << "Starting test_allocation_expand"
  697. << std::endl;
  698. if(!test_allocation_expand()){
  699. std::cout << "test_allocation_expand failed"
  700. << std::endl;
  701. return false;
  702. }
  703. std::cout << "Starting test_allocation_deallocation_expand"
  704. << std::endl;
  705. if(!test_allocation_deallocation_expand()){
  706. std::cout << "test_allocation_deallocation_expand failed"
  707. << std::endl;
  708. return false;
  709. }
  710. std::cout << "Starting test_allocation_with_reuse"
  711. << std::endl;
  712. if(!test_allocation_with_reuse()){
  713. std::cout << "test_allocation_with_reuse failed"
  714. << std::endl;
  715. return false;
  716. }
  717. std::cout << "Starting test_aligned_allocation"
  718. << std::endl;
  719. if(!test_aligned_allocation()){
  720. std::cout << "test_aligned_allocation failed"
  721. << std::endl;
  722. return false;
  723. }
  724. std::cout << "Starting test_continuous_aligned_allocation"
  725. << std::endl;
  726. if(!test_continuous_aligned_allocation()){
  727. std::cout << "test_continuous_aligned_allocation failed"
  728. << std::endl;
  729. return false;
  730. }
  731. if(!test_many_deallocation()){
  732. std::cout << "test_many_deallocation failed"
  733. << std::endl;
  734. return false;
  735. }
  736. return 0 != dlmalloc_all_deallocated();
  737. }
  738. }}} //namespace boost { namespace container { namespace test {
  739. int main()
  740. {
  741. if(!boost::container::test::test_all_allocation())
  742. return 1;
  743. return 0;
  744. }