From 71a59d20e068dae48f37f4085fe5783667784cfb Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Sat, 21 Sep 2019 12:13:24 -0700 Subject: [PATCH] ircd::prof: Add a scope_cycles utility device. --- include/ircd/prof/prof.h | 1 + include/ircd/prof/scope_cycles.h | 63 ++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 include/ircd/prof/scope_cycles.h diff --git a/include/ircd/prof/prof.h b/include/ircd/prof/prof.h index 7a38e9d91..a1c577460 100644 --- a/include/ircd/prof/prof.h +++ b/include/ircd/prof/prof.h @@ -35,6 +35,7 @@ namespace ircd::prof #include "x86.h" #include "vg.h" #include "type.h" +#include "scope_cycles.h" #include "syscall_timer.h" #include "instructions.h" #include "resource.h" diff --git a/include/ircd/prof/scope_cycles.h b/include/ircd/prof/scope_cycles.h new file mode 100644 index 000000000..472dc2a7a --- /dev/null +++ b/include/ircd/prof/scope_cycles.h @@ -0,0 +1,63 @@ +// Matrix Construct +// +// Copyright (C) Matrix Construct Developers, Authors & Contributors +// Copyright (C) 2016-2019 Jason Volk +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice is present in all copies. The +// full license for this software is available in the LICENSE file. + +#pragma once +#define HAVE_IRCD_PROF_SCOPE_CYCLES_H + +namespace ircd::prof +{ + struct scope_cycles; +} + +/// Count the reference cycles for a scope using the lifetime of this object. +/// The result is stored in `result`. Note that `result` is also used while +/// this object is operating. +struct ircd::prof::scope_cycles +{ + uint64_t &result; + + scope_cycles(uint64_t &result) noexcept; + ~scope_cycles() noexcept; +}; + +extern inline +__attribute__((flatten, always_inline, gnu_inline, artificial)) +ircd::prof::scope_cycles::scope_cycles(uint64_t &result) +noexcept +:result{result} +{ + #if defined(__x86_64__) || defined(__i386__) + asm volatile ("mfence"); + asm volatile ("lfence"); + #endif + + result = cycles(); + + #if defined(__x86_64__) || defined(__i386__) + asm volatile ("lfence"); + #endif +} + +extern inline +__attribute__((flatten, always_inline, gnu_inline, artificial)) +ircd::prof::scope_cycles::~scope_cycles() +noexcept +{ + #if defined(__x86_64__) || defined(__i386__) + asm volatile ("mfence"); + asm volatile ("lfence"); + #endif + + result = cycles() - result; + + #if defined(__x86_64__) || defined(__i386__) + asm volatile ("lfence"); + #endif +}