| 160 | } |
| 161 | |
| 162 | void MemPool::AcquireData(MemPool* src, bool keep_current) { |
| 163 | DFAKE_SCOPED_LOCK(mutex_); |
| 164 | DCHECK(src->CheckIntegrity(false)); |
| 165 | int num_acquired_chunks; |
| 166 | if (keep_current) { |
| 167 | num_acquired_chunks = src->current_chunk_idx_; |
| 168 | } else if (src->GetFreeOffset() == 0) { |
| 169 | // nothing in the last chunk |
| 170 | num_acquired_chunks = src->current_chunk_idx_; |
| 171 | } else { |
| 172 | num_acquired_chunks = src->current_chunk_idx_ + 1; |
| 173 | } |
| 174 | |
| 175 | if (num_acquired_chunks <= 0) { |
| 176 | if (!keep_current) src->FreeAll(); |
| 177 | return; |
| 178 | } |
| 179 | |
| 180 | vector<ChunkInfo>::iterator end_chunk = src->chunks_.begin() + num_acquired_chunks; |
| 181 | int64_t total_transfered_bytes = 0; |
| 182 | for (vector<ChunkInfo>::iterator i = src->chunks_.begin(); i != end_chunk; ++i) { |
| 183 | total_transfered_bytes += i->size; |
| 184 | } |
| 185 | src->total_reserved_bytes_ -= total_transfered_bytes; |
| 186 | total_reserved_bytes_ += total_transfered_bytes; |
| 187 | |
| 188 | src->mem_tracker_->TransferTo(mem_tracker_, total_transfered_bytes); |
| 189 | |
| 190 | // insert new chunks after current_chunk_idx_. We must calculate current_chunk_idx_ + 1 |
| 191 | // before finding the offset from chunks_.begin() because current_chunk_idx_ can be -1 |
| 192 | // and adding a negative number to chunks_.begin() is undefined behavior in C++. |
| 193 | vector<ChunkInfo>::iterator insert_chunk = chunks_.begin() + (current_chunk_idx_ + 1); |
| 194 | chunks_.insert(insert_chunk, src->chunks_.begin(), end_chunk); |
| 195 | src->chunks_.erase(src->chunks_.begin(), end_chunk); |
| 196 | current_chunk_idx_ += num_acquired_chunks; |
| 197 | |
| 198 | if (keep_current) { |
| 199 | src->current_chunk_idx_ = 0; |
| 200 | DCHECK(src->chunks_.size() == 1 || src->chunks_[1].allocated_bytes == 0); |
| 201 | total_allocated_bytes_ += src->total_allocated_bytes_ - src->GetFreeOffset(); |
| 202 | src->total_allocated_bytes_ = src->GetFreeOffset(); |
| 203 | } else { |
| 204 | src->current_chunk_idx_ = -1; |
| 205 | total_allocated_bytes_ += src->total_allocated_bytes_; |
| 206 | src->total_allocated_bytes_ = 0; |
| 207 | } |
| 208 | |
| 209 | if (!keep_current) src->FreeAll(); |
| 210 | DCHECK(src->CheckIntegrity(false)); |
| 211 | DCHECK(CheckIntegrity(false)); |
| 212 | } |
| 213 | |
| 214 | void MemPool::SetMemTracker(MemTracker* new_tracker) { |
| 215 | DFAKE_SCOPED_LOCK(mutex_); |