SecureValueRecovery2/enclave/context/context.cc
2023-05-05 16:25:12 -06:00

48 lines
1.3 KiB
C++

// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
#include "context/context.h"
#include "metrics/metrics.h"
#include "util/cpu.h"
namespace svr2::context {
Context::Context() : cpu_current_(nullptr), cpu_top_(nullptr, COUNTER(context, cpu_uncategorized)) {
cpu_top_.SetContext(this);
}
CPUMeasurement::CPUMeasurement(Context* ctx, metrics::Counter* counter)
: ctx_(nullptr), counter_(counter), ticks_(util::asm_rdtsc()) {
if (ctx != nullptr) {
SetContext(ctx);
}
}
CPUMeasurement::~CPUMeasurement() {
uint64_t ticks = util::asm_rdtsc();
counter_->IncrementBy(ticks - ticks_);
if (parent_ != nullptr) {
parent_->ticks_ = ticks;
}
ctx_->cpu_current_ = parent_;
}
void CPUMeasurement::SetContext(Context* ctx) {
CHECK(ctx_ == nullptr);
ctx_ = ctx;
parent_ = ctx_->cpu_current_;
ctx_->cpu_current_ = this;
if (parent_ != nullptr) {
// If there's a parent CPUMeasurement, increment its ticks-so-far.
// When we're destroyed, we'll push parent_->ticks_ forward so ticks
// during our lifetime are not double-counted.
parent_->counter_->IncrementBy(ticks_ - parent_->ticks_);
}
}
CPUMeasurement Context::MeasureCPU(metrics::Counter* counter) {
return CPUMeasurement(this, counter);
}
} // namespace svr2::context