split.c 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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 "freelist/split.h"
  18. #include "dmm_config.h"
  19. #ifdef WITH_KNOBS
  20. #include "dmmlib/dmmlib.h"
  21. #endif /* WITH_KNOBS */
  22. #include "freelist/block_header_funcs.h"
  23. #include "freelist/ordering_policy.h"
  24. void split(freelist_rb_t *raw_block, block_header_t *ptr, size_t req_size) {
  25. size_t new_size;
  26. size_t min_split_size;
  27. block_header_t *new_block;
  28. #ifdef COALESCE_AFTER_SPLIT
  29. size_t max_coal_size;
  30. block_header_t *next_block;
  31. size_t current_next_size;
  32. next_block = get_dlnext(raw_block, ptr);
  33. #endif /* COALESCE_AFTER_SPLIT */
  34. /* Check what would be the size of the new block if we split the current
  35. * one.
  36. * Note: new_size is a size_t, so compare first in order to prevent an
  37. * underflow.
  38. */
  39. if(get_size(ptr) > req_size + HEADER_SIZE) {
  40. new_size = get_size(ptr) - req_size - HEADER_SIZE;
  41. } else {
  42. new_size = 0;
  43. }
  44. #ifdef SPLITTING_FIXED
  45. min_split_size = MIN_SPLIT_SIZE;
  46. #endif /* SPLITTING_FIXED */
  47. #ifdef SPLITTING_VARIABLE
  48. min_split_size = (size_t) systemallocator.dmm_knobs.min_split_size;
  49. #endif /* SPLITTING_VARIABLE */
  50. if(new_size < min_split_size) {
  51. return;
  52. }
  53. new_block = (block_header_t *)((char *)ptr + req_size + HEADER_SIZE);
  54. if(raw_block->border_ptr == ptr) {
  55. raw_block->border_ptr = new_block;
  56. }
  57. /* Resize the previous, to be used block */
  58. set_size_and_used(raw_block, ptr, req_size);
  59. #ifdef COALESCE_AFTER_SPLIT
  60. /* Try to coalesce with the next block if it is free */
  61. #ifdef COALESCING_FIXED
  62. max_coal_size = MAX_COAL_SIZE;
  63. #endif /* COALESCING_FIXED */
  64. #ifdef COALESCING_VARIABLE
  65. max_coal_size = systemallocator.dmm_knobs.max_coal_size;
  66. #endif /* COALESCING_VARIABLE */
  67. if(next_block != NULL && is_free(next_block) == true) {
  68. current_next_size = new_size + get_size(next_block) + HEADER_SIZE;
  69. if(current_next_size <= max_coal_size) {
  70. REMOVE_FSLLIST(raw_block, next_block);
  71. if(raw_block->border_ptr == next_block) {
  72. raw_block->border_ptr = new_block;
  73. }
  74. new_size = current_next_size;
  75. }
  76. }
  77. #endif /* COALESCE_AFTER_SPLIT */
  78. set_size_and_free(raw_block, new_block, new_size);
  79. ADD_BLOCK(new_block);
  80. }