heap_check.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #include "private.h"
  2. /* flag to indicate whether to check memory or not */
  3. static bool_t checking = BOOL_FALSE;
  4. typedef struct
  5. {
  6. bool_t result;
  7. unsigned free_blocks;
  8. lub_heap_t *heap;
  9. } check_arg_t;
  10. /*--------------------------------------------------------- */
  11. static void
  12. process_segment(void *s,
  13. unsigned index,
  14. size_t size,
  15. void *a)
  16. {
  17. lub_heap_segment_t *segment = s;
  18. lub_heap_block_t *block = lub_heap_block_getfirst(segment);
  19. check_arg_t *arg = a;
  20. /*
  21. * don't bother checking if this segment has zero blocks
  22. */
  23. if(arg->heap->stats.free_blocks || arg->heap->stats.alloc_blocks)
  24. {
  25. arg->result = lub_heap_block_check(block);
  26. if(BOOL_TRUE == arg->result)
  27. {
  28. /* check that the first block has the segment set */
  29. arg->result = (block->free.tag.segment == 1) ? BOOL_TRUE : BOOL_FALSE;
  30. if(block->free.tag.free)
  31. {
  32. ++arg->free_blocks;
  33. }
  34. }
  35. /* now iterate along the block chain checking each one */
  36. while((BOOL_TRUE == arg->result)
  37. && (block = lub_heap_block_getnext(block)))
  38. {
  39. /* check this block */
  40. arg->result = lub_heap_block_check(block);
  41. if(BOOL_TRUE == arg->result)
  42. {
  43. /* ensure that all non-first blocks have the segment clear */
  44. arg->result = (block->free.tag.segment == 0) ? BOOL_TRUE : BOOL_FALSE;
  45. if(block->free.tag.free)
  46. {
  47. ++arg->free_blocks;
  48. }
  49. }
  50. }
  51. }
  52. }
  53. /*--------------------------------------------------------- */
  54. bool_t
  55. lub_heap_check(bool_t enable)
  56. {
  57. bool_t result = checking;
  58. checking = enable;
  59. return result;
  60. }
  61. /*--------------------------------------------------------- */
  62. bool_t
  63. lub_heap_is_checking(void)
  64. {
  65. return checking;
  66. }
  67. /*--------------------------------------------------------- */
  68. bool_t
  69. lub_heap_check_memory(lub_heap_t *this)
  70. {
  71. check_arg_t arg;
  72. arg.result = BOOL_TRUE;
  73. if(BOOL_TRUE == checking)
  74. {
  75. arg.free_blocks = 0;
  76. arg.heap = this;
  77. /* iterate all the segments in the system */
  78. lub_heap_foreach_segment(this,process_segment,&arg);
  79. /* now check that the stats map to the available free blocks
  80. * checking the alloc blocks is more difficult because of the hidden
  81. * overheads when performing leak detection.
  82. */
  83. if( (this->stats.free_blocks != arg.free_blocks) )
  84. {
  85. arg.result = BOOL_FALSE;
  86. }
  87. }
  88. return arg.result;
  89. }
  90. /*--------------------------------------------------------- */