]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/db/flush_scheduler.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / rocksdb / db / flush_scheduler.cc
CommitLineData
7c673cae 1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
11fdf7f2
TL
2// This source code is licensed under both the GPLv2 (found in the
3// COPYING file in the root directory) and Apache 2.0 License
4// (found in the LICENSE.Apache file in the root directory).
7c673cae
FG
5
6#include "db/flush_scheduler.h"
7
8#include <cassert>
9
10#include "db/column_family.h"
11
f67539c2 12namespace ROCKSDB_NAMESPACE {
7c673cae 13
f67539c2 14void FlushScheduler::ScheduleWork(ColumnFamilyData* cfd) {
7c673cae 15#ifndef NDEBUG
f67539c2
TL
16 {
17 std::lock_guard<std::mutex> lock(checking_mutex_);
18 assert(checking_set_.count(cfd) == 0);
19 checking_set_.insert(cfd);
20 }
7c673cae
FG
21#endif // NDEBUG
22 cfd->Ref();
23// Suppress false positive clang analyzer warnings.
24#ifndef __clang_analyzer__
25 Node* node = new Node{cfd, head_.load(std::memory_order_relaxed)};
26 while (!head_.compare_exchange_strong(
27 node->next, node, std::memory_order_relaxed, std::memory_order_relaxed)) {
28 // failing CAS updates the first param, so we are already set for
29 // retry. TakeNextColumnFamily won't happen until after another
30 // inter-thread synchronization, so we don't even need release
31 // semantics for this CAS
32 }
33#endif // __clang_analyzer__
34}
35
36ColumnFamilyData* FlushScheduler::TakeNextColumnFamily() {
37 while (true) {
11fdf7f2 38 if (head_.load(std::memory_order_relaxed) == nullptr) {
7c673cae
FG
39 return nullptr;
40 }
41
42 // dequeue the head
43 Node* node = head_.load(std::memory_order_relaxed);
44 head_.store(node->next, std::memory_order_relaxed);
45 ColumnFamilyData* cfd = node->column_family;
46 delete node;
47
48#ifndef NDEBUG
f67539c2
TL
49 {
50 std::lock_guard<std::mutex> lock(checking_mutex_);
51 auto iter = checking_set_.find(cfd);
52 assert(iter != checking_set_.end());
53 checking_set_.erase(iter);
54 }
7c673cae
FG
55#endif // NDEBUG
56
57 if (!cfd->IsDropped()) {
58 // success
59 return cfd;
60 }
61
62 // no longer relevant, retry
f67539c2 63 cfd->UnrefAndTryDelete();
7c673cae
FG
64 }
65}
66
67bool FlushScheduler::Empty() {
68 auto rv = head_.load(std::memory_order_relaxed) == nullptr;
11fdf7f2 69#ifndef NDEBUG
f67539c2
TL
70 std::lock_guard<std::mutex> lock(checking_mutex_);
71 // Empty is allowed to be called concurrnetly with ScheduleFlush. It would
72 // only miss the recent schedules.
73 assert((rv == checking_set_.empty()) || rv);
11fdf7f2 74#endif // NDEBUG
7c673cae
FG
75 return rv;
76}
77
78void FlushScheduler::Clear() {
79 ColumnFamilyData* cfd;
80 while ((cfd = TakeNextColumnFamily()) != nullptr) {
f67539c2 81 cfd->UnrefAndTryDelete();
7c673cae 82 }
11fdf7f2 83 assert(head_.load(std::memory_order_relaxed) == nullptr);
7c673cae
FG
84}
85
f67539c2 86} // namespace ROCKSDB_NAMESPACE