MCPcopy Create free account
hub / github.com/apache/impala / CleanPages

Method CleanPages

be/src/runtime/bufferpool/buffer-pool.cc:663–717  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

661}
662
663Status BufferPool::Client::CleanPages(
664 unique_lock<mutex>* client_lock, int64_t len, bool lazy_flush) {
665 DCHECK_GE(len, 0);
666 DCHECK_LE(len, reservation_.GetReservation());
667 DCheckHoldsLock(*client_lock);
668 // If another thread is in CleanPages() for this client (and has dropped the lock while
669 // waiting on 'write_complete_cv_', wait for it to flush its pages before proceeding so
670 // that we don't overcommit memory.
671 while (cleaning_pages_) clean_pages_done_cv_.Wait(*client_lock);
672
673 DCHECK_CONSISTENCY();
674 // Work out what we need to get bytes of dirty unpinned + in flight pages down to
675 // in order to satisfy the eviction policy.
676 int64_t target_dirty_bytes = reservation_.GetReservation() - buffers_allocated_bytes_
677 - pinned_pages_.bytes() - len;
678 if (VLOG_IS_ON(3)) {
679 VLOG(3) << "target_dirty_bytes=" << target_dirty_bytes
680 << " reservation=" << reservation_.GetReservation()
681 << " buffers_allocated_bytes_=" << buffers_allocated_bytes_
682 << " pinned_pages_.bytes()=" << pinned_pages_.bytes()
683 << " len=" << len << "\n"
684 << DebugStringLocked();
685 }
686 // Start enough writes to ensure that the loop condition below will eventually become
687 // false (or a write error will be encountered).
688 int64_t min_bytes_to_write =
689 max<int64_t>(0, dirty_unpinned_pages_.bytes() - target_dirty_bytes);
690 if (lazy_flush
691 && dirty_unpinned_pages_.bytes() + in_flight_write_pages_.bytes()
692 <= target_dirty_bytes) {
693 return Status::OK();
694 }
695 cleaning_pages_ = true;
696 auto exit_trigger = MakeScopeExitTrigger([this, client_lock]() {
697 DCheckHoldsLock(*client_lock);
698 cleaning_pages_ = false;
699 clean_pages_done_cv_.NotifyAll();
700 });
701 WriteDirtyPagesAsync(min_bytes_to_write);
702
703 // One of the writes we initiated, or an earlier in-flight write may have hit an error.
704 RETURN_IF_ERROR(write_status_);
705
706 // Wait until enough writes have finished so that we can make the allocation without
707 // violating the eviction policy. I.e. so that other clients can immediately get the
708 // memory they're entitled to without waiting for this client's write to complete.
709 DCHECK_GE(in_flight_write_pages_.bytes(), min_bytes_to_write) << DebugStringLocked();
710 while (dirty_unpinned_pages_.bytes() + in_flight_write_pages_.bytes()
711 > target_dirty_bytes) {
712 SCOPED_TIMER(counters().write_wait_time);
713 write_complete_cv_.Wait(*client_lock);
714 RETURN_IF_ERROR(write_status_); // Check if error occurred while waiting.
715 }
716 return Status::OK();
717}
718
719void BufferPool::Client::WriteDirtyPagesAsync(int64_t min_bytes_to_write) {
720 DCHECK_GE(min_bytes_to_write, 0) << DebugStringLocked();

Callers

nothing calls this directly

Calls 6

OKFunction · 0.85
MakeScopeExitTriggerFunction · 0.85
bytesMethod · 0.80
NotifyAllMethod · 0.80
GetReservationMethod · 0.45
WaitMethod · 0.45

Tested by

no test coverage detected