partition_realloc.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * partition_realloc.c
  3. */
  4. #include <string.h>
  5. #include "private.h"
  6. /*--------------------------------------------------------- */
  7. void
  8. lub_partition_stop_here(lub_heap_status_t status,
  9. char *old_ptr,
  10. size_t new_size)
  11. {
  12. /* This is provided as a debug aid */
  13. status = status;
  14. old_ptr = old_ptr;
  15. new_size = new_size;
  16. }
  17. /*--------------------------------------------------------- */
  18. void
  19. lub_partition_time_to_die(lub_partition_t *this)
  20. {
  21. bool_t time_to_die = BOOL_TRUE;
  22. lub_heap_stats_t stats;
  23. lub_heap_t *local_heap = lub_partition__get_local_heap(this);
  24. if(local_heap)
  25. {
  26. lub_heap__get_stats(local_heap,&stats);
  27. if(stats.alloc_blocks)
  28. {
  29. time_to_die = BOOL_FALSE;
  30. }
  31. }
  32. if(BOOL_FALSE == time_to_die)
  33. {
  34. lub_partition_lock(this);
  35. lub_heap__get_stats(this->m_global_heap,&stats);
  36. lub_partition_unlock(this);
  37. if(stats.alloc_blocks)
  38. {
  39. time_to_die = BOOL_FALSE;
  40. }
  41. }
  42. if(BOOL_TRUE == time_to_die)
  43. {
  44. /* and so the time has come... */
  45. lub_partition_destroy(this);
  46. }
  47. }
  48. /*--------------------------------------------------------- */
  49. lub_heap_status_t
  50. lub_partition_global_realloc(lub_partition_t *this,
  51. char **ptr,
  52. size_t size,
  53. lub_heap_align_t alignment)
  54. {
  55. lub_heap_status_t status = LUB_HEAP_FAILED;
  56. lub_partition_lock(this);
  57. if(!this->m_global_heap)
  58. {
  59. /*
  60. * Create the global heap
  61. */
  62. size_t required = size;
  63. void *segment = lub_partition_segment_alloc(this,&required);
  64. this->m_global_heap = lub_heap_create(segment,required);
  65. }
  66. if(this->m_global_heap)
  67. {
  68. status = lub_heap_realloc(this->m_global_heap,ptr,size,alignment);
  69. if(LUB_HEAP_FAILED == status)
  70. {
  71. /* expand memory and try again */
  72. if(lub_partition_extend_memory(this,size))
  73. {
  74. status = lub_heap_realloc(this->m_global_heap,
  75. ptr,size,alignment);
  76. }
  77. }
  78. }
  79. lub_partition_unlock(this);
  80. return status;
  81. }
  82. /*--------------------------------------------------------- */
  83. lub_heap_status_t
  84. lub_partition_realloc(lub_partition_t *this,
  85. char **ptr,
  86. size_t size,
  87. lub_heap_align_t alignment)
  88. {
  89. lub_heap_status_t status = LUB_HEAP_FAILED;
  90. size_t requested_size = size;
  91. lub_heap_t *local_heap;
  92. if((0 == size) && (0 == *ptr))
  93. {
  94. /* simple optimisation */
  95. return LUB_HEAP_OK;
  96. }
  97. if(this->m_dying)
  98. {
  99. local_heap = lub_partition__get_local_heap(this);
  100. if(size)
  101. {
  102. /* don't allocate any new memory when dying */
  103. size = 0;
  104. }
  105. }
  106. else
  107. {
  108. local_heap = lub_partition_findcreate_local_heap(this);
  109. }
  110. if(local_heap)
  111. {
  112. /* try the fast local heap first */
  113. status = lub_heap_realloc(local_heap,ptr,size,alignment);
  114. }
  115. if((LUB_HEAP_FAILED == status) || (LUB_HEAP_INVALID_POINTER == status))
  116. {
  117. char *old_ptr = 0;
  118. if(local_heap && (LUB_HEAP_FAILED == status) && size)
  119. {
  120. /* we need to reallocate from the global and copy from the local */
  121. old_ptr = *ptr;
  122. *ptr = 0;
  123. }
  124. /* time to use the slower global heap */
  125. status = lub_partition_global_realloc(this,ptr,size,alignment);
  126. if(old_ptr && (LUB_HEAP_OK == status))
  127. {
  128. /* copy from the local to the global */
  129. memcpy(*ptr,old_ptr,size);
  130. /* and release the local block */
  131. status = lub_heap_realloc(local_heap,&old_ptr,0,alignment);
  132. }
  133. }
  134. if(LUB_HEAP_OK != status)
  135. {
  136. lub_partition_stop_here(status,*ptr,size);
  137. }
  138. /* allow the partion to destroy itself if necessary */
  139. if(this->m_dying)
  140. {
  141. lub_partition_time_to_die(this);
  142. if(requested_size)
  143. {
  144. /* we don't allocate memory whilst dying */
  145. status = LUB_HEAP_FAILED;
  146. }
  147. }
  148. return status;
  149. }
  150. /*-------------------------------------------------------- */