rocksdb/util/thread_status_util.cc
Yueh-Hsuan Chiang 89597bb66b Allow GetThreadList() to report the start time of the current operation.
Summary: Allow GetThreadList() to report the start time of the current operation.

Test Plan:
./db_bench --benchmarks=fillrandom --num=100000 --threads=40 \
  --max_background_compactions=10 --max_background_flushes=3 \
  --thread_status_per_interval=1000 --key_size=16 --value_size=1000 \
  --num_column_families=10

Sample output:
          ThreadID ThreadType                    cfName    Operation        OP_StartTime         State
   140338840797248   High Pri column_family_name_000003        Flush 2015/03/09-17:49:59
   140338844991552   High Pri column_family_name_000004        Flush 2015/03/09-17:49:59
   140338849185856    Low Pri
   140338983403584    Low Pri
   140339008569408    Low Pri
   140338861768768    Low Pri
   140338924683328    Low Pri
   140338899517504    Low Pri
   140338853380160    Low Pri
   140338882740288    Low Pri
   140338865963072   High Pri column_family_name_000006        Flush 2015/03/09-17:49:59
   140338954043456    Low Pri
   140338857574464    Low Pri

Reviewers: igor, rven, sdong

Reviewed By: sdong

Subscribers: lgalanis, dhruba, leveldb

Differential Revision: https://reviews.facebook.net/D34689
2015-03-10 14:51:28 -07:00

156 lines
4.6 KiB
C++

// Copyright (c) 2013, Facebook, Inc. All rights reserved.
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree. An additional grant
// of patent rights can be found in the PATENTS file in the same directory.
#include "rocksdb/env.h"
#include "util/thread_status_updater.h"
#include "util/thread_status_util.h"
namespace rocksdb {
#if ROCKSDB_USING_THREAD_STATUS
__thread ThreadStatusUpdater*
ThreadStatusUtil::thread_updater_local_cache_ = nullptr;
__thread bool ThreadStatusUtil::thread_updater_initialized_ = false;
void ThreadStatusUtil::SetThreadType(
const Env* env, ThreadStatus::ThreadType thread_type) {
if (!MaybeInitThreadLocalUpdater(env)) {
return;
}
assert(thread_updater_local_cache_);
thread_updater_local_cache_->SetThreadType(thread_type);
}
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) {
if (!MaybeInitThreadLocalUpdater(cfd->ioptions()->env)) {
return;
}
assert(thread_updater_local_cache_);
if (cfd != nullptr && cfd->options()->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) {
int64_t current_time = 0;
Env::Default()->GetCurrentTime(&current_time);
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);
}
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) {
if (!MaybeInitThreadLocalUpdater(cfd->ioptions()->env)) {
return;
}
assert(thread_updater_local_cache_);
if (thread_updater_local_cache_) {
thread_updater_local_cache_->NewColumnFamilyInfo(
db, db->GetName(), cfd, cfd->GetName());
}
}
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) {
if (thread_updater_local_cache_ == nullptr) {
return;
}
thread_updater_local_cache_->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);
}
#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) {
}
void ThreadStatusUtil::SetThreadOperation(ThreadStatus::OperationType op) {
}
void ThreadStatusUtil::SetThreadState(ThreadStatus::StateType state) {
}
void ThreadStatusUtil::NewColumnFamilyInfo(
const DB* db, const ColumnFamilyData* cfd) {
}
void ThreadStatusUtil::EraseColumnFamilyInfo(
const ColumnFamilyData* cfd) {
}
void ThreadStatusUtil::EraseDatabaseInfo(const DB* db) {
}
void ThreadStatusUtil::ResetThreadStatus() {
}
#endif // ROCKSDB_USING_THREAD_STATUS
} // namespace rocksdb