コード例 #1
0
ServerBlock* DiskBackedBlockMap::allocate_block(ServerBlock* block, size_t block_size, bool initialize){
    /** If enough memory remains, allocates block and returns.
     * Otherwise, frees up memory by writing out dirty blocks
     * till enough memory has been obtained, then allocates
     * and returns block.
     */
	std::size_t remaining_mem = max_allocatable_bytes_ - ServerBlock::allocated_bytes();

    while (block_size * sizeof(double) > remaining_mem){
        try{
			BlockId bid = policy_.get_next_block_for_removal();
			ServerBlock* blk = block_map_.block(bid);
			SIP_LOG(std::cout << "S " << sip_mpi_attr_.company_rank()
					<< " : Freeing block " << bid
					<< " and writing to disk to make space for new block"
					<< std::endl);
			if(blk->is_dirty()){
				write_block_to_disk(bid, blk);
			}
			blk->free_in_memory_data();

			// Junmin's fix :
			// As a result of freeing up block memory, the remaining memory should
			// have increased. Otherwise it will go into an infinite loop.
			if (!(remaining_mem < max_allocatable_bytes_ - ServerBlock::allocated_bytes())) {
				throw std::out_of_range("Break now.");
			}
            remaining_mem = max_allocatable_bytes_ - ServerBlock::allocated_bytes();

        } catch (const std::out_of_range& oor){
            std::cerr << " In DiskBackedBlockMap::allocate_block" << std::endl;
            std::cerr << oor.what() << std::endl;
            std::cerr << *this << std::endl;
            fail(" Something got messed up in the internal data structures of the Server", current_line());
        } catch(const std::bad_alloc& ba){
            std::cerr << " In DiskBackedBlockMap::allocate_block" << std::endl;
            std::cerr << ba.what() << std::endl;
            std::cerr << *this << std::endl;
			fail(" Could not allocate ServerBlock, out of memory", current_line());
		}
	}

	std::stringstream ss;
	ss << "S " << sip_mpi_attr_.company_rank() << " : Could not allocate memory for block of size "
			<< block_size << ", Memory being used :" << ServerBlock::allocated_bytes() << std::endl;
	sip :: check (block_size <= max_allocatable_bytes_ - ServerBlock::allocated_bytes(), ss.str());
   
    if (block == NULL) {
	    block = new ServerBlock(block_size, initialize);
    } else {
        block->allocate_in_memory_data();
    }

	return block;
}