| // 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 "monitoring/thread_status_util.h" |
| |
| #include "monitoring/thread_status_updater.h" |
| #include "rocksdb/env.h" |
| |
| namespace rocksdb { |
| |
| |
| #ifdef ROCKSDB_USING_THREAD_STATUS |
| __thread ThreadStatusUpdater* |
| ThreadStatusUtil::thread_updater_local_cache_ = nullptr; |
| __thread bool ThreadStatusUtil::thread_updater_initialized_ = false; |
| |
| void ThreadStatusUtil::RegisterThread( |
| const Env* env, ThreadStatus::ThreadType thread_type) { |
| if (!MaybeInitThreadLocalUpdater(env)) { |
| return; |
| } |
| assert(thread_updater_local_cache_); |
| thread_updater_local_cache_->RegisterThread( |
| thread_type, env->GetThreadID()); |
| } |
| |
| void ThreadStatusUtil::UnregisterThread() { |
| thread_updater_initialized_ = false; |
| if (thread_updater_local_cache_ != nullptr) { |
| thread_updater_local_cache_->UnregisterThread(); |
| thread_updater_local_cache_ = nullptr; |
| } |
| } |
| |
| void ThreadStatusUtil::SetColumnFamily(const ColumnFamilyData* cfd, |
| const Env* env, |
| bool enable_thread_tracking) { |
| if (!MaybeInitThreadLocalUpdater(env)) { |
| return; |
| } |
| assert(thread_updater_local_cache_); |
| if (cfd != nullptr && enable_thread_tracking) { |
| thread_updater_local_cache_->SetColumnFamilyInfoKey(cfd); |
| } else { |
| // When cfd == nullptr or enable_thread_tracking == false, we set |
| // ColumnFamilyInfoKey to nullptr, which makes SetThreadOperation |
| // and SetThreadState become no-op. |
| thread_updater_local_cache_->SetColumnFamilyInfoKey(nullptr); |
| } |
| } |
| |
| void ThreadStatusUtil::SetThreadOperation(ThreadStatus::OperationType op) { |
| if (thread_updater_local_cache_ == nullptr) { |
| // thread_updater_local_cache_ must be set in SetColumnFamily |
| // or other ThreadStatusUtil functions. |
| return; |
| } |
| |
| if (op != ThreadStatus::OP_UNKNOWN) { |
| uint64_t current_time = Env::Default()->NowMicros(); |
| thread_updater_local_cache_->SetOperationStartTime(current_time); |
| } else { |
| // TDOO(yhchiang): we could report the time when we set operation to |
| // OP_UNKNOWN once the whole instrumentation has been done. |
| thread_updater_local_cache_->SetOperationStartTime(0); |
| } |
| thread_updater_local_cache_->SetThreadOperation(op); |
| } |
| |
| ThreadStatus::OperationStage ThreadStatusUtil::SetThreadOperationStage( |
| ThreadStatus::OperationStage stage) { |
| if (thread_updater_local_cache_ == nullptr) { |
| // thread_updater_local_cache_ must be set in SetColumnFamily |
| // or other ThreadStatusUtil functions. |
| return ThreadStatus::STAGE_UNKNOWN; |
| } |
| |
| return thread_updater_local_cache_->SetThreadOperationStage(stage); |
| } |
| |
| void ThreadStatusUtil::SetThreadOperationProperty( |
| int code, uint64_t value) { |
| if (thread_updater_local_cache_ == nullptr) { |
| // thread_updater_local_cache_ must be set in SetColumnFamily |
| // or other ThreadStatusUtil functions. |
| return; |
| } |
| |
| thread_updater_local_cache_->SetThreadOperationProperty( |
| code, value); |
| } |
| |
| void ThreadStatusUtil::IncreaseThreadOperationProperty( |
| int code, uint64_t delta) { |
| if (thread_updater_local_cache_ == nullptr) { |
| // thread_updater_local_cache_ must be set in SetColumnFamily |
| // or other ThreadStatusUtil functions. |
| return; |
| } |
| |
| thread_updater_local_cache_->IncreaseThreadOperationProperty( |
| code, delta); |
| } |
| |
| void ThreadStatusUtil::SetThreadState(ThreadStatus::StateType state) { |
| if (thread_updater_local_cache_ == nullptr) { |
| // thread_updater_local_cache_ must be set in SetColumnFamily |
| // or other ThreadStatusUtil functions. |
| return; |
| } |
| |
| thread_updater_local_cache_->SetThreadState(state); |
| } |
| |
| void ThreadStatusUtil::ResetThreadStatus() { |
| if (thread_updater_local_cache_ == nullptr) { |
| return; |
| } |
| thread_updater_local_cache_->ResetThreadStatus(); |
| } |
| |
| void ThreadStatusUtil::NewColumnFamilyInfo(const DB* db, |
| const ColumnFamilyData* cfd, |
| const std::string& cf_name, |
| const Env* env) { |
| if (!MaybeInitThreadLocalUpdater(env)) { |
| return; |
| } |
| assert(thread_updater_local_cache_); |
| if (thread_updater_local_cache_) { |
| thread_updater_local_cache_->NewColumnFamilyInfo(db, db->GetName(), cfd, |
| cf_name); |
| } |
| } |
| |
| void ThreadStatusUtil::EraseColumnFamilyInfo( |
| const ColumnFamilyData* cfd) { |
| if (thread_updater_local_cache_ == nullptr) { |
| return; |
| } |
| thread_updater_local_cache_->EraseColumnFamilyInfo(cfd); |
| } |
| |
| void ThreadStatusUtil::EraseDatabaseInfo(const DB* db) { |
| ThreadStatusUpdater* thread_updater = db->GetEnv()->GetThreadStatusUpdater(); |
| if (thread_updater == nullptr) { |
| return; |
| } |
| thread_updater->EraseDatabaseInfo(db); |
| } |
| |
| bool ThreadStatusUtil::MaybeInitThreadLocalUpdater(const Env* env) { |
| if (!thread_updater_initialized_ && env != nullptr) { |
| thread_updater_initialized_ = true; |
| thread_updater_local_cache_ = env->GetThreadStatusUpdater(); |
| } |
| return (thread_updater_local_cache_ != nullptr); |
| } |
| |
| AutoThreadOperationStageUpdater::AutoThreadOperationStageUpdater( |
| ThreadStatus::OperationStage stage) { |
| prev_stage_ = ThreadStatusUtil::SetThreadOperationStage(stage); |
| } |
| |
| AutoThreadOperationStageUpdater::~AutoThreadOperationStageUpdater() { |
| ThreadStatusUtil::SetThreadOperationStage(prev_stage_); |
| } |
| |
| #else |
| |
| ThreadStatusUpdater* ThreadStatusUtil::thread_updater_local_cache_ = nullptr; |
| bool ThreadStatusUtil::thread_updater_initialized_ = false; |
| |
| bool ThreadStatusUtil::MaybeInitThreadLocalUpdater(const Env* env) { |
| return false; |
| } |
| |
| void ThreadStatusUtil::SetColumnFamily(const ColumnFamilyData* cfd, |
| const Env* env, |
| bool enable_thread_tracking) {} |
| |
| void ThreadStatusUtil::SetThreadOperation(ThreadStatus::OperationType op) { |
| } |
| |
| void ThreadStatusUtil::SetThreadOperationProperty( |
| int code, uint64_t value) { |
| } |
| |
| void ThreadStatusUtil::IncreaseThreadOperationProperty( |
| int code, uint64_t delta) { |
| } |
| |
| void ThreadStatusUtil::SetThreadState(ThreadStatus::StateType state) { |
| } |
| |
| void ThreadStatusUtil::NewColumnFamilyInfo(const DB* db, |
| const ColumnFamilyData* cfd, |
| const std::string& cf_name, |
| const Env* env) {} |
| |
| void ThreadStatusUtil::EraseColumnFamilyInfo( |
| const ColumnFamilyData* cfd) { |
| } |
| |
| void ThreadStatusUtil::EraseDatabaseInfo(const DB* db) { |
| } |
| |
| void ThreadStatusUtil::ResetThreadStatus() { |
| } |
| |
| AutoThreadOperationStageUpdater::AutoThreadOperationStageUpdater( |
| ThreadStatus::OperationStage stage) { |
| } |
| |
| AutoThreadOperationStageUpdater::~AutoThreadOperationStageUpdater() { |
| } |
| |
| #endif // ROCKSDB_USING_THREAD_STATUS |
| |
| } // namespace rocksdb |