summaryrefslogtreecommitdiff
path: root/src/mongo/db/operation_cpu_timer.cpp
diff options
context:
space:
mode:
authorAmirsaman Memaripour <amirsaman.memaripour@mongodb.com>2020-10-14 19:35:32 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-11-19 22:01:23 +0000
commit4739fb232284a655f0ae89c9a43490ed2219cb5e (patch)
tree7e26424d85e12344d0965193d259dd6c7c268a59 /src/mongo/db/operation_cpu_timer.cpp
parent48fcb9bd106ca5e6a5a361a8a51992392ee8b335 (diff)
downloadmongo-4739fb232284a655f0ae89c9a43490ed2219cb5e.tar.gz
SERVER-51601 Make OperationCPUTimer initializer more resilient
Diffstat (limited to 'src/mongo/db/operation_cpu_timer.cpp')
-rw-r--r--src/mongo/db/operation_cpu_timer.cpp43
1 files changed, 33 insertions, 10 deletions
diff --git a/src/mongo/db/operation_cpu_timer.cpp b/src/mongo/db/operation_cpu_timer.cpp
index 7627c8af11c..34cb63eb3d4 100644
--- a/src/mongo/db/operation_cpu_timer.cpp
+++ b/src/mongo/db/operation_cpu_timer.cpp
@@ -27,6 +27,8 @@
* it in the license file.
*/
+#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kDefault
+
#include <boost/optional.hpp>
#include <fmt/format.h>
@@ -39,6 +41,7 @@
#include "mongo/base/error_codes.h"
#include "mongo/db/client.h"
#include "mongo/db/operation_context.h"
+#include "mongo/logv2/log.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/errno_util.h"
@@ -46,11 +49,22 @@
namespace mongo {
+using namespace fmt::literals;
+
#if defined(__linux__)
namespace {
-using namespace fmt::literals;
+// Reads the thread timer, and throws with `InternalError` if that fails.
+Nanoseconds getThreadCPUTime() {
+ struct timespec t;
+ if (auto ret = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t); ret != 0) {
+ int ec = errno;
+ internalAssert(Status(ErrorCodes::InternalError,
+ "Unable to get time: {}"_format(errnoWithDescription(ec))));
+ }
+ return Seconds(t.tv_sec) + Nanoseconds(t.tv_nsec);
+}
MONGO_FAIL_POINT_DEFINE(hangCPUTimerAfterOnThreadAttach);
MONGO_FAIL_POINT_DEFINE(hangCPUTimerAfterOnThreadDetach);
@@ -132,14 +146,13 @@ void PosixTimer::onThreadDetach() {
hangCPUTimerAfterOnThreadDetach.pauseWhileSet();
}
-Nanoseconds PosixTimer::_getThreadTime() const {
- struct timespec t;
- if (auto ret = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t); ret != 0) {
- int ec = errno;
- internalAssert(Status(ErrorCodes::InternalError,
- "Unable to get time: {}"_format(errnoWithDescription(ec))));
- }
- return Seconds(t.tv_sec) + Nanoseconds(t.tv_nsec);
+Nanoseconds PosixTimer::_getThreadTime() const try {
+ return getThreadCPUTime();
+} catch (const ExceptionFor<ErrorCodes::InternalError>& ex) {
+ // Abort the process as the timer cannot account for the elapsed time. This path is only
+ // reachable if the platform supports CPU time measurement at startup, but returns an error
+ // for a subsequent attempt to get thread-specific CPU consumption.
+ LOGV2_FATAL(4744601, "Failed to read the CPU time for the current thread", "error"_attr = ex);
}
static auto getCPUTimer = OperationContext::declareDecoration<PosixTimer>();
@@ -154,7 +167,17 @@ OperationCPUTimer* OperationCPUTimer::get(OperationContext* opCtx) {
// of SMP systems.
static bool isTimeSupported = [] {
clockid_t cid;
- return clock_getcpuclockid(0, &cid) == 0;
+ if (clock_getcpuclockid(0, &cid) != 0)
+ return false;
+
+ try {
+ getThreadCPUTime();
+ } catch (const ExceptionFor<ErrorCodes::InternalError>&) {
+ // Unable to collect the CPU time for the current thread.
+ return false;
+ }
+
+ return true;
}();
if (!isTimeSupported)