123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- /*
- * Copyright 2011 Institute of Communication and Computer Systems (ICCS)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
- #include "freelist/split.h"
- #include "dmmlib/config.h"
- #ifdef WITH_KNOBS
- #include "dmmlib/dmmlib.h"
- #endif /* WITH_KNOBS */
- #include "other.h"
- #include "freelist/block_header_funcs.h"
- #include "freelist/ordering_policy.h"
- void split(freelist_rb_t *raw_block, block_header_t *ptr, size_t req_size) {
- size_t new_size;
- size_t min_split_size;
- block_header_t *new_block;
- #ifdef COALESCE_AFTER_SPLIT
- size_t max_coal_size;
- block_header_t *next_block;
- size_t current_next_size;
- next_block = get_dlnext(raw_block, ptr);
- #endif /* COALESCE_AFTER_SPLIT */
- /* Align the requested size */
- req_size = req_padding(req_size);
- /* Check what would be the size of the new block if we split the current
- * one.
- * Note: new_size is a size_t, so compare first in order to prevent an
- * underflow.
- */
- if(get_size(ptr) > req_size + HEADER_SIZE) {
- new_size = get_size(ptr) - req_size - HEADER_SIZE;
- } else {
- new_size = 0;
- }
- #ifdef SPLITTING_FIXED
- min_split_size = MIN_SPLIT_SIZE;
- #endif /* SPLITTING_FIXED */
- #ifdef SPLITTING_VARIABLE
- min_split_size = (size_t) systemallocator.dmm_knobs.min_split_size;
- #endif /* SPLITTING_VARIABLE */
- if(new_size < min_split_size) {
- return;
- }
- new_block = (block_header_t *)((char *)ptr + req_size + HEADER_SIZE);
- if(raw_block->border_ptr == ptr) {
- raw_block->border_ptr = new_block;
- }
- /* Resize the previous, to be used block */
- set_size_and_used(raw_block, ptr, req_size);
- #ifdef COALESCE_AFTER_SPLIT
- /* Try to coalesce with the next block if it is free */
- #ifdef COALESCING_FIXED
- max_coal_size = MAX_COAL_SIZE;
- #endif /* COALESCING_FIXED */
- #ifdef COALESCING_VARIABLE
- max_coal_size = systemallocator.dmm_knobs.max_coal_size;
- #endif /* COALESCING_VARIABLE */
- if(next_block != NULL && is_free(next_block) == true) {
- current_next_size = new_size + get_size(next_block) + HEADER_SIZE;
- if(current_next_size <= max_coal_size) {
- REMOVE_FSLLIST(raw_block, next_block);
- if(raw_block->border_ptr == next_block) {
- raw_block->border_ptr = new_block;
- }
- new_size = current_next_size;
- }
- }
- #endif /* COALESCE_AFTER_SPLIT */
- set_size_and_free(raw_block, new_block, new_size);
- ADD_BLOCK(new_block);
- }
|