summaryrefslogtreecommitdiff
path: root/src/video_core/buffer_cache
diff options
context:
space:
mode:
authorGravatar Rodrigo Locatti2020-06-15 22:29:32 -0300
committerGravatar GitHub2020-06-15 22:29:32 -0300
commit0bd9bc7201568f1c1f6f0a0c425cff6229ffc597 (patch)
tree7a398409a2e8a03a4bf5246ac5bda06a6d7ef823 /src/video_core/buffer_cache
parentMerge pull request #4085 from ReinUsesLisp/gcc-times (diff)
parentbuffer_cache: Avoid passing references of shared pointers and misc style changes (diff)
downloadyuzu-0bd9bc7201568f1c1f6f0a0c425cff6229ffc597.tar.gz
yuzu-0bd9bc7201568f1c1f6f0a0c425cff6229ffc597.tar.xz
yuzu-0bd9bc7201568f1c1f6f0a0c425cff6229ffc597.zip
Merge pull request #4066 from ReinUsesLisp/shared-ptr-buf
buffer_cache: Avoid passing references of shared pointers and misc style changes
Diffstat (limited to 'src/video_core/buffer_cache')
-rw-r--r--src/video_core/buffer_cache/buffer_block.h27
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h199
2 files changed, 112 insertions, 114 deletions
diff --git a/src/video_core/buffer_cache/buffer_block.h b/src/video_core/buffer_cache/buffer_block.h
index e35ee0b67..e64170e66 100644
--- a/src/video_core/buffer_cache/buffer_block.h
+++ b/src/video_core/buffer_cache/buffer_block.h
@@ -15,48 +15,47 @@ namespace VideoCommon {
15 15
16class BufferBlock { 16class BufferBlock {
17public: 17public:
18 bool Overlaps(const VAddr start, const VAddr end) const { 18 bool Overlaps(VAddr start, VAddr end) const {
19 return (cpu_addr < end) && (cpu_addr_end > start); 19 return (cpu_addr < end) && (cpu_addr_end > start);
20 } 20 }
21 21
22 bool IsInside(const VAddr other_start, const VAddr other_end) const { 22 bool IsInside(VAddr other_start, VAddr other_end) const {
23 return cpu_addr <= other_start && other_end <= cpu_addr_end; 23 return cpu_addr <= other_start && other_end <= cpu_addr_end;
24 } 24 }
25 25
26 std::size_t GetOffset(const VAddr in_addr) { 26 std::size_t Offset(VAddr in_addr) const {
27 return static_cast<std::size_t>(in_addr - cpu_addr); 27 return static_cast<std::size_t>(in_addr - cpu_addr);
28 } 28 }
29 29
30 VAddr GetCpuAddr() const { 30 VAddr CpuAddr() const {
31 return cpu_addr; 31 return cpu_addr;
32 } 32 }
33 33
34 VAddr GetCpuAddrEnd() const { 34 VAddr CpuAddrEnd() const {
35 return cpu_addr_end; 35 return cpu_addr_end;
36 } 36 }
37 37
38 void SetCpuAddr(const VAddr new_addr) { 38 void SetCpuAddr(VAddr new_addr) {
39 cpu_addr = new_addr; 39 cpu_addr = new_addr;
40 cpu_addr_end = new_addr + size; 40 cpu_addr_end = new_addr + size;
41 } 41 }
42 42
43 std::size_t GetSize() const { 43 std::size_t Size() const {
44 return size; 44 return size;
45 } 45 }
46 46
47 void SetEpoch(u64 new_epoch) { 47 u64 Epoch() const {
48 epoch = new_epoch; 48 return epoch;
49 } 49 }
50 50
51 u64 GetEpoch() { 51 void SetEpoch(u64 new_epoch) {
52 return epoch; 52 epoch = new_epoch;
53 } 53 }
54 54
55protected: 55protected:
56 explicit BufferBlock(VAddr cpu_addr, const std::size_t size) : size{size} { 56 explicit BufferBlock(VAddr cpu_addr_, std::size_t size_) : size{size_} {
57 SetCpuAddr(cpu_addr); 57 SetCpuAddr(cpu_addr_);
58 } 58 }
59 ~BufferBlock() = default;
60 59
61private: 60private:
62 VAddr cpu_addr{}; 61 VAddr cpu_addr{};
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index 77ae34339..308d8b55f 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -30,12 +30,16 @@
30 30
31namespace VideoCommon { 31namespace VideoCommon {
32 32
33template <typename OwnerBuffer, typename BufferType, typename StreamBuffer> 33template <typename Buffer, typename BufferType, typename StreamBuffer>
34class BufferCache { 34class BufferCache {
35 using IntervalSet = boost::icl::interval_set<VAddr>; 35 using IntervalSet = boost::icl::interval_set<VAddr>;
36 using IntervalType = typename IntervalSet::interval_type; 36 using IntervalType = typename IntervalSet::interval_type;
37 using VectorMapInterval = boost::container::small_vector<MapInterval*, 1>; 37 using VectorMapInterval = boost::container::small_vector<MapInterval*, 1>;
38 38
39 static constexpr u64 WRITE_PAGE_BIT = 11;
40 static constexpr u64 BLOCK_PAGE_BITS = 21;
41 static constexpr u64 BLOCK_PAGE_SIZE = 1ULL << BLOCK_PAGE_BITS;
42
39public: 43public:
40 using BufferInfo = std::pair<BufferType, u64>; 44 using BufferInfo = std::pair<BufferType, u64>;
41 45
@@ -82,7 +86,7 @@ public:
82 } 86 }
83 } 87 }
84 88
85 OwnerBuffer block = GetBlock(cpu_addr, size); 89 Buffer* const block = GetBlock(cpu_addr, size);
86 MapInterval* const map = MapAddress(block, gpu_addr, cpu_addr, size); 90 MapInterval* const map = MapAddress(block, gpu_addr, cpu_addr, size);
87 if (!map) { 91 if (!map) {
88 return {GetEmptyBuffer(size), 0}; 92 return {GetEmptyBuffer(size), 0};
@@ -98,7 +102,7 @@ public:
98 } 102 }
99 } 103 }
100 104
101 return {ToHandle(block), static_cast<u64>(block->GetOffset(cpu_addr))}; 105 return {block->Handle(), static_cast<u64>(block->Offset(cpu_addr))};
102 } 106 }
103 107
104 /// Uploads from a host memory. Returns the OpenGL buffer where it's located and its offset. 108 /// Uploads from a host memory. Returns the OpenGL buffer where it's located and its offset.
@@ -129,16 +133,18 @@ public:
129 stream_buffer->Unmap(buffer_offset - buffer_offset_base); 133 stream_buffer->Unmap(buffer_offset - buffer_offset_base);
130 } 134 }
131 135
136 /// Function called at the end of each frame, inteded for deferred operations
132 void TickFrame() { 137 void TickFrame() {
133 ++epoch; 138 ++epoch;
139
134 while (!pending_destruction.empty()) { 140 while (!pending_destruction.empty()) {
135 // Delay at least 4 frames before destruction. 141 // Delay at least 4 frames before destruction.
136 // This is due to triple buffering happening on some drivers. 142 // This is due to triple buffering happening on some drivers.
137 static constexpr u64 epochs_to_destroy = 5; 143 static constexpr u64 epochs_to_destroy = 5;
138 if (pending_destruction.front()->GetEpoch() + epochs_to_destroy > epoch) { 144 if (pending_destruction.front()->Epoch() + epochs_to_destroy > epoch) {
139 break; 145 break;
140 } 146 }
141 pending_destruction.pop_front(); 147 pending_destruction.pop();
142 } 148 }
143 } 149 }
144 150
@@ -253,23 +259,21 @@ public:
253 259
254protected: 260protected:
255 explicit BufferCache(VideoCore::RasterizerInterface& rasterizer, Core::System& system, 261 explicit BufferCache(VideoCore::RasterizerInterface& rasterizer, Core::System& system,
256 std::unique_ptr<StreamBuffer> stream_buffer) 262 std::unique_ptr<StreamBuffer> stream_buffer_)
257 : rasterizer{rasterizer}, system{system}, stream_buffer{std::move(stream_buffer)}, 263 : rasterizer{rasterizer}, system{system}, stream_buffer{std::move(stream_buffer_)},
258 stream_buffer_handle{this->stream_buffer->GetHandle()} {} 264 stream_buffer_handle{stream_buffer->Handle()} {}
259 265
260 ~BufferCache() = default; 266 ~BufferCache() = default;
261 267
262 virtual BufferType ToHandle(const OwnerBuffer& storage) = 0; 268 virtual std::shared_ptr<Buffer> CreateBlock(VAddr cpu_addr, std::size_t size) = 0;
263 269
264 virtual OwnerBuffer CreateBlock(VAddr cpu_addr, std::size_t size) = 0; 270 virtual void UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
265
266 virtual void UploadBlockData(const OwnerBuffer& buffer, std::size_t offset, std::size_t size,
267 const u8* data) = 0; 271 const u8* data) = 0;
268 272
269 virtual void DownloadBlockData(const OwnerBuffer& buffer, std::size_t offset, std::size_t size, 273 virtual void DownloadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
270 u8* data) = 0; 274 u8* data) = 0;
271 275
272 virtual void CopyBlock(const OwnerBuffer& src, const OwnerBuffer& dst, std::size_t src_offset, 276 virtual void CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset,
273 std::size_t dst_offset, std::size_t size) = 0; 277 std::size_t dst_offset, std::size_t size) = 0;
274 278
275 virtual BufferInfo ConstBufferUpload(const void* raw_pointer, std::size_t size) { 279 virtual BufferInfo ConstBufferUpload(const void* raw_pointer, std::size_t size) {
@@ -325,7 +329,7 @@ protected:
325 } 329 }
326 330
327private: 331private:
328 MapInterval* MapAddress(const OwnerBuffer& block, GPUVAddr gpu_addr, VAddr cpu_addr, 332 MapInterval* MapAddress(const Buffer* block, GPUVAddr gpu_addr, VAddr cpu_addr,
329 std::size_t size) { 333 std::size_t size) {
330 const VectorMapInterval overlaps = GetMapsInRange(cpu_addr, size); 334 const VectorMapInterval overlaps = GetMapsInRange(cpu_addr, size);
331 if (overlaps.empty()) { 335 if (overlaps.empty()) {
@@ -333,11 +337,11 @@ private:
333 const VAddr cpu_addr_end = cpu_addr + size; 337 const VAddr cpu_addr_end = cpu_addr + size;
334 if (memory_manager.IsGranularRange(gpu_addr, size)) { 338 if (memory_manager.IsGranularRange(gpu_addr, size)) {
335 u8* host_ptr = memory_manager.GetPointer(gpu_addr); 339 u8* host_ptr = memory_manager.GetPointer(gpu_addr);
336 UploadBlockData(block, block->GetOffset(cpu_addr), size, host_ptr); 340 UploadBlockData(*block, block->Offset(cpu_addr), size, host_ptr);
337 } else { 341 } else {
338 staging_buffer.resize(size); 342 staging_buffer.resize(size);
339 memory_manager.ReadBlockUnsafe(gpu_addr, staging_buffer.data(), size); 343 memory_manager.ReadBlockUnsafe(gpu_addr, staging_buffer.data(), size);
340 UploadBlockData(block, block->GetOffset(cpu_addr), size, staging_buffer.data()); 344 UploadBlockData(*block, block->Offset(cpu_addr), size, staging_buffer.data());
341 } 345 }
342 return Register(MapInterval(cpu_addr, cpu_addr_end, gpu_addr)); 346 return Register(MapInterval(cpu_addr, cpu_addr_end, gpu_addr));
343 } 347 }
@@ -380,7 +384,7 @@ private:
380 return map; 384 return map;
381 } 385 }
382 386
383 void UpdateBlock(const OwnerBuffer& block, VAddr start, VAddr end, 387 void UpdateBlock(const Buffer* block, VAddr start, VAddr end,
384 const VectorMapInterval& overlaps) { 388 const VectorMapInterval& overlaps) {
385 const IntervalType base_interval{start, end}; 389 const IntervalType base_interval{start, end};
386 IntervalSet interval_set{}; 390 IntervalSet interval_set{};
@@ -390,13 +394,13 @@ private:
390 interval_set.subtract(subtract); 394 interval_set.subtract(subtract);
391 } 395 }
392 for (auto& interval : interval_set) { 396 for (auto& interval : interval_set) {
393 std::size_t size = interval.upper() - interval.lower(); 397 const std::size_t size = interval.upper() - interval.lower();
394 if (size > 0) { 398 if (size == 0) {
395 staging_buffer.resize(size); 399 continue;
396 system.Memory().ReadBlockUnsafe(interval.lower(), staging_buffer.data(), size);
397 UploadBlockData(block, block->GetOffset(interval.lower()), size,
398 staging_buffer.data());
399 } 400 }
401 staging_buffer.resize(size);
402 system.Memory().ReadBlockUnsafe(interval.lower(), staging_buffer.data(), size);
403 UploadBlockData(*block, block->Offset(interval.lower()), size, staging_buffer.data());
400 } 404 }
401 } 405 }
402 406
@@ -426,10 +430,14 @@ private:
426 } 430 }
427 431
428 void FlushMap(MapInterval* map) { 432 void FlushMap(MapInterval* map) {
433 const auto it = blocks.find(map->start >> BLOCK_PAGE_BITS);
434 ASSERT_OR_EXECUTE(it != blocks.end(), return;);
435
436 std::shared_ptr<Buffer> block = it->second;
437
429 const std::size_t size = map->end - map->start; 438 const std::size_t size = map->end - map->start;
430 OwnerBuffer block = blocks[map->start >> block_page_bits];
431 staging_buffer.resize(size); 439 staging_buffer.resize(size);
432 DownloadBlockData(block, block->GetOffset(map->start), size, staging_buffer.data()); 440 DownloadBlockData(*block, block->Offset(map->start), size, staging_buffer.data());
433 system.Memory().WriteBlockUnsafe(map->start, staging_buffer.data(), size); 441 system.Memory().WriteBlockUnsafe(map->start, staging_buffer.data(), size);
434 map->MarkAsModified(false, 0); 442 map->MarkAsModified(false, 0);
435 } 443 }
@@ -452,97 +460,89 @@ private:
452 buffer_offset = offset_aligned; 460 buffer_offset = offset_aligned;
453 } 461 }
454 462
455 OwnerBuffer EnlargeBlock(OwnerBuffer buffer) { 463 std::shared_ptr<Buffer> EnlargeBlock(std::shared_ptr<Buffer> buffer) {
456 const std::size_t old_size = buffer->GetSize(); 464 const std::size_t old_size = buffer->Size();
457 const std::size_t new_size = old_size + block_page_size; 465 const std::size_t new_size = old_size + BLOCK_PAGE_SIZE;
458 const VAddr cpu_addr = buffer->GetCpuAddr(); 466 const VAddr cpu_addr = buffer->CpuAddr();
459 OwnerBuffer new_buffer = CreateBlock(cpu_addr, new_size); 467 std::shared_ptr<Buffer> new_buffer = CreateBlock(cpu_addr, new_size);
460 CopyBlock(buffer, new_buffer, 0, 0, old_size); 468 CopyBlock(*buffer, *new_buffer, 0, 0, old_size);
461 buffer->SetEpoch(epoch); 469 QueueDestruction(std::move(buffer));
462 pending_destruction.push_back(buffer); 470
463 const VAddr cpu_addr_end = cpu_addr + new_size - 1; 471 const VAddr cpu_addr_end = cpu_addr + new_size - 1;
464 u64 page_start = cpu_addr >> block_page_bits; 472 const u64 page_end = cpu_addr_end >> BLOCK_PAGE_BITS;
465 const u64 page_end = cpu_addr_end >> block_page_bits; 473 for (u64 page_start = cpu_addr >> BLOCK_PAGE_BITS; page_start <= page_end; ++page_start) {
466 while (page_start <= page_end) { 474 blocks.insert_or_assign(page_start, new_buffer);
467 blocks[page_start] = new_buffer;
468 ++page_start;
469 } 475 }
476
470 return new_buffer; 477 return new_buffer;
471 } 478 }
472 479
473 OwnerBuffer MergeBlocks(OwnerBuffer first, OwnerBuffer second) { 480 std::shared_ptr<Buffer> MergeBlocks(std::shared_ptr<Buffer> first,
474 const std::size_t size_1 = first->GetSize(); 481 std::shared_ptr<Buffer> second) {
475 const std::size_t size_2 = second->GetSize(); 482 const std::size_t size_1 = first->Size();
476 const VAddr first_addr = first->GetCpuAddr(); 483 const std::size_t size_2 = second->Size();
477 const VAddr second_addr = second->GetCpuAddr(); 484 const VAddr first_addr = first->CpuAddr();
485 const VAddr second_addr = second->CpuAddr();
478 const VAddr new_addr = std::min(first_addr, second_addr); 486 const VAddr new_addr = std::min(first_addr, second_addr);
479 const std::size_t new_size = size_1 + size_2; 487 const std::size_t new_size = size_1 + size_2;
480 OwnerBuffer new_buffer = CreateBlock(new_addr, new_size); 488
481 CopyBlock(first, new_buffer, 0, new_buffer->GetOffset(first_addr), size_1); 489 std::shared_ptr<Buffer> new_buffer = CreateBlock(new_addr, new_size);
482 CopyBlock(second, new_buffer, 0, new_buffer->GetOffset(second_addr), size_2); 490 CopyBlock(*first, *new_buffer, 0, new_buffer->Offset(first_addr), size_1);
483 first->SetEpoch(epoch); 491 CopyBlock(*second, *new_buffer, 0, new_buffer->Offset(second_addr), size_2);
484 second->SetEpoch(epoch); 492 QueueDestruction(std::move(first));
485 pending_destruction.push_back(first); 493 QueueDestruction(std::move(second));
486 pending_destruction.push_back(second); 494
487 const VAddr cpu_addr_end = new_addr + new_size - 1; 495 const VAddr cpu_addr_end = new_addr + new_size - 1;
488 u64 page_start = new_addr >> block_page_bits; 496 const u64 page_end = cpu_addr_end >> BLOCK_PAGE_BITS;
489 const u64 page_end = cpu_addr_end >> block_page_bits; 497 for (u64 page_start = new_addr >> BLOCK_PAGE_BITS; page_start <= page_end; ++page_start) {
490 while (page_start <= page_end) { 498 blocks.insert_or_assign(page_start, new_buffer);
491 blocks[page_start] = new_buffer;
492 ++page_start;
493 } 499 }
494 return new_buffer; 500 return new_buffer;
495 } 501 }
496 502
497 OwnerBuffer GetBlock(const VAddr cpu_addr, const std::size_t size) { 503 Buffer* GetBlock(VAddr cpu_addr, std::size_t size) {
498 OwnerBuffer found; 504 std::shared_ptr<Buffer> found;
505
499 const VAddr cpu_addr_end = cpu_addr + size - 1; 506 const VAddr cpu_addr_end = cpu_addr + size - 1;
500 u64 page_start = cpu_addr >> block_page_bits; 507 const u64 page_end = cpu_addr_end >> BLOCK_PAGE_BITS;
501 const u64 page_end = cpu_addr_end >> block_page_bits; 508 for (u64 page_start = cpu_addr >> BLOCK_PAGE_BITS; page_start <= page_end; ++page_start) {
502 while (page_start <= page_end) {
503 auto it = blocks.find(page_start); 509 auto it = blocks.find(page_start);
504 if (it == blocks.end()) { 510 if (it == blocks.end()) {
505 if (found) { 511 if (found) {
506 found = EnlargeBlock(found); 512 found = EnlargeBlock(found);
507 } else { 513 continue;
508 const VAddr start_addr = (page_start << block_page_bits);
509 found = CreateBlock(start_addr, block_page_size);
510 blocks[page_start] = found;
511 }
512 } else {
513 if (found) {
514 if (found == it->second) {
515 ++page_start;
516 continue;
517 }
518 found = MergeBlocks(found, it->second);
519 } else {
520 found = it->second;
521 } 514 }
515 const VAddr start_addr = page_start << BLOCK_PAGE_BITS;
516 found = CreateBlock(start_addr, BLOCK_PAGE_SIZE);
517 blocks.insert_or_assign(page_start, found);
518 continue;
519 }
520 if (!found) {
521 found = it->second;
522 continue;
523 }
524 if (found != it->second) {
525 found = MergeBlocks(std::move(found), it->second);
522 } 526 }
523 ++page_start;
524 } 527 }
525 return found; 528 return found.get();
526 } 529 }
527 530
528 void MarkRegionAsWritten(const VAddr start, const VAddr end) { 531 void MarkRegionAsWritten(VAddr start, VAddr end) {
529 u64 page_start = start >> write_page_bit; 532 const u64 page_end = end >> WRITE_PAGE_BIT;
530 const u64 page_end = end >> write_page_bit; 533 for (u64 page_start = start >> WRITE_PAGE_BIT; page_start <= page_end; ++page_start) {
531 while (page_start <= page_end) {
532 auto it = written_pages.find(page_start); 534 auto it = written_pages.find(page_start);
533 if (it != written_pages.end()) { 535 if (it != written_pages.end()) {
534 it->second = it->second + 1; 536 it->second = it->second + 1;
535 } else { 537 } else {
536 written_pages[page_start] = 1; 538 written_pages.insert_or_assign(page_start, 1);
537 } 539 }
538 ++page_start;
539 } 540 }
540 } 541 }
541 542
542 void UnmarkRegionAsWritten(const VAddr start, const VAddr end) { 543 void UnmarkRegionAsWritten(VAddr start, VAddr end) {
543 u64 page_start = start >> write_page_bit; 544 const u64 page_end = end >> WRITE_PAGE_BIT;
544 const u64 page_end = end >> write_page_bit; 545 for (u64 page_start = start >> WRITE_PAGE_BIT; page_start <= page_end; ++page_start) {
545 while (page_start <= page_end) {
546 auto it = written_pages.find(page_start); 546 auto it = written_pages.find(page_start);
547 if (it != written_pages.end()) { 547 if (it != written_pages.end()) {
548 if (it->second > 1) { 548 if (it->second > 1) {
@@ -551,22 +551,24 @@ private:
551 written_pages.erase(it); 551 written_pages.erase(it);
552 } 552 }
553 } 553 }
554 ++page_start;
555 } 554 }
556 } 555 }
557 556
558 bool IsRegionWritten(const VAddr start, const VAddr end) const { 557 bool IsRegionWritten(VAddr start, VAddr end) const {
559 u64 page_start = start >> write_page_bit; 558 const u64 page_end = end >> WRITE_PAGE_BIT;
560 const u64 page_end = end >> write_page_bit; 559 for (u64 page_start = start >> WRITE_PAGE_BIT; page_start <= page_end; ++page_start) {
561 while (page_start <= page_end) {
562 if (written_pages.count(page_start) > 0) { 560 if (written_pages.count(page_start) > 0) {
563 return true; 561 return true;
564 } 562 }
565 ++page_start;
566 } 563 }
567 return false; 564 return false;
568 } 565 }
569 566
567 void QueueDestruction(std::shared_ptr<Buffer> buffer) {
568 buffer->SetEpoch(epoch);
569 pending_destruction.push(std::move(buffer));
570 }
571
570 void MarkForAsyncFlush(MapInterval* map) { 572 void MarkForAsyncFlush(MapInterval* map) {
571 if (!uncommitted_flushes) { 573 if (!uncommitted_flushes) {
572 uncommitted_flushes = std::make_shared<std::unordered_set<MapInterval*>>(); 574 uncommitted_flushes = std::make_shared<std::unordered_set<MapInterval*>>();
@@ -578,7 +580,7 @@ private:
578 Core::System& system; 580 Core::System& system;
579 581
580 std::unique_ptr<StreamBuffer> stream_buffer; 582 std::unique_ptr<StreamBuffer> stream_buffer;
581 BufferType stream_buffer_handle{}; 583 BufferType stream_buffer_handle;
582 584
583 u8* buffer_ptr = nullptr; 585 u8* buffer_ptr = nullptr;
584 u64 buffer_offset = 0; 586 u64 buffer_offset = 0;
@@ -588,18 +590,15 @@ private:
588 boost::intrusive::set<MapInterval, boost::intrusive::compare<MapIntervalCompare>> 590 boost::intrusive::set<MapInterval, boost::intrusive::compare<MapIntervalCompare>>
589 mapped_addresses; 591 mapped_addresses;
590 592
591 static constexpr u64 write_page_bit = 11;
592 std::unordered_map<u64, u32> written_pages; 593 std::unordered_map<u64, u32> written_pages;
594 std::unordered_map<u64, std::shared_ptr<Buffer>> blocks;
593 595
594 static constexpr u64 block_page_bits = 21; 596 std::queue<std::shared_ptr<Buffer>> pending_destruction;
595 static constexpr u64 block_page_size = 1ULL << block_page_bits;
596 std::unordered_map<u64, OwnerBuffer> blocks;
597
598 std::list<OwnerBuffer> pending_destruction;
599 u64 epoch = 0; 597 u64 epoch = 0;
600 u64 modified_ticks = 0; 598 u64 modified_ticks = 0;
601 599
602 std::vector<u8> staging_buffer; 600 std::vector<u8> staging_buffer;
601
603 std::list<MapInterval*> marked_for_unregister; 602 std::list<MapInterval*> marked_for_unregister;
604 603
605 std::shared_ptr<std::unordered_set<MapInterval*>> uncommitted_flushes; 604 std::shared_ptr<std::unordered_set<MapInterval*>> uncommitted_flushes;