2018-03-23 19:48:45 +00:00
|
|
|
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
|
|
|
// This source code is licensed under both the GPLv2 (found in the
|
|
|
|
// COPYING file in the root directory) and Apache 2.0 License
|
|
|
|
// (found in the LICENSE.Apache file in the root directory).
|
|
|
|
|
|
|
|
#include <assert.h>
|
2021-05-27 20:13:18 +00:00
|
|
|
|
2018-06-13 20:03:09 +00:00
|
|
|
#include <atomic>
|
2018-03-23 19:48:45 +00:00
|
|
|
#include <condition_variable>
|
|
|
|
#include <functional>
|
|
|
|
#include <mutex>
|
|
|
|
#include <string>
|
|
|
|
#include <thread>
|
|
|
|
#include <unordered_map>
|
|
|
|
#include <unordered_set>
|
|
|
|
|
2021-05-27 20:13:18 +00:00
|
|
|
#include "memory/concurrent_arena.h"
|
2018-03-23 19:48:45 +00:00
|
|
|
#include "port/port.h"
|
2021-05-27 20:13:18 +00:00
|
|
|
#include "test_util/sync_point.h"
|
|
|
|
#include "util/dynamic_bloom.h"
|
2018-03-23 19:48:45 +00:00
|
|
|
#include "util/random.h"
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
2020-02-20 20:07:53 +00:00
|
|
|
namespace ROCKSDB_NAMESPACE {
|
2021-05-27 20:13:18 +00:00
|
|
|
// A hacky allocator for single use.
|
|
|
|
// Arena depends on SyncPoint and create circular dependency.
|
|
|
|
class SingleAllocator : public Allocator {
|
|
|
|
public:
|
|
|
|
char* Allocate(size_t) override {
|
|
|
|
assert(false);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
char* AllocateAligned(size_t bytes, size_t, Logger*) override {
|
|
|
|
buf_.resize(bytes);
|
|
|
|
return const_cast<char*>(buf_.data());
|
|
|
|
}
|
|
|
|
size_t BlockSize() const override {
|
|
|
|
assert(false);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
std::string buf_;
|
|
|
|
};
|
|
|
|
|
2018-03-23 19:48:45 +00:00
|
|
|
struct SyncPoint::Data {
|
2021-05-27 20:13:18 +00:00
|
|
|
Data() : point_filter_(&alloc_, /*total_bits=*/8192), enabled_(false) {}
|
2018-03-23 19:48:45 +00:00
|
|
|
// Enable proper deletion by subclasses
|
|
|
|
virtual ~Data() {}
|
|
|
|
// successor/predecessor map loaded from LoadDependency
|
|
|
|
std::unordered_map<std::string, std::vector<std::string>> successors_;
|
|
|
|
std::unordered_map<std::string, std::vector<std::string>> predecessors_;
|
|
|
|
std::unordered_map<std::string, std::function<void(void*)> > callbacks_;
|
|
|
|
std::unordered_map<std::string, std::vector<std::string> > markers_;
|
|
|
|
std::unordered_map<std::string, std::thread::id> marked_thread_id_;
|
|
|
|
|
|
|
|
std::mutex mutex_;
|
|
|
|
std::condition_variable cv_;
|
|
|
|
// sync points that have been passed through
|
|
|
|
std::unordered_set<std::string> cleared_points_;
|
2021-05-27 20:13:18 +00:00
|
|
|
SingleAllocator alloc_;
|
|
|
|
// A filter before holding mutex to speed up process.
|
|
|
|
DynamicBloom point_filter_;
|
2018-06-13 20:03:09 +00:00
|
|
|
std::atomic<bool> enabled_;
|
2018-03-23 19:48:45 +00:00
|
|
|
int num_callbacks_running_ = 0;
|
|
|
|
|
|
|
|
void LoadDependency(const std::vector<SyncPointPair>& dependencies);
|
|
|
|
void LoadDependencyAndMarkers(const std::vector<SyncPointPair>& dependencies,
|
|
|
|
const std::vector<SyncPointPair>& markers);
|
|
|
|
bool PredecessorsAllCleared(const std::string& point);
|
|
|
|
void SetCallBack(const std::string& point,
|
|
|
|
const std::function<void(void*)>& callback) {
|
|
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
|
|
callbacks_[point] = callback;
|
2021-05-27 20:13:18 +00:00
|
|
|
point_filter_.Add(point);
|
2018-03-23 19:48:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ClearCallBack(const std::string& point);
|
|
|
|
void ClearAllCallBacks();
|
|
|
|
void EnableProcessing() {
|
|
|
|
enabled_ = true;
|
|
|
|
}
|
|
|
|
void DisableProcessing() {
|
|
|
|
enabled_ = false;
|
|
|
|
}
|
|
|
|
void ClearTrace() {
|
|
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
|
|
cleared_points_.clear();
|
|
|
|
}
|
|
|
|
bool DisabledByMarker(const std::string& point,
|
|
|
|
std::thread::id thread_id) {
|
|
|
|
auto marked_point_iter = marked_thread_id_.find(point);
|
|
|
|
return marked_point_iter != marked_thread_id_.end() &&
|
|
|
|
thread_id != marked_point_iter->second;
|
|
|
|
}
|
2021-10-15 20:05:17 +00:00
|
|
|
void Process(const Slice& point, void* cb_arg);
|
2018-03-23 19:48:45 +00:00
|
|
|
};
|
2020-02-20 20:07:53 +00:00
|
|
|
} // namespace ROCKSDB_NAMESPACE
|
2018-03-23 19:48:45 +00:00
|
|
|
#endif // NDEBUG
|