Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
2752// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)2753auto fd = static_cast<int>(syscall(__NR_perf_event_open, &pea, pid, cpu, mFd, flags));2754if (-1 == fd) {2755return false;2756}2757if (-1 == mFd) {2758// first call: set to fd, and use this from now on2759mFd = fd;2760}2761uint64_t id = 0;2762// NOLINTNEXTLINE(hicpp-signed-bitwise,cppcoreguidelines-pro-type-vararg)2763if (-1 == ioctl(fd, PERF_EVENT_IOC_ID, &id)) {2764// couldn't get id2765return false;2766}2768// insert into map, rely on the fact that map's references are constant.2769mIdToTarget.emplace(id, target);2771// prepare readformat with the correct size (after the insert)2772auto size = 3 + 2 * mIdToTarget.size();2773mCounters.resize(size);2774mCalibratedOverhead.resize(size);2775mLoopOverhead.resize(size);2777return true;2778}2780PerformanceCounters::PerformanceCounters()2781: mPc(new LinuxPerformanceCounters())2782, mVal()2783, mHas() {2785// HW events2786mHas.cpuCycles = mPc->monitor(PERF_COUNT_HW_REF_CPU_CYCLES, LinuxPerformanceCounters::Target(&mVal.cpuCycles, true, false));2787if (!mHas.cpuCycles) {2788// Fallback to cycles counter, reference cycles not available in many systems.2789mHas.cpuCycles = mPc->monitor(PERF_COUNT_HW_CPU_CYCLES, LinuxPerformanceCounters::Target(&mVal.cpuCycles, true, false));2790}2791mHas.instructions = mPc->monitor(PERF_COUNT_HW_INSTRUCTIONS, LinuxPerformanceCounters::Target(&mVal.instructions, true, true));2792mHas.branchInstructions =2793mPc->monitor(PERF_COUNT_HW_BRANCH_INSTRUCTIONS, LinuxPerformanceCounters::Target(&mVal.branchInstructions, true, false));2794mHas.branchMisses = mPc->monitor(PERF_COUNT_HW_BRANCH_MISSES, LinuxPerformanceCounters::Target(&mVal.branchMisses, true, false));2795// mHas.branchMisses = false;2797// SW events2798mHas.pageFaults = mPc->monitor(PERF_COUNT_SW_PAGE_FAULTS, LinuxPerformanceCounters::Target(&mVal.pageFaults, true, false));2799mHas.contextSwitches =2800mPc->monitor(PERF_COUNT_SW_CONTEXT_SWITCHES, LinuxPerformanceCounters::Target(&mVal.contextSwitches, true, false));2802mPc->start();2803mPc->calibrate([] {2804auto before = ankerl::nanobench::Clock::now();2805auto after = ankerl::nanobench::Clock::now();2806(void)before;2807(void)after;2808});2810if (mPc->hasError()) {2811// something failed, don't monitor anything.2812mHas = PerfCountSet<bool>{};2813}2814}2816PerformanceCounters::~PerformanceCounters() {2817// no need to check for nullptr, delete nullptr has no effect2818delete mPc;2819}2821void PerformanceCounters::beginMeasure() {2822mPc->beginMeasure();2823}2825void PerformanceCounters::endMeasure() {2826mPc->endMeasure();2827}2829void PerformanceCounters::updateResults(uint64_t numIters) {2830mPc->updateResults(numIters);2831}2833# else2835PerformanceCounters::PerformanceCounters() = default;2836PerformanceCounters::~PerformanceCounters() = default;2837void PerformanceCounters::beginMeasure() {}2838void PerformanceCounters::endMeasure() {}2839void PerformanceCounters::updateResults(uint64_t) {}2841# endif2843ANKERL_NANOBENCH(NODISCARD) PerfCountSet<uint64_t> const& PerformanceCounters::val() const noexcept {2844return mVal;2845}2846ANKERL_NANOBENCH(NODISCARD) PerfCountSet<bool> const& PerformanceCounters::has() const noexcept {2847return mHas;2848}2850// formatting utilities2851namespace fmt {2853// adds thousands separator to numbers2854NumSep::NumSep(char sep)2855: mSep(sep) {}2857char NumSep::do_thousands_sep() const {2858return mSep;2859}2861std::string NumSep::do_grouping() const {2862return "\003";2863}2865// RAII to save & restore a stream's state2866StreamStateRestorer::StreamStateRestorer(std::ostream& s)2867: mStream(s)2868, mLocale(s.getloc())2869, mPrecision(s.precision())2870, mWidth(s.width())2871, mFill(s.fill())2872, mFmtFlags(s.flags()) {}2874StreamStateRestorer::~StreamStateRestorer() {2875restore();2876}2878// sets back all stream info that we remembered at construction2879void StreamStateRestorer::restore() {2880mStream.imbue(mLocale);2881mStream.precision(mPrecision);2882mStream.width(mWidth);2883mStream.fill(mFill);2884mStream.flags(mFmtFlags);2885}2887Number::Number(int width, int precision, int64_t value)2888: mWidth(width)2889, mPrecision(precision)2890, mValue(d(value)) {}2892Number::Number(int width, int precision, double value)2893: mWidth(width)2894, mPrecision(precision)2895, mValue(value) {}2897std::ostream& Number::write(std::ostream& os) const {2898StreamStateRestorer const restorer(os);2899os.imbue(std::locale(os.getloc(), new NumSep(',')));2900os << std::setw(mWidth) << std::setprecision(mPrecision) << std::fixed << mValue;2901return os;2902}2904std::string Number::to_s() const {2905std::stringstream ss;2906write(ss);2907return ss.str();2908}2910std::string to_s(uint64_t n) {2911std::string str;2912do {2913str += static_cast<char>('0' + static_cast<char>(n % 10));2914n /= 10;2915} while (n != 0);2916std::reverse(str.begin(), str.end());2917return str;2918}2920std::ostream& operator<<(std::ostream& os, Number const& n) {2921return n.write(os);2922}2924MarkDownColumn::MarkDownColumn(int w, int prec, std::string tit, std::string suff, double val) noexcept2925: mWidth(w)2926, mPrecision(prec)2927, mTitle(std::move(tit))2928, mSuffix(std::move(suff))2929, mValue(val) {}2931std::string MarkDownColumn::title() const {2932std::stringstream ss;2933ss << '|' << std::setw(mWidth - 2) << std::right << mTitle << ' ';2934return ss.str();2935}2937std::string MarkDownColumn::separator() const {2938std::string sep(static_cast<size_t>(mWidth), '-');2939sep.front() = '|';2940sep.back() = ':';2941return sep;2942}2944std::string MarkDownColumn::invalid() const {2945std::string sep(static_cast<size_t>(mWidth), ' ');2946sep.front() = '|';2947sep[sep.size() - 2] = '-';2948return sep;2949}2951std::string MarkDownColumn::value() const {2952std::stringstream ss;2953auto width = mWidth - 2 - static_cast<int>(mSuffix.size());2954ss << '|' << Number(width, mPrecision, mValue) << mSuffix << ' ';2955return ss.str();2956}2958// Formats any text as markdown code, escaping backticks.2959MarkDownCode::MarkDownCode(std::string const& what) {2960mWhat.reserve(what.size() + 2);2961mWhat.push_back('`');2962for (char const c : what) {2963mWhat.push_back(c);2964if ('`' == c) {2965mWhat.push_back('`');2966}2967}2968mWhat.push_back('`');2969}2971std::ostream& MarkDownCode::write(std::ostream& os) const {2972return os << mWhat;2973}2975std::ostream& operator<<(std::ostream& os, MarkDownCode const& mdCode) {2976return mdCode.write(os);2977}2978} // namespace fmt2979} // namespace detail2981// provide implementation here so it's only generated once2982Config::Config() = default;2983Config::~Config() = default;2984Config& Config::operator=(Config const&) = default;2985Config& Config::operator=(Config&&) noexcept(ANKERL_NANOBENCH(NOEXCEPT_STRING_MOVE)) = default;2986Config::Config(Config const&) = default;2987Config::Config(Config&&) noexcept = default;2989// provide implementation here so it's only generated once2990Result::~Result() = default;2991Result& Result::operator=(Result const&) = default;2992Result& Result::operator=(Result&&) noexcept(ANKERL_NANOBENCH(NOEXCEPT_STRING_MOVE)) = default;2993Result::Result(Result const&) = default;2994Result::Result(Result&&) noexcept = default;2996namespace detail {2997template <typename T>2998inline constexpr typename std::underlying_type<T>::type u(T val) noexcept {2999return static_cast<typename std::underlying_type<T>::type>(val);3000}
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.