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; }