1 //  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
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).
5 
6 #include "test_util/sync_point.h"
7 
8 #include <assert.h>
9 #include <atomic>
10 #include <condition_variable>
11 #include <functional>
12 #include <mutex>
13 #include <string>
14 #include <thread>
15 #include <unordered_map>
16 #include <unordered_set>
17 
18 #include "port/port.h"
19 #include "util/random.h"
20 
21 #pragma once
22 
23 #ifndef NDEBUG
24 namespace ROCKSDB_NAMESPACE {
25 struct SyncPoint::Data {
DataData26   Data() : enabled_(false) {}
27   // Enable proper deletion by subclasses
~DataData28   virtual ~Data() {}
29   // successor/predecessor map loaded from LoadDependency
30   std::unordered_map<std::string, std::vector<std::string>> successors_;
31   std::unordered_map<std::string, std::vector<std::string>> predecessors_;
32   std::unordered_map<std::string, std::function<void(void*)> > callbacks_;
33   std::unordered_map<std::string, std::vector<std::string> > markers_;
34   std::unordered_map<std::string, std::thread::id> marked_thread_id_;
35 
36   std::mutex              mutex_;
37   std::condition_variable cv_;
38   // sync points that have been passed through
39   std::unordered_set<std::string> cleared_points_;
40   std::atomic<bool> enabled_;
41   int num_callbacks_running_ = 0;
42 
43   void LoadDependency(const std::vector<SyncPointPair>& dependencies);
44   void LoadDependencyAndMarkers(const std::vector<SyncPointPair>& dependencies,
45     const std::vector<SyncPointPair>& markers);
46   bool PredecessorsAllCleared(const std::string& point);
SetCallBackData47   void SetCallBack(const std::string& point,
48     const std::function<void(void*)>& callback) {
49   std::lock_guard<std::mutex> lock(mutex_);
50   callbacks_[point] = callback;
51 }
52 
53   void ClearCallBack(const std::string& point);
54   void ClearAllCallBacks();
EnableProcessingData55   void EnableProcessing() {
56     enabled_ = true;
57   }
DisableProcessingData58   void DisableProcessing() {
59     enabled_ = false;
60   }
ClearTraceData61   void ClearTrace() {
62     std::lock_guard<std::mutex> lock(mutex_);
63     cleared_points_.clear();
64   }
DisabledByMarkerData65   bool DisabledByMarker(const std::string& point,
66                         std::thread::id thread_id) {
67     auto marked_point_iter = marked_thread_id_.find(point);
68     return marked_point_iter != marked_thread_id_.end() &&
69            thread_id != marked_point_iter->second;
70   }
71   void Process(const std::string& point, void* cb_arg);
72 };
73 }  // namespace ROCKSDB_NAMESPACE
74 #endif // NDEBUG
75