heap.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
  1. /**
  2. \example test/heap.c
  3. */
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include "lub/heap.h"
  7. #include "lub/test.h"
  8. /*************************************************************
  9. * TEST CODE
  10. ************************************************************* */
  11. int testseq = 0;
  12. /*
  13. * This is the main entry point for this executable
  14. */
  15. #define SIZEOF_HEAP_T (140)
  16. #define SIZEOF_ALLOC_BLOCK_T ( 8)
  17. #define SIZEOF_NODE_T ( 20)
  18. #define SIZEOF_CONTEXT_T (104)
  19. #define RAW_SIZE (SIZEOF_HEAP_T + 132)
  20. /* allow space to assign a leak detection context */
  21. #define ACTUAL_SIZE (RAW_SIZE)
  22. char segment1[ACTUAL_SIZE];
  23. char segment2[ACTUAL_SIZE*4];
  24. #define LARGE_SIZE 1024 * 400
  25. char large_seg[LARGE_SIZE];
  26. #define MIN_ALLOC 12
  27. typedef struct test_node_s test_node_t;
  28. struct test_node_s
  29. {
  30. test_node_t *next;
  31. };
  32. static test_node_t *first_node;
  33. /*--------------------------------------------------------- */
  34. /*
  35. * Returns a pseudo random number based on the input.
  36. * This will given 2^15 concequtive numbers generate the entire
  37. * number space in a psedo random manner.
  38. */
  39. static int
  40. random(int i)
  41. {
  42. /* multiply the first prime after 2^14 and mask to 15 bits */
  43. return (16411*i) & (32767);
  44. }
  45. /*--------------------------------------------------------- */
  46. static void
  47. create_nodes(lub_heap_t *heap,
  48. int count)
  49. {
  50. test_node_t *node;
  51. int i;
  52. lub_test_seq_log(LUB_TEST_NORMAL,"Create % random sized blocks",count);
  53. first_node = NULL;
  54. for(i = 0; i < count; i++)
  55. {
  56. union
  57. {
  58. test_node_t **node_ptr;
  59. char **char_ptr;
  60. } tmp;
  61. /* pick a random size upto 400 bytes */
  62. size_t size = 1 + 400 * random(i) / 32768;
  63. node = NULL;
  64. tmp.node_ptr = &node;
  65. lub_heap_realloc(heap,tmp.char_ptr,size,LUB_HEAP_ALIGN_NATIVE);
  66. if(NULL != node)
  67. {
  68. /* put this into the linked list for later */
  69. node->next = first_node;
  70. first_node = node;
  71. }
  72. else
  73. {
  74. lub_test_seq_log(LUB_TEST_NORMAL,"ONLY MANAGED TO CREATE %d BLOCKS",i);
  75. break;
  76. }
  77. }
  78. lub_test_seq_log(LUB_TEST_NORMAL,"Dump the details...");
  79. lub_heap_show(heap,BOOL_TRUE);
  80. }
  81. /*--------------------------------------------------------- */
  82. static void
  83. test_performance(void)
  84. {
  85. lub_heap_t *heap;
  86. lub_test_seq_begin(++testseq,"Check the performance...");
  87. heap = lub_heap_create(large_seg,sizeof(large_seg));
  88. lub_test_check(NULL != heap,"Check creation of 400KB heap");
  89. create_nodes(heap,1000);
  90. lub_test_seq_log(LUB_TEST_NORMAL,"Now free every other node...");
  91. {
  92. test_node_t **ptr;
  93. int i = 0;
  94. for(ptr = &first_node;
  95. *ptr;
  96. i++,ptr = &(*ptr)->next)
  97. {
  98. if(i % 2)
  99. {
  100. char *tmp = (char*)*ptr;
  101. /* remove from the linked list */
  102. *ptr = (*ptr)->next;
  103. /* and free the node */
  104. lub_heap_realloc(heap,&tmp,0,LUB_HEAP_ALIGN_NATIVE);
  105. }
  106. }
  107. }
  108. lub_test_seq_log(LUB_TEST_NORMAL,"Dump the details...");
  109. lub_heap_show(heap,BOOL_TRUE);
  110. create_nodes(heap,500);
  111. lub_heap_destroy(heap);
  112. lub_test_seq_end();
  113. }
  114. /*--------------------------------------------------------- */
  115. static void
  116. test_stats_check(lub_heap_t *this)
  117. {
  118. lub_heap_stats_t stats;
  119. unsigned total_memory,used_memory;
  120. lub_heap__get_stats(this,&stats);
  121. total_memory = stats.segs_bytes
  122. - stats.static_bytes;
  123. used_memory = stats.free_bytes
  124. + stats.free_overhead
  125. + stats.alloc_bytes
  126. + stats.alloc_overhead;
  127. lub_test_check_int(total_memory,used_memory,
  128. "Check that the (segs_bytes - static_bytes) equals the free and allocated bytes + overheads");
  129. if(total_memory != used_memory)
  130. {
  131. lub_heap_show(this,BOOL_TRUE);
  132. }
  133. }
  134. /*--------------------------------------------------------- */
  135. static void
  136. test_taint_check(char *ptr,size_t size)
  137. {
  138. bool_t tainted = BOOL_TRUE;
  139. if(ptr && (LUB_HEAP_ZERO_ALLOC != ptr))
  140. {
  141. while(size--)
  142. {
  143. if((unsigned char)*ptr != 0xaa)
  144. {
  145. tainted = BOOL_FALSE;
  146. break;
  147. }
  148. }
  149. }
  150. lub_test_check(tainted,"Check memory has been tainted");
  151. }
  152. /*--------------------------------------------------------- */
  153. void
  154. test_main(unsigned frame_count)
  155. {
  156. lub_heap_t *heap;
  157. char *tmp;
  158. char *ptr1 = NULL;
  159. char *ptr2 = NULL;
  160. char *ptr3 = NULL;
  161. lub_heap_status_t result;
  162. lub_heap_stats_t stats;
  163. size_t actual_size = RAW_SIZE;
  164. if(frame_count)
  165. {
  166. actual_size = ACTUAL_SIZE;
  167. }
  168. /*----------------------------------------------------- */
  169. lub_test_seq_begin(++testseq,"lub_heap_create(segment1,%d)",actual_size);
  170. heap = lub_heap_create(segment1,actual_size);
  171. lub_test_check(NULL != heap,"Check heap created correctly");
  172. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  173. test_stats_check(heap);
  174. lub_test_seq_log(LUB_TEST_NORMAL,"Configured to collect %d frames for leak detection",frame_count);
  175. lub_heap__set_framecount(frame_count);
  176. lub_heap__get_stats(heap,&stats);
  177. lub_test_check_int(1,stats.free_blocks,"Check the number of free blocks");
  178. lub_test_seq_end();
  179. /*----------------------------------------------------- */
  180. lub_test_seq_begin(++testseq,"lub_heap_add_segment(segment2,%d)",actual_size*2);
  181. lub_heap_add_segment(heap,segment2,actual_size*2);
  182. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  183. test_stats_check(heap);
  184. lub_heap__get_stats(heap,&stats);
  185. lub_test_check_int(1,stats.free_blocks,"Check the two adjacent segments get merged");
  186. lub_test_seq_end();
  187. /*----------------------------------------------------- */
  188. lub_test_seq_begin(++testseq,"lub_heap_static_alloc(heap,10)");
  189. tmp = lub_heap_static_alloc(heap,10);
  190. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  191. lub_test_check(NULL != tmp,"Check static allocation works");
  192. test_taint_check(tmp,12);
  193. test_stats_check(heap);
  194. lub_heap__get_stats(heap,&stats);
  195. lub_test_check_int(1,stats.static_blocks,"Check the number of static blocks");
  196. lub_test_check_int(12,stats.static_bytes,"Check static_bytes has gone up");
  197. if (tmp)
  198. memset(tmp,0x11,10);
  199. lub_test_seq_end();
  200. /*----------------------------------------------------- */
  201. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr1,10,LUB_HEAP_ALIGN_NATIVE)");
  202. result = lub_heap_realloc(heap,&ptr1,10,LUB_HEAP_ALIGN_NATIVE);
  203. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  204. lub_test_check(LUB_HEAP_OK == result,"Check dynamic allocation says it works");
  205. lub_test_check(NULL != ptr1,"Check dynamic allocation actually works");
  206. test_taint_check(ptr1,10);
  207. test_stats_check(heap);
  208. lub_heap__get_stats(heap,&stats);
  209. lub_test_check_int(1,stats.alloc_blocks,"Check the number of dynamic blocks");
  210. lub_test_check_int(MIN_ALLOC,stats.alloc_bytes,"Check alloc bytes has gone up");
  211. if(ptr1)
  212. memset(ptr1,0x22,10);
  213. lub_test_seq_end();
  214. /*----------------------------------------------------- */
  215. lub_test_seq_begin(++testseq,"lub_heap_static_alloc(heap,10)");
  216. tmp = lub_heap_static_alloc(heap,10);
  217. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  218. lub_test_check(NULL != tmp,"Check static allocation works");
  219. test_taint_check(tmp,10);
  220. test_stats_check(heap);
  221. lub_heap__get_stats(heap,&stats);
  222. lub_test_check_int(2,stats.static_blocks,"Check the number of static blocks");
  223. lub_test_check_int(2*MIN_ALLOC,stats.static_bytes,"Check static bytes has gone up");
  224. if(tmp)
  225. memset(tmp,0x33,10);
  226. lub_test_seq_end();
  227. /*----------------------------------------------------- */
  228. lub_test_seq_begin(++testseq,"lub_heap_static_alloc(heap,200)");
  229. tmp = lub_heap_static_alloc(heap,200);
  230. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  231. lub_test_check(NULL != tmp,"Check static allocation from second segment works");
  232. test_taint_check(tmp,200);
  233. test_stats_check(heap);
  234. lub_heap__get_stats(heap,&stats);
  235. lub_test_check_int(3,stats.static_blocks,"Check the number of static blocks");
  236. lub_test_check_int(200+2*MIN_ALLOC,stats.static_bytes,"Check static_bytes has gone up");
  237. if(tmp)
  238. memset(tmp,0x99,200);
  239. lub_test_seq_end();
  240. /*----------------------------------------------------- */
  241. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr1,30,LUB_HEAP_ALIGN_NATIVE)");
  242. tmp = ptr1;
  243. result = lub_heap_realloc(heap,&ptr1,30,LUB_HEAP_ALIGN_NATIVE);
  244. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  245. lub_test_check(LUB_HEAP_OK == result,"Check growing an allocation works");
  246. lub_test_check(ptr1 == tmp,"Check growing an allocation keeps the same pointer");
  247. test_taint_check(ptr1+10,20);
  248. test_stats_check(heap);
  249. lub_heap__get_stats(heap,&stats);
  250. lub_test_check_int(1,stats.alloc_blocks,"Check the number of dynamic blocks");
  251. lub_test_check_int(20 + MIN_ALLOC,stats.alloc_bytes,"Check alloc bytes has gone up");
  252. if(ptr1)
  253. memset(ptr1,0x44,30);
  254. lub_test_seq_end();
  255. /*----------------------------------------------------- */
  256. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr1,30,LUB_HEAP_ALIGN_NATIVE)");
  257. tmp = ptr1;
  258. result = lub_heap_realloc(heap,&ptr1,30,LUB_HEAP_ALIGN_NATIVE);
  259. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  260. lub_test_check(LUB_HEAP_OK == result,"Check asking for the same size works");
  261. lub_test_check(ptr1 == tmp,"Check it keeps the same pointer");
  262. test_stats_check(heap);
  263. lub_heap__get_stats(heap,&stats);
  264. lub_test_check_int(1,stats.alloc_blocks,"Check the number of dynamic blocks");
  265. lub_test_check_int(20+MIN_ALLOC,stats.alloc_bytes,"Check alloc bytes");
  266. lub_test_seq_end();
  267. /*----------------------------------------------------- */
  268. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr1,4,LUB_HEAP_ALIGN_NATIVE)");
  269. tmp = ptr1;
  270. result = lub_heap_realloc(heap,&ptr1,4,LUB_HEAP_ALIGN_NATIVE);
  271. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  272. lub_test_check(LUB_HEAP_OK == result,"Check shrinking an allocation works");
  273. lub_test_check(ptr1 == tmp,"Check shrinking an allocation retains pointer");
  274. test_taint_check(ptr1+4,MIN_ALLOC-4);
  275. test_stats_check(heap);
  276. lub_heap__get_stats(heap,&stats);
  277. lub_test_check_int(1,stats.alloc_blocks,"Check the number of dynamic blocks");
  278. if(ptr1)
  279. memset(ptr1,0x55,4);
  280. lub_test_seq_end();
  281. /*----------------------------------------------------- */
  282. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr1,100,LUB_HEAP_ALIGN_NATIVE)");
  283. tmp = ptr1;
  284. result = lub_heap_realloc(heap,&ptr1,104,LUB_HEAP_ALIGN_NATIVE);
  285. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  286. lub_test_check(LUB_HEAP_OK == result,"Check growing and moving works");
  287. lub_test_check(ptr1 != tmp,"Check growing and moving changes the pointer");
  288. test_taint_check(ptr1+4,100);
  289. test_stats_check(heap);
  290. lub_heap__get_stats(heap,&stats);
  291. lub_test_check_int(1,stats.alloc_blocks,"Check the number of dynamic blocks");
  292. if(ptr1)
  293. memset(ptr1,0x55,100);
  294. lub_test_seq_end();
  295. /*----------------------------------------------------- */
  296. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr1,0,LUB_HEAP_ALIGN_NATIVE)");
  297. tmp = ptr1;
  298. result = lub_heap_realloc(heap,&ptr1,0,LUB_HEAP_ALIGN_NATIVE);
  299. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  300. lub_test_check(LUB_HEAP_OK == result,"Check releasing an allocation says it works");
  301. lub_test_check(LUB_HEAP_ZERO_ALLOC == ptr1,"Check releasing an allocation actually works");
  302. test_stats_check(heap);
  303. lub_heap__get_stats(heap,&stats);
  304. lub_test_check_int(0,stats.alloc_blocks,"Check the number of dynamic blocks");
  305. lub_test_check(BOOL_TRUE == lub_heap_check_memory(heap),"Check integrity of heap");
  306. lub_test_seq_end();
  307. /*----------------------------------------------------- */
  308. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr1,20,LUB_HEAP_ALIGN_NATIVE)");
  309. /* now test with multiple dynamic blocks to exercise different recovery mechanisms */
  310. result = lub_heap_realloc(heap,&ptr1,20,LUB_HEAP_ALIGN_NATIVE);
  311. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  312. lub_test_check(LUB_HEAP_OK == result,"Check dynamic allocation (1) says it works");
  313. lub_test_check(NULL != ptr1,"Check dynamic allocation (1) actually works");
  314. test_taint_check(ptr1,20);
  315. test_stats_check(heap);
  316. if(ptr1)
  317. memset(ptr1,0x66,20);
  318. lub_test_seq_end();
  319. /*----------------------------------------------------- */
  320. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr2,20,LUB_HEAP_ALIGN_NATIVE)");
  321. result = lub_heap_realloc(heap,&ptr2,30,LUB_HEAP_ALIGN_NATIVE);
  322. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  323. lub_test_check(LUB_HEAP_OK == result,"Check dynamic allocation (2) says it works");
  324. lub_test_check(NULL != ptr2,"Check dynamic allocation (2) actually works");
  325. test_taint_check(ptr2,32);
  326. test_stats_check(heap);
  327. if(ptr2)
  328. memset(ptr2,0x77,20);
  329. lub_test_seq_end();
  330. /*----------------------------------------------------- */
  331. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr3,1,LUB_HEAP_ALIGN_NATIVE)");
  332. result = lub_heap_realloc(heap,&ptr3,1,LUB_HEAP_ALIGN_NATIVE);
  333. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  334. lub_test_check(LUB_HEAP_OK == result,"Check dynamic allocation (3) says it works");
  335. lub_test_check(NULL != ptr3,"Check dynamic allocation (3) actually works");
  336. test_taint_check(ptr3,8);
  337. test_stats_check(heap);
  338. if(ptr3)
  339. memset(ptr3,0x88,1);
  340. lub_heap__get_stats(heap,&stats);
  341. lub_test_check_int(3,stats.alloc_blocks,"Check the number of dynamic blocks");
  342. lub_test_check_int(3,stats.static_blocks,"Check the number static blocks");
  343. lub_test_check_int(1,stats.free_blocks,"Check the number of free blocks");
  344. lub_test_check_int(60,stats.alloc_bytes,"Check alloc bytes has gone up");
  345. lub_test_seq_end();
  346. /*----------------------------------------------------- */
  347. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr2,8,LUB_HEAP_ALIGN_NATIVE)");
  348. /* shrink the second block to create a new free block */
  349. tmp = ptr2;
  350. result = lub_heap_realloc(heap,&ptr2,8,LUB_HEAP_ALIGN_NATIVE);
  351. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  352. lub_test_check(LUB_HEAP_OK == result,"Check shrinking (2) says it works");
  353. lub_test_check(tmp == ptr2,"Check shrinking (2) maintains the pointer");
  354. test_stats_check(heap);
  355. lub_heap__get_stats(heap,&stats);
  356. lub_test_check_int(3,stats.alloc_blocks,"Check the number of dynamic blocks");
  357. lub_test_check_int(2,stats.free_blocks,"Check the number of free blocks");
  358. lub_test_seq_end();
  359. /*----------------------------------------------------- */
  360. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr2,0,LUB_HEAP_ALIGN_NATIVE)");
  361. /* release the second block to cause fragmentation */
  362. tmp = ptr2;
  363. result = lub_heap_realloc(heap,&ptr2,0,LUB_HEAP_ALIGN_NATIVE);
  364. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  365. lub_test_check(LUB_HEAP_OK == result,"Check releasing an allocation (2) says it works");
  366. lub_test_check(LUB_HEAP_ZERO_ALLOC == ptr2,"Check releasing an allocation (2) actually works");
  367. test_stats_check(heap);
  368. lub_heap__get_stats(heap,&stats);
  369. lub_test_check_int(2,stats.alloc_blocks,"Check the number of dynamic blocks");
  370. lub_test_check_int(2,stats.free_blocks,"Check the number of free blocks");
  371. lub_test_seq_end();
  372. /*----------------------------------------------------- */
  373. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr2,0,LUB_HEAP_ALIGN_NATIVE)");
  374. /* deliberatly double free the memory */
  375. ptr2 = tmp;
  376. result = lub_heap_realloc(heap,&ptr2,0,LUB_HEAP_ALIGN_NATIVE);
  377. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  378. lub_test_check(LUB_HEAP_DOUBLE_FREE == result,"Check double free is spotted");
  379. lub_test_check(tmp == ptr2,"Check pointer hasn't changed.");
  380. test_stats_check(heap);
  381. ptr2 = NULL;
  382. lub_heap__get_stats(heap,&stats);
  383. lub_test_check_int(2,stats.alloc_blocks,"Check the number of dynamic blocks");
  384. lub_test_check_int(2,stats.free_blocks,"Check the number of free blocks");
  385. lub_test_seq_end();
  386. /*----------------------------------------------------- */
  387. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr1,24,LUB_HEAP_ALIGN_NATIVE)");
  388. /* extend the lower block */
  389. tmp = ptr1;
  390. result = lub_heap_realloc(heap,&ptr1,24,LUB_HEAP_ALIGN_NATIVE);
  391. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  392. lub_test_check(LUB_HEAP_OK == result,"Check growing allocation (1) says it works");
  393. lub_test_check(NULL != ptr1,"Check growing allocation (1) actually works");
  394. lub_test_check(tmp == ptr1,"Check growing allocation (1) didn't move block");
  395. test_taint_check(ptr1+20,4);
  396. test_stats_check(heap);
  397. lub_heap__get_stats(heap,&stats);
  398. lub_test_check_int(2,stats.alloc_blocks,"Check the number of dynamic blocks");
  399. lub_test_check_int(2,stats.free_blocks,"Check the number of free blocks");
  400. lub_test_seq_end();
  401. /*----------------------------------------------------- */
  402. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr1,48,LUB_HEAP_ALIGN_NATIVE)");
  403. /* extend the lower block to absorb the free block */
  404. tmp = ptr1;
  405. result = lub_heap_realloc(heap,&ptr1,48,LUB_HEAP_ALIGN_NATIVE);
  406. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  407. lub_test_check(LUB_HEAP_OK == result,"Check growing allocation (1) says it works");
  408. lub_test_check(NULL != ptr1,"Check growing allocation (1) actually works");
  409. lub_test_check(tmp == ptr1,"Check growing allocation (1) didn't move block");
  410. test_taint_check(ptr1+20,16);
  411. test_stats_check(heap);
  412. lub_heap__get_stats(heap,&stats);
  413. lub_test_check_int(2,stats.alloc_blocks,"Check the number of dynamic blocks");
  414. lub_test_check_int(1,stats.free_blocks,"Check the number of free blocks");
  415. lub_test_seq_end();
  416. /*----------------------------------------------------- */
  417. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr1,0,LUB_HEAP_ALIGN_NATIVE)");
  418. /* release the lower block */
  419. tmp = ptr1;
  420. result = lub_heap_realloc(heap,&ptr1,0,LUB_HEAP_ALIGN_NATIVE);
  421. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  422. lub_test_check(LUB_HEAP_OK == result,"Check releasing (1) says it works");
  423. lub_test_check(LUB_HEAP_ZERO_ALLOC == ptr1,"Check releasing memory (1) actually works");
  424. test_stats_check(heap);
  425. lub_heap__get_stats(heap,&stats);
  426. lub_test_check_int(1,stats.alloc_blocks,"Check the number of dynamic blocks");
  427. lub_test_check_int(2,stats.free_blocks,"Check the number of free blocks");
  428. lub_test_seq_end();
  429. /*----------------------------------------------------- */
  430. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr3,0,LUB_HEAP_ALIGN_NATIVE)");
  431. /* release the upper block */
  432. tmp = ptr3;
  433. result = lub_heap_realloc(heap,&ptr3,0,LUB_HEAP_ALIGN_NATIVE);
  434. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  435. lub_test_check(LUB_HEAP_OK == result,"Check releasing (3) says it works");
  436. lub_test_check(LUB_HEAP_ZERO_ALLOC == ptr3,"Check releasing memory (3) actually works");
  437. test_stats_check(heap);
  438. lub_heap__get_stats(heap,&stats);
  439. lub_test_check_int(0,stats.alloc_blocks,"Check the number of dynamic blocks");
  440. lub_test_check_int(1,stats.free_blocks,"Check the number of free blocks");
  441. lub_test_seq_end();
  442. /*----------------------------------------------------- */
  443. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr1,12,LUB_HEAP_ALIGN_NATIVE)");
  444. /* now test extending blocks downwards */
  445. result = lub_heap_realloc(heap,&ptr1,12,LUB_HEAP_ALIGN_NATIVE);
  446. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  447. lub_test_check(LUB_HEAP_OK == result,"Check allocation (1) says it works");
  448. lub_test_check(NULL != ptr1,"Check allocation memory (1) actually works");
  449. test_stats_check(heap);
  450. lub_heap__get_stats(heap,&stats);
  451. lub_test_check_int(1,stats.alloc_blocks,"Check the number of dynamic blocks");
  452. lub_test_check_int(1,stats.free_blocks,"Check the number of free blocks");
  453. lub_test_seq_end();
  454. /*----------------------------------------------------- */
  455. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr2,12,LUB_HEAP_ALIGN_NATIVE)");
  456. /* now test extending blocks downwards */
  457. result = lub_heap_realloc(heap,&ptr2,12,LUB_HEAP_ALIGN_NATIVE);
  458. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  459. lub_test_check(LUB_HEAP_OK == result,"Check allocation (2) says it works");
  460. lub_test_check(NULL != ptr2,"Check allocation memory (2) actually works");
  461. test_stats_check(heap);
  462. lub_heap__get_stats(heap,&stats);
  463. lub_test_check_int(2,stats.alloc_blocks,"Check the number of dynamic blocks");
  464. lub_test_check_int(1,stats.free_blocks,"Check the number of free blocks");
  465. lub_test_seq_end();
  466. /*----------------------------------------------------- */
  467. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr3,12,LUB_HEAP_ALIGN_NATIVE)");
  468. /* now test extending blocks downwards */
  469. result = lub_heap_realloc(heap,&ptr3,12,LUB_HEAP_ALIGN_NATIVE);
  470. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  471. lub_test_check(LUB_HEAP_OK == result,"Check allocation (1) says it works");
  472. lub_test_check(NULL != ptr3,"Check allocation memory (1) actually works");
  473. test_stats_check(heap);
  474. lub_heap__get_stats(heap,&stats);
  475. lub_test_check_int(3,stats.alloc_blocks,"Check the number of dynamic blocks");
  476. lub_test_check_int(1,stats.free_blocks,"Check the number of free blocks");
  477. lub_test_seq_end();
  478. /*----------------------------------------------------- */
  479. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr1,0,LUB_HEAP_ALIGN_NATIVE)");
  480. /* release the lower block */
  481. tmp = ptr1;
  482. result = lub_heap_realloc(heap,&ptr1,0,LUB_HEAP_ALIGN_NATIVE);
  483. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  484. lub_test_check(LUB_HEAP_OK == result,"Check releasing (1) says it works");
  485. lub_test_check(LUB_HEAP_ZERO_ALLOC == ptr1,"Check releasing memory (1) actually works");
  486. test_stats_check(heap);
  487. lub_heap__get_stats(heap,&stats);
  488. lub_test_check_int(2,stats.alloc_blocks,"Check the number of dynamic blocks");
  489. lub_test_check_int(2,stats.free_blocks,"Check the number of free blocks");
  490. lub_test_seq_end();
  491. /*----------------------------------------------------- */
  492. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr2,16,LUB_HEAP_ALIGN_NATIVE)");
  493. /* now extend the middle block (downwards) */
  494. tmp = ptr2;
  495. result = lub_heap_realloc(heap,&ptr2,16,LUB_HEAP_ALIGN_NATIVE);
  496. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  497. lub_test_check(LUB_HEAP_OK == result,"Check extending downwards (2) says it works");
  498. lub_test_check(tmp != ptr2,"Check extending downwards (2) changes pointer");
  499. test_stats_check(heap);
  500. lub_heap__get_stats(heap,&stats);
  501. lub_test_check_int(2,stats.alloc_blocks,"Check the number of dynamic blocks");
  502. lub_test_check_int(1,stats.free_blocks,"Check the number of free blocks");
  503. lub_test_seq_end();
  504. /*----------------------------------------------------- */
  505. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr2,20,LUB_HEAP_ALIGN_NATIVE)");
  506. /* now extend the middle block (downwards) */
  507. tmp = ptr2;
  508. result = lub_heap_realloc(heap,&ptr2,20,LUB_HEAP_ALIGN_NATIVE);
  509. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  510. lub_test_check(LUB_HEAP_OK == result,"Check extending downwards (2) says it works");
  511. lub_test_check(tmp != ptr2,"Check extending downwards (2) changes pointer");
  512. test_stats_check(heap);
  513. lub_heap__get_stats(heap,&stats);
  514. lub_test_check_int(2,stats.alloc_blocks,"Check the number of dynamic blocks");
  515. lub_test_check_int(2,stats.free_blocks,"Check the number of free blocks");
  516. lub_test_seq_end();
  517. /*----------------------------------------------------- */
  518. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr2,0,LUB_HEAP_ALIGN_NATIVE)");
  519. /* now set the pointer to NULL */
  520. ptr2 = NULL;
  521. result = lub_heap_realloc(heap,&ptr2,0,LUB_HEAP_ALIGN_NATIVE);
  522. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  523. lub_test_check(LUB_HEAP_OK == result,"Check that releasing NULL and allocating nothing says it works");
  524. lub_test_check(LUB_HEAP_ZERO_ALLOC == ptr2,"Check pointer is LUB_HEAP_ALLOC_ZERO");
  525. test_stats_check(heap);
  526. lub_heap__get_stats(heap,&stats);
  527. lub_test_check_int(2,stats.alloc_blocks,"Check the number of dynamic blocks");
  528. lub_test_check_int(1,stats.free_blocks,"Check the number of free blocks");
  529. lub_test_seq_end();
  530. /*----------------------------------------------------- */
  531. lub_test_seq_begin(++testseq,"lub_heap_realloc(heap,&ptr2,-1,LUB_HEAP_ALIGN_NATIVE)");
  532. result = lub_heap_realloc(heap,&ptr2,-1,LUB_HEAP_ALIGN_NATIVE);
  533. lub_test_check(lub_heap_check_memory(heap),"Check integrity of heap");
  534. lub_test_check(LUB_HEAP_FAILED == result,"Check that allocating large size near 2^32 fails");
  535. lub_test_check(NULL == ptr2,"Check pointer is unchanged");
  536. test_stats_check(heap);
  537. lub_heap__get_stats(heap,&stats);
  538. lub_test_check_int(2,stats.alloc_blocks,"Check the number of dynamic blocks");
  539. lub_test_check_int(1,stats.free_blocks,"Check the number of free blocks");
  540. lub_test_seq_end();
  541. /*----------------------------------------------------- */
  542. lub_test_seq_begin(++testseq,"lub_heap_show()");
  543. lub_heap_show(heap,BOOL_TRUE);
  544. lub_test_seq_end();
  545. /*----------------------------------------------------- */
  546. lub_test_seq_begin(++testseq,"lub_heap_show()");
  547. lub_heap_show(heap,BOOL_TRUE);
  548. lub_test_seq_end();
  549. /*----------------------------------------------------- */
  550. lub_test_seq_begin(++testseq,"lub_heap_show_leaks()");
  551. lub_heap_leak_report(LUB_HEAP_SHOW_ALL,"");
  552. lub_test_seq_end();
  553. /*----------------------------------------------------- */
  554. test_performance();
  555. /*----------------------------------------------------- */
  556. lub_test_seq_begin(++testseq,"lub_heap_destroy()");
  557. lub_heap_destroy(heap);
  558. lub_test_seq_end();
  559. /*----------------------------------------------------- */
  560. }
  561. /*--------------------------------------------------------- */
  562. int
  563. main(int argc, const char *argv[])
  564. {
  565. int status;
  566. lub_heap_init(argv[0]);
  567. lub_test_parse_command_line(argc,argv);
  568. lub_test_begin("lub_heap");
  569. lub_heap_taint(BOOL_TRUE);
  570. lub_heap_check(BOOL_TRUE);
  571. /* first of all test with leak detection switched off */
  572. test_main(0);
  573. #if 1
  574. /* now test with leak detection switched on */
  575. test_main(1); /* a single context to use */
  576. #endif
  577. /* tidy up */
  578. status = lub_test_get_status();
  579. lub_test_end();
  580. return status;
  581. }
  582. /*--------------------------------------------------------- */