heap_check.c 2.3 KB

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