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 #pragma once 7 8 #include <string> 9 10 #include "monitoring/thread_status_updater.h" 11 #include "rocksdb/db.h" 12 #include "rocksdb/env.h" 13 #include "rocksdb/thread_status.h" 14 15 namespace ROCKSDB_NAMESPACE { 16 17 class ColumnFamilyData; 18 19 // The static utility class for updating thread-local status. 20 // 21 // The thread-local status is updated via the thread-local cached 22 // pointer thread_updater_local_cache_. During each function call, 23 // when ThreadStatusUtil finds thread_updater_local_cache_ is 24 // left uninitialized (determined by thread_updater_initialized_), 25 // it will tries to initialize it using the return value of 26 // Env::GetThreadStatusUpdater(). When thread_updater_local_cache_ 27 // is initialized by a non-null pointer, each function call will 28 // then update the status of the current thread. Otherwise, 29 // all function calls to ThreadStatusUtil will be no-op. 30 class ThreadStatusUtil { 31 public: 32 // Register the current thread for tracking. 33 static void RegisterThread( 34 const Env* env, ThreadStatus::ThreadType thread_type); 35 36 // Unregister the current thread. 37 static void UnregisterThread(); 38 39 // Create an entry in the global ColumnFamilyInfo table for the 40 // specified column family. This function should be called only 41 // when the current thread does not hold db_mutex. 42 static void NewColumnFamilyInfo(const DB* db, const ColumnFamilyData* cfd, 43 const std::string& cf_name, const Env* env); 44 45 // Erase the ConstantColumnFamilyInfo that is associated with the 46 // specified ColumnFamilyData. This function should be called only 47 // when the current thread does not hold db_mutex. 48 static void EraseColumnFamilyInfo(const ColumnFamilyData* cfd); 49 50 // Erase all ConstantColumnFamilyInfo that is associated with the 51 // specified db instance. This function should be called only when 52 // the current thread does not hold db_mutex. 53 static void EraseDatabaseInfo(const DB* db); 54 55 // Update the thread status to indicate the current thread is doing 56 // something related to the specified column family. 57 static void SetColumnFamily(const ColumnFamilyData* cfd, const Env* env, 58 bool enable_thread_tracking); 59 60 static void SetThreadOperation(ThreadStatus::OperationType type); 61 62 static ThreadStatus::OperationStage SetThreadOperationStage( 63 ThreadStatus::OperationStage stage); 64 65 static void SetThreadOperationProperty( 66 int code, uint64_t value); 67 68 static void IncreaseThreadOperationProperty( 69 int code, uint64_t delta); 70 71 static void SetThreadState(ThreadStatus::StateType type); 72 73 static void ResetThreadStatus(); 74 75 #ifndef NDEBUG 76 static void TEST_SetStateDelay( 77 const ThreadStatus::StateType state, int micro); 78 static void TEST_StateDelay(const ThreadStatus::StateType state); 79 #endif 80 81 protected: 82 // Initialize the thread-local ThreadStatusUpdater when it finds 83 // the cached value is nullptr. Returns true if it has cached 84 // a non-null pointer. 85 static bool MaybeInitThreadLocalUpdater(const Env* env); 86 87 #ifdef ROCKSDB_USING_THREAD_STATUS 88 // A boolean flag indicating whether thread_updater_local_cache_ 89 // is initialized. It is set to true when an Env uses any 90 // ThreadStatusUtil functions using the current thread other 91 // than UnregisterThread(). It will be set to false when 92 // UnregisterThread() is called. 93 // 94 // When this variable is set to true, thread_updater_local_cache_ 95 // will not be updated until this variable is again set to false 96 // in UnregisterThread(). 97 static __thread bool thread_updater_initialized_; 98 99 // The thread-local cached ThreadStatusUpdater that caches the 100 // thread_status_updater_ of the first Env that uses any ThreadStatusUtil 101 // function other than UnregisterThread(). This variable will 102 // be cleared when UnregisterThread() is called. 103 // 104 // When this variable is set to a non-null pointer, then the status 105 // of the current thread will be updated when a function of 106 // ThreadStatusUtil is called. Otherwise, all functions of 107 // ThreadStatusUtil will be no-op. 108 // 109 // When thread_updater_initialized_ is set to true, this variable 110 // will not be updated until this thread_updater_initialized_ is 111 // again set to false in UnregisterThread(). 112 static __thread ThreadStatusUpdater* thread_updater_local_cache_; 113 #else 114 static bool thread_updater_initialized_; 115 static ThreadStatusUpdater* thread_updater_local_cache_; 116 #endif 117 }; 118 119 // A helper class for updating thread state. It will set the 120 // thread state according to the input parameter in its constructor 121 // and set the thread state to the previous state in its destructor. 122 class AutoThreadOperationStageUpdater { 123 public: 124 explicit AutoThreadOperationStageUpdater( 125 ThreadStatus::OperationStage stage); 126 ~AutoThreadOperationStageUpdater(); 127 128 #ifdef ROCKSDB_USING_THREAD_STATUS 129 private: 130 ThreadStatus::OperationStage prev_stage_; 131 #endif 132 }; 133 134 } // namespace ROCKSDB_NAMESPACE 135