Disable IOStatsContext/PerfContext if no thread local (#8117)
Summary: Before this PR, `get_iostats_context()` will silently return a nullptr if no thread_local support is detected. This can be the result of build_detect_platform's failure to compile the simple code snippet on certain platforms, as reported in https://github.com/facebook/mysql-5.6/issues/904. To be safe, we should fail the compilation if user does not opt out IOStatsContext and ROCKSDB_SUPPORT_THREAD_LOCAL is not defined. If RocksDB relies on c++11, can we just always use thread_local? It turns out there might be performance concerns (https://github.com/facebook/rocksdb/issues/5774), which is beyond the scope of this PR. We can revisit this later. Here, we stick to the original impl. Pull Request resolved: https://github.com/facebook/rocksdb/pull/8117 Reviewed By: ajkr Differential Revision: D27356847 Pulled By: riversand963 fbshipit-source-id: f7d5776842277598d8341b955febb601946801ae
This commit is contained in:
parent
bb75092574
commit
fd00f39f97
@ -326,12 +326,23 @@ CHECK_CXX_SOURCE_COMPILES("
|
||||
#endif
|
||||
int main() {
|
||||
static __thread int tls;
|
||||
(void)tls;
|
||||
}
|
||||
" HAVE_THREAD_LOCAL)
|
||||
if(HAVE_THREAD_LOCAL)
|
||||
add_definitions(-DROCKSDB_SUPPORT_THREAD_LOCAL)
|
||||
endif()
|
||||
|
||||
option(WITH_IOSTATS_CONTEXT "Enable IO stats context" ON)
|
||||
if (NOT WITH_IOSTATS_CONTEXT)
|
||||
add_definitions(-DNIOSTATS_CONTEXT)
|
||||
endif()
|
||||
|
||||
option(WITH_PERF_CONTEXT "Enable perf context" ON)
|
||||
if (NOT WITH_PERF_CONTEXT)
|
||||
add_definitions(-DNPERF_CONTEXT)
|
||||
endif()
|
||||
|
||||
option(FAIL_ON_WARNINGS "Treat compile warnings as errors" ON)
|
||||
if(FAIL_ON_WARNINGS)
|
||||
if(MSVC)
|
||||
|
@ -4,6 +4,7 @@
|
||||
* `ColumnFamilyOptions::sample_for_compression` now takes effect for creation of all block-based tables. Previously it only took effect for block-based tables created by flush.
|
||||
* `CompactFiles()` can no longer compact files from lower level to up level, which has the risk to corrupt DB (details: #8063). The validation is also added to all compactions.
|
||||
* Fixed some cases in which DB::OpenForReadOnly() could write to the filesystem. If you want a Logger with a read-only DB, you must now set DBOptions::info_log yourself, such as using CreateLoggerFromOptions().
|
||||
* get_iostats_context() will never return nullptr. If thread-local support is not available, and user does not opt-out iostats context, then compilation will fail. The same applies to perf context as well.
|
||||
|
||||
### Bug Fixes
|
||||
* Use thread-safe `strerror_r()` to get error messages.
|
||||
|
@ -50,7 +50,15 @@ struct IOStatsContext {
|
||||
uint64_t cpu_read_nanos;
|
||||
};
|
||||
|
||||
// Get Thread-local IOStatsContext object pointer
|
||||
// If RocksDB is compiled with -DNIOSTATS_CONTEXT, then a pointer to a global,
|
||||
// non-thread-local IOStatsContext object will be returned. Attempts to update
|
||||
// this object will be ignored, and reading from it will also be no-op.
|
||||
// Otherwise,
|
||||
// a) if thread-local is supported on the platform, then a pointer to
|
||||
// a thread-local IOStatsContext object will be returned.
|
||||
// b) if thread-local is NOT supported, then compilation will fail.
|
||||
//
|
||||
// This function never returns nullptr.
|
||||
IOStatsContext* get_iostats_context();
|
||||
|
||||
} // namespace ROCKSDB_NAMESPACE
|
||||
|
@ -230,8 +230,15 @@ struct PerfContext {
|
||||
bool per_level_perf_context_enabled = false;
|
||||
};
|
||||
|
||||
// Get Thread-local PerfContext object pointer
|
||||
// if defined(NPERF_CONTEXT), then the pointer is not thread-local
|
||||
// If RocksDB is compiled with -DNPERF_CONTEXT, then a pointer to a global,
|
||||
// non-thread-local PerfContext object will be returned. Attempts to update
|
||||
// this object will be ignored, and reading from it will also be no-op.
|
||||
// Otherwise,
|
||||
// a) if thread-local is supported on the platform, then a pointer to
|
||||
// a thread-local PerfContext object will be returned.
|
||||
// b) if thread-local is NOT supported, then compilation will fail.
|
||||
//
|
||||
// This function never returns nullptr.
|
||||
PerfContext* get_perf_context();
|
||||
|
||||
} // namespace ROCKSDB_NAMESPACE
|
||||
|
@ -9,19 +9,23 @@
|
||||
|
||||
namespace ROCKSDB_NAMESPACE {
|
||||
|
||||
#ifdef ROCKSDB_SUPPORT_THREAD_LOCAL
|
||||
#ifdef NIOSTATS_CONTEXT
|
||||
// Should not be used because the counters are not thread-safe.
|
||||
// Put here just to make get_iostats_context() simple without ifdef.
|
||||
static IOStatsContext iostats_context;
|
||||
#elif defined(ROCKSDB_SUPPORT_THREAD_LOCAL)
|
||||
__thread IOStatsContext iostats_context;
|
||||
#else
|
||||
#error \
|
||||
"No thread-local support. Disable iostats context with -DNIOSTATS_CONTEXT."
|
||||
#endif
|
||||
|
||||
IOStatsContext* get_iostats_context() {
|
||||
#ifdef ROCKSDB_SUPPORT_THREAD_LOCAL
|
||||
return &iostats_context;
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void IOStatsContext::Reset() {
|
||||
#ifndef NIOSTATS_CONTEXT
|
||||
thread_pool_id = Env::Priority::TOTAL;
|
||||
bytes_read = 0;
|
||||
bytes_written = 0;
|
||||
@ -35,6 +39,7 @@ void IOStatsContext::Reset() {
|
||||
logger_nanos = 0;
|
||||
cpu_write_nanos = 0;
|
||||
cpu_read_nanos = 0;
|
||||
#endif //! NIOSTATS_CONTEXT
|
||||
}
|
||||
|
||||
#define IOSTATS_CONTEXT_OUTPUT(counter) \
|
||||
@ -43,6 +48,10 @@ void IOStatsContext::Reset() {
|
||||
}
|
||||
|
||||
std::string IOStatsContext::ToString(bool exclude_zero_counters) const {
|
||||
#ifdef NIOSTATS_CONTEXT
|
||||
(void)exclude_zero_counters;
|
||||
return "";
|
||||
#else
|
||||
std::ostringstream ss;
|
||||
IOSTATS_CONTEXT_OUTPUT(thread_pool_id);
|
||||
IOSTATS_CONTEXT_OUTPUT(bytes_read);
|
||||
@ -61,6 +70,7 @@ std::string IOStatsContext::ToString(bool exclude_zero_counters) const {
|
||||
std::string str = ss.str();
|
||||
str.erase(str.find_last_not_of(", ") + 1);
|
||||
return str;
|
||||
#endif //! NIOSTATS_CONTEXT
|
||||
}
|
||||
|
||||
} // namespace ROCKSDB_NAMESPACE
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "monitoring/perf_step_timer.h"
|
||||
#include "rocksdb/iostats_context.h"
|
||||
|
||||
#ifdef ROCKSDB_SUPPORT_THREAD_LOCAL
|
||||
#if defined(ROCKSDB_SUPPORT_THREAD_LOCAL) && !defined(NIOSTATS_CONTEXT)
|
||||
namespace ROCKSDB_NAMESPACE {
|
||||
extern __thread IOStatsContext iostats_context;
|
||||
} // namespace ROCKSDB_NAMESPACE
|
||||
@ -44,7 +44,7 @@ extern __thread IOStatsContext iostats_context;
|
||||
PerfLevel::kEnableTimeAndCPUTimeExceptForMutex); \
|
||||
iostats_step_timer_##metric.Start();
|
||||
|
||||
#else // ROCKSDB_SUPPORT_THREAD_LOCAL
|
||||
#else // ROCKSDB_SUPPORT_THREAD_LOCAL && !NIOSTATS_CONTEXT
|
||||
|
||||
#define IOSTATS_ADD(metric, value)
|
||||
#define IOSTATS_ADD_IF_POSITIVE(metric, value)
|
||||
@ -57,4 +57,4 @@ extern __thread IOStatsContext iostats_context;
|
||||
#define IOSTATS_TIMER_GUARD(metric)
|
||||
#define IOSTATS_CPU_TIMER_GUARD(metric, clock) static_cast<void>(clock)
|
||||
|
||||
#endif // ROCKSDB_SUPPORT_THREAD_LOCAL
|
||||
#endif // ROCKSDB_SUPPORT_THREAD_LOCAL && !NIOSTATS_CONTEXT
|
||||
|
@ -9,26 +9,22 @@
|
||||
|
||||
namespace ROCKSDB_NAMESPACE {
|
||||
|
||||
#if defined(NPERF_CONTEXT) || !defined(ROCKSDB_SUPPORT_THREAD_LOCAL)
|
||||
#if defined(NPERF_CONTEXT)
|
||||
// Should not be used because the counters are not thread-safe.
|
||||
// Put here just to make get_perf_context() simple without ifdef.
|
||||
PerfContext perf_context;
|
||||
#else
|
||||
#elif defined(ROCKSDB_SUPPORT_THREAD_LOCAL)
|
||||
#if defined(OS_SOLARIS)
|
||||
__thread PerfContext perf_context_;
|
||||
#else
|
||||
__thread PerfContext perf_context;
|
||||
#else // OS_SOLARIS
|
||||
thread_local PerfContext perf_context;
|
||||
#endif
|
||||
#endif // OS_SOLARIS
|
||||
#else
|
||||
#error "No thread-local support. Disable perf context with -DNPERF_CONTEXT."
|
||||
#endif
|
||||
|
||||
PerfContext* get_perf_context() {
|
||||
#if defined(NPERF_CONTEXT) || !defined(ROCKSDB_SUPPORT_THREAD_LOCAL)
|
||||
return &perf_context;
|
||||
#else
|
||||
#if defined(OS_SOLARIS)
|
||||
return &perf_context_;
|
||||
#else
|
||||
return &perf_context;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
PerfContext::~PerfContext() {
|
||||
|
Loading…
Reference in New Issue
Block a user