/* * Copyright 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 "dmmlib/raw_block.h" #include #ifdef PAGESIZE_ALIGN #include /* for pagesize */ #endif /* PAGESIZE_ALIGN */ #include "request_memory.h" #ifdef FL_RB_ONLY #include "dmmlib/freelist/freelist_rb.h" #include "dmmlib/freelist/initialize.h" #endif /* FL_RB_ONLY */ #ifdef BITMAP_RB_ONLY #include "bitmap/bitmap_rb.h" #endif /* BITMAP_RB_ONLY */ #include "locks.h" raw_block_header_t *create_raw_block(size_t raw_block_size, rb_type type) { raw_block_header_t *ptr; #ifdef BITMAP_RB_ONLY bitmap_rb_t *bitmap_rb; BMAP_EL_TYPE *bitmap_p; size_t vector_elements; size_t remaining_cells; #endif /* BITMAP_RB_ONLY */ // In case mmap() function is used, align the requested size to multiple of // pagesizes #ifdef PAGESIZE_ALIGN size_t pagesize = (size_t) sysconf(_SC_PAGESIZE); raw_block_size = pagesize * ((raw_block_size + pagesize - 1) / pagesize); #endif /* PAGESIZE_ALIGN */ ptr = (raw_block_header_t *)request_memory(raw_block_size); if(ptr == NULL) { return NULL; } init_raw_block_lock(ptr); lock_raw_block(ptr); #ifdef REQUEST_SIZE_INFO ptr->requested_size = raw_block_size; #endif /* REQUEST_SIZE_INFO */ ptr->size = raw_block_size; switch(type) { #ifdef FL_RB_ONLY case FREELIST: initialize_freelist((char *) ptr + sizeof(raw_block_header_t), raw_block_size - sizeof(raw_block_header_t)); break; #endif /* FL_RB_ONLY */ #ifdef BITMAP_RB_ONLY case BITMAP: bitmap_rb = (bitmap_rb_t *)((char *)ptr + sizeof(raw_block_header_t)); bitmap_rb->bytes_per_cell = BITMAP_RESOLUTION; vector_elements = (raw_block_size - sizeof(raw_block_header_t) - sizeof(bitmap_rb_t)) / (BMAP_EL_SIZE + BMAP_EL_SIZE_BITS * bitmap_rb->bytes_per_cell); remaining_cells = ((raw_block_size - sizeof(raw_block_header_t) - sizeof(bitmap_rb_t)) % (BMAP_EL_SIZE + BMAP_EL_SIZE_BITS * bitmap_rb->bytes_per_cell)) / bitmap_rb->bytes_per_cell; if(remaining_cells == 0) { bitmap_rb->elements = vector_elements; } else { bitmap_rb->elements = vector_elements + 1; } /* Initialize the bitmap vector just right after the raw block * header */ bitmap_p = (BMAP_EL_TYPE *)((char *)bitmap_rb + sizeof(bitmap_rb_t)); for(size_t i = 0; i < bitmap_rb->elements; ++i) { /* If there are some remaining cells, so an extra bitmap vector * element is used, the cells that cannot be used by the * application, have to be set as already used. */ if(i == bitmap_rb->elements - 1 && remaining_cells != 0) { *bitmap_p = (BMAP_EL_TYPE) 1; *bitmap_p <<= remaining_cells; *bitmap_p -= 1; } else { *bitmap_p = BMAP_EL_INIT_VAL; } bitmap_p++; } break; #endif /* BITMAP_RB_ONLY */ case BIGBLOCK: #ifdef REQUEST_SIZE_INFO ptr->requested_size -= sizeof(raw_block_header_t); #endif /* REQUEST_SIZE_INFO */ break; } unlock_raw_block(ptr); return ptr; }