coalesce.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. * Copyright 2011 Institute of Communication and Computer Systems (ICCS)
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. #include "dmm_config.h"
  18. #ifdef WITH_KNOBS
  19. #include "dmmlib/dmmlib.h"
  20. #endif /* WITH_KNOBS */
  21. #include "freelist/coalesce.h"
  22. #include "freelist/block_header_funcs.h"
  23. #include "freelist/ordering_policy.h"
  24. void coalesce(freelist_rb_t *raw_block, block_header_t *ptr) {
  25. size_t max_coal_size;
  26. size_t size;
  27. size_t current_next_size;
  28. size_t previous_current_size;
  29. size_t three_blocks_size;
  30. block_header_t *previous_block, *next_block;
  31. #ifdef COALESCING_FIXED
  32. max_coal_size = MAX_COALESCE_SIZE;
  33. #endif /* COALESCING_FIXED */
  34. #ifdef COALESCING_VARIABLE
  35. max_coal_size = (size_t) systemallocator.dmm_knobs.max_coalesce_size;
  36. #endif /* COALESCING_VARIABLE */
  37. size = get_size(ptr);
  38. previous_block = get_dlprevious(ptr);
  39. next_block = get_dlnext(raw_block, ptr);
  40. /* Find out the sizes of all possible combinations */
  41. /* Current + Next */
  42. if(next_block != NULL && is_free(next_block) == true) {
  43. current_next_size = size + get_size(next_block) + HEADER_SIZE;
  44. } else {
  45. current_next_size = (size_t) -1; /* SIZE_MAX */
  46. }
  47. /* Previous + Current */
  48. if(is_previous_free(ptr) == true) {
  49. previous_current_size = size + get_previous_size(ptr) + HEADER_SIZE;
  50. } else {
  51. previous_current_size = (size_t) -1; /* SIZE_MAX */
  52. }
  53. /* Previous + Current + Next */
  54. if(is_previous_free(ptr) == true && next_block != NULL &&
  55. is_free(next_block) == true) {
  56. three_blocks_size = get_previous_size(ptr) + size +
  57. get_size(next_block) + 2 * HEADER_SIZE;
  58. } else {
  59. three_blocks_size = (size_t) -1; /* SIZE_MAX */
  60. }
  61. /* Check if Previous + Current + Next is ok */
  62. if(three_blocks_size <= max_coal_size) {
  63. /* Remove the next block from the free list */
  64. REMOVE_FSLLIST(raw_block, next_block);
  65. /* Update border pointer if the next block was the border pointer */
  66. if(raw_block->border_ptr == next_block) {
  67. raw_block->border_ptr = previous_block;
  68. }
  69. /* Reset the previous block size */
  70. set_size_and_free(raw_block, previous_block, three_blocks_size);
  71. return;
  72. }
  73. /* Check if Previous + Current is ok */
  74. if(previous_current_size <= max_coal_size) {
  75. /* Update border pointer if the current block was the border pointer */
  76. if(raw_block->border_ptr == ptr) {
  77. raw_block->border_ptr = previous_block;
  78. }
  79. /* Reset the previous block size */
  80. set_size_and_free(raw_block, previous_block, previous_current_size);
  81. return;
  82. }
  83. /* Check if Current + Next is ok */
  84. if(current_next_size <= max_coal_size) {
  85. REMOVE_FSLLIST(raw_block, next_block);
  86. if(raw_block->border_ptr == next_block) {
  87. raw_block->border_ptr = ptr;
  88. }
  89. set_size_and_free(raw_block, ptr, current_next_size);
  90. ADD_BLOCK(ptr);
  91. return;
  92. }
  93. /* If everything fails, just mark the block free and add it to the free
  94. * list
  95. */
  96. mark_free(raw_block, ptr);
  97. ADD_BLOCK(ptr);
  98. return;
  99. }