2019-04-01 03:04:11 +02:00
|
|
|
// Matrix Construct
|
|
|
|
//
|
|
|
|
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
|
|
|
// Copyright (C) 2016-2019 Jason Volk <jason@zemos.net>
|
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
|
2019-04-03 22:16:05 +02:00
|
|
|
#include <RB_INC_SYS_SYSCALL_H
|
|
|
|
#include <RB_INC_SYS_IOCTL_H
|
|
|
|
#include <RB_INC_SYS_MMAN_H
|
2019-04-08 00:34:39 +02:00
|
|
|
#include <RB_INC_SYS_RESOURCE_H
|
2019-07-31 23:06:13 +02:00
|
|
|
|
2019-04-06 01:56:51 +02:00
|
|
|
#include <boost/chrono/chrono.hpp>
|
|
|
|
#include <boost/chrono/process_cpu_clocks.hpp>
|
2019-04-03 22:16:05 +02:00
|
|
|
|
2020-03-07 00:30:32 +01:00
|
|
|
decltype(ircd::prof::log)
|
|
|
|
ircd::prof::log
|
|
|
|
{
|
|
|
|
"prof"
|
|
|
|
};
|
|
|
|
|
2020-05-10 02:03:27 +02:00
|
|
|
#ifndef __linux__
|
|
|
|
[[gnu::weak]]
|
|
|
|
decltype(ircd::prof::psi::supported)
|
|
|
|
ircd::prof::psi::supported
|
|
|
|
{
|
|
|
|
false
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2019-07-31 23:06:13 +02:00
|
|
|
uint64_t
|
|
|
|
ircd::prof::time_real()
|
2019-08-06 01:15:56 +02:00
|
|
|
noexcept
|
2019-04-01 03:04:11 +02:00
|
|
|
{
|
2019-07-31 23:06:13 +02:00
|
|
|
return boost::chrono::process_real_cpu_clock::now().time_since_epoch().count();
|
2019-04-01 03:04:11 +02:00
|
|
|
}
|
|
|
|
|
2019-07-31 23:06:13 +02:00
|
|
|
uint64_t
|
|
|
|
ircd::prof::time_kern()
|
2019-08-06 01:15:56 +02:00
|
|
|
noexcept
|
2019-04-01 03:04:11 +02:00
|
|
|
{
|
2019-07-31 23:06:13 +02:00
|
|
|
return boost::chrono::process_system_cpu_clock::now().time_since_epoch().count();
|
2019-04-03 22:16:05 +02:00
|
|
|
}
|
|
|
|
|
2019-07-31 23:06:13 +02:00
|
|
|
uint64_t
|
|
|
|
ircd::prof::time_user()
|
2019-08-06 01:15:56 +02:00
|
|
|
noexcept
|
2019-04-03 22:16:05 +02:00
|
|
|
{
|
2019-07-31 23:06:13 +02:00
|
|
|
return boost::chrono::process_user_cpu_clock::now().time_since_epoch().count();
|
2019-04-01 03:04:11 +02:00
|
|
|
}
|
2019-04-03 22:16:05 +02:00
|
|
|
|
2019-07-31 23:06:13 +02:00
|
|
|
uint64_t
|
|
|
|
__attribute__((weak))
|
|
|
|
ircd::prof::time_thrd()
|
2019-04-03 22:16:05 +02:00
|
|
|
{
|
2019-07-31 23:06:13 +02:00
|
|
|
return 0;
|
2019-04-03 22:16:05 +02:00
|
|
|
}
|
|
|
|
|
2019-07-31 23:06:13 +02:00
|
|
|
uint64_t
|
|
|
|
__attribute__((weak))
|
|
|
|
ircd::prof::time_proc()
|
2019-04-03 22:16:05 +02:00
|
|
|
{
|
2019-07-31 23:06:13 +02:00
|
|
|
return 0;
|
2019-04-03 22:16:05 +02:00
|
|
|
}
|
|
|
|
|
2019-07-31 23:06:13 +02:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2019-04-26 05:49:04 +02:00
|
|
|
//
|
2019-07-31 23:06:13 +02:00
|
|
|
// prof/vg.h
|
2019-04-26 05:49:04 +02:00
|
|
|
//
|
2019-07-03 23:45:23 +02:00
|
|
|
// note: further definitions calling valgrind isolated to ircd/vg.cc
|
2019-04-26 05:49:04 +02:00
|
|
|
|
|
|
|
//
|
2019-06-23 08:28:48 +02:00
|
|
|
// prof::vg::enable
|
2019-04-26 05:49:04 +02:00
|
|
|
//
|
|
|
|
|
|
|
|
ircd::prof::vg::enable::enable()
|
|
|
|
noexcept
|
|
|
|
{
|
|
|
|
start();
|
|
|
|
}
|
|
|
|
|
|
|
|
ircd::prof::vg::enable::~enable()
|
|
|
|
noexcept
|
|
|
|
{
|
|
|
|
stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
2019-06-23 08:28:48 +02:00
|
|
|
// prof::vg::disable
|
2019-04-26 05:49:04 +02:00
|
|
|
//
|
|
|
|
|
|
|
|
ircd::prof::vg::disable::disable()
|
|
|
|
noexcept
|
|
|
|
{
|
|
|
|
stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
ircd::prof::vg::disable::~disable()
|
|
|
|
noexcept
|
|
|
|
{
|
|
|
|
start();
|
|
|
|
}
|
|
|
|
|
2020-03-07 00:19:05 +01:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// prof/syscall_usage_warning.h
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifdef RB_DEBUG
|
|
|
|
ircd::prof::syscall_usage_warning::~syscall_usage_warning()
|
|
|
|
noexcept
|
|
|
|
{
|
2021-01-04 11:05:36 +01:00
|
|
|
// Ignore this if we get here during static initialization before main()
|
|
|
|
if(unlikely(!ircd::ios::epoch()))
|
|
|
|
return;
|
|
|
|
|
2020-03-07 00:19:05 +01:00
|
|
|
const uint64_t total
|
|
|
|
{
|
|
|
|
timer.stopped?
|
|
|
|
timer.at():
|
|
|
|
timer.sample()
|
|
|
|
};
|
|
|
|
|
|
|
|
if(likely(!total))
|
|
|
|
return;
|
|
|
|
|
2020-10-29 12:04:31 +01:00
|
|
|
char buf[256];
|
2020-03-07 00:19:05 +01:00
|
|
|
const string_view reason
|
|
|
|
{
|
|
|
|
fmt::vsprintf
|
|
|
|
{
|
|
|
|
buf, fmt, ap
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-10-29 12:04:31 +01:00
|
|
|
char tmbuf[64];
|
2021-04-09 20:05:36 +02:00
|
|
|
log::logf
|
2020-03-07 00:19:05 +01:00
|
|
|
{
|
2021-04-09 20:05:36 +02:00
|
|
|
log, log::level::DWARNING,
|
|
|
|
"[%s] context id:%lu watchdog :system call took %s :%s",
|
2020-03-07 00:19:05 +01:00
|
|
|
ctx::current?
|
|
|
|
name(ctx::cur()):
|
|
|
|
ios::handler::current?
|
|
|
|
name(*ios::handler::current):
|
|
|
|
"*"_sv,
|
|
|
|
ctx::current?
|
|
|
|
id(ctx::cur()):
|
|
|
|
0,
|
2020-09-29 19:37:03 +02:00
|
|
|
pretty(tmbuf, nanoseconds(total), true),
|
2020-03-07 00:19:05 +01:00
|
|
|
reason
|
|
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2019-07-31 23:06:13 +02:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2019-05-08 02:18:39 +02:00
|
|
|
//
|
2019-07-31 23:06:13 +02:00
|
|
|
// prof/syscall_timer.h
|
2019-05-08 02:18:39 +02:00
|
|
|
//
|
|
|
|
|
2019-04-26 05:49:04 +02:00
|
|
|
//
|
|
|
|
// syscall_timer
|
|
|
|
//
|
|
|
|
|
|
|
|
ircd::prof::syscall_timer::syscall_timer()
|
|
|
|
noexcept
|
|
|
|
:started
|
|
|
|
{
|
|
|
|
time_kern()
|
|
|
|
}
|
|
|
|
,stopped
|
|
|
|
{
|
|
|
|
0UL
|
|
|
|
}
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
ircd::prof::syscall_timer::sample()
|
|
|
|
{
|
|
|
|
stopped = time_kern();
|
|
|
|
return at();
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
ircd::prof::syscall_timer::at()
|
|
|
|
const
|
|
|
|
{
|
|
|
|
return stopped - started;
|
|
|
|
}
|
|
|
|
|
2019-04-26 06:09:50 +02:00
|
|
|
//
|
|
|
|
// syscall_timer::high_resolution
|
|
|
|
//
|
|
|
|
|
|
|
|
ircd::prof::syscall_timer::high_resolution::high_resolution()
|
|
|
|
noexcept
|
|
|
|
:started
|
|
|
|
{
|
|
|
|
resource(prof::sample).at(resource::TIME_KERN)
|
|
|
|
}
|
|
|
|
,stopped
|
|
|
|
{
|
|
|
|
0UL
|
|
|
|
}
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
ircd::prof::syscall_timer::high_resolution::sample()
|
|
|
|
{
|
|
|
|
stopped = resource(prof::sample).at(resource::TIME_KERN);
|
|
|
|
return at();
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
ircd::prof::syscall_timer::high_resolution::at()
|
|
|
|
const
|
|
|
|
{
|
|
|
|
return stopped - started;
|
|
|
|
}
|
2019-04-26 05:49:04 +02:00
|
|
|
|
2019-07-31 23:06:13 +02:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2019-04-26 05:49:04 +02:00
|
|
|
//
|
2019-07-31 23:06:13 +02:00
|
|
|
// prof/times.h
|
2019-04-26 05:49:04 +02:00
|
|
|
//
|
|
|
|
|
|
|
|
ircd::prof::times::times(sample_t)
|
|
|
|
:real{}
|
|
|
|
,kern{}
|
|
|
|
,user{}
|
|
|
|
{
|
|
|
|
const auto tp
|
|
|
|
{
|
|
|
|
boost::chrono::process_cpu_clock::now()
|
|
|
|
};
|
|
|
|
|
|
|
|
const auto d
|
|
|
|
{
|
|
|
|
tp.time_since_epoch()
|
|
|
|
};
|
|
|
|
|
|
|
|
this->real = d.count().real;
|
|
|
|
this->kern = d.count().system;
|
|
|
|
this->user = d.count().user;
|
|
|
|
}
|
|
|
|
|
2019-07-31 23:06:13 +02:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2019-04-08 00:34:39 +02:00
|
|
|
//
|
2019-07-31 23:06:13 +02:00
|
|
|
// prof/resource.h
|
2019-04-08 00:34:39 +02:00
|
|
|
//
|
|
|
|
|
|
|
|
ircd::prof::resource
|
|
|
|
ircd::prof::operator-(const resource &a,
|
|
|
|
const resource &b)
|
|
|
|
{
|
|
|
|
resource ret;
|
|
|
|
std::transform(begin(a), end(a), begin(b), begin(ret), std::minus<resource::value_type>{});
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ircd::prof::resource
|
|
|
|
ircd::prof::operator+(const resource &a,
|
|
|
|
const resource &b)
|
|
|
|
{
|
|
|
|
resource ret;
|
|
|
|
std::transform(begin(a), end(a), begin(b), begin(ret), std::plus<resource::value_type>{});
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ircd::prof::resource &
|
|
|
|
ircd::prof::operator-=(resource &a,
|
|
|
|
const resource &b)
|
|
|
|
{
|
|
|
|
for(size_t i(0); i < a.size(); ++i)
|
|
|
|
a[i] -= b[i];
|
|
|
|
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
ircd::prof::resource &
|
|
|
|
ircd::prof::operator+=(resource &a,
|
|
|
|
const resource &b)
|
|
|
|
{
|
|
|
|
for(size_t i(0); i < a.size(); ++i)
|
|
|
|
a[i] += b[i];
|
|
|
|
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// resource::resource
|
|
|
|
//
|
|
|
|
|
|
|
|
ircd::prof::resource::resource(sample_t)
|
|
|
|
{
|
|
|
|
struct ::rusage ru;
|
|
|
|
syscall(::getrusage, RUSAGE_SELF, &ru);
|
|
|
|
|
|
|
|
at(TIME_USER) = ru.ru_utime.tv_sec * 1000000UL + ru.ru_utime.tv_usec;
|
|
|
|
at(TIME_KERN) = ru.ru_stime.tv_sec * 1000000UL + ru.ru_stime.tv_usec;
|
|
|
|
at(RSS_MAX) = ru.ru_maxrss;
|
|
|
|
at(PF_MINOR) = ru.ru_minflt;
|
|
|
|
at(PF_MAJOR) = ru.ru_majflt;
|
|
|
|
at(BLOCK_IN) = ru.ru_inblock;
|
|
|
|
at(BLOCK_OUT) = ru.ru_oublock;
|
|
|
|
at(SCHED_YIELD) = ru.ru_nvcsw;
|
|
|
|
at(SCHED_PREEMPT) = ru.ru_nivcsw;
|
|
|
|
}
|