Skip to content
GitLab
Explore
Sign in
Commits on Source (2)
Debug Timer, it should be moved to the logger
· 06b496e2
Julius Athenstaedt
authored
Apr 17, 2025
06b496e2
use debug timer to see what takes so long, not complete
· 7b92d158
Julius Athenstaedt
authored
Apr 17, 2025
7b92d158
Show whitespace changes
Inline
Side-by-side
include/client/preload.hpp
View file @
7b92d158
...
@@ -46,6 +46,7 @@
...
@@ -46,6 +46,7 @@
#define EUNKNOWN (-1)
#define EUNKNOWN (-1)
#define CTX gkfs::preload::PreloadContext::getInstance()
#define CTX gkfs::preload::PreloadContext::getInstance()
#define DT gkfs::preload::DebugTimer::getInstance()
namespace
gkfs
::
preload
{
namespace
gkfs
::
preload
{
void
void
init_environment
();
init_environment
();
...
...
include/client/preload_context.hpp
View file @
7b92d158
...
@@ -50,6 +50,14 @@
...
@@ -50,6 +50,14 @@
#include
<bitset>
#include
<bitset>
// Debug timer
#include
<chrono>
#include
<unordered_map>
#include
<string>
#include
<mutex>
extern
char
*
program_invocation_name
;
// ---------
/* Forward declarations */
/* Forward declarations */
namespace
gkfs
{
namespace
gkfs
{
namespace
filemap
{
namespace
filemap
{
...
@@ -75,6 +83,43 @@ class WriteSizeCache;
...
@@ -75,6 +83,43 @@ class WriteSizeCache;
}
// namespace cache
}
// namespace cache
namespace
preload
{
namespace
preload
{
// Debug timer
class
DebugTimer
{
public:
static
DebugTimer
&
getInstance
()
{
static
DebugTimer
instance
;
return
instance
;
}
void
record
(
const
std
::
string
&
name
);
void
write_stats
(
const
std
::
string
&
file
);
private
:
struct
Stat
{
std
::
chrono
::
high_resolution_clock
::
time_point
lastTime
{};
int
callCount
=
0
;
double
maxDuration
=
0.0
;
double
totalDuration
=
0.0
;
};
std
::
chrono
::
high_resolution_clock
::
time_point
start_time
{};
std
::
unordered_map
<
std
::
string
,
Stat
>
stats_
;
mutable
std
::
mutex
mutex_
;
// Private constructor to enforce singleton
DebugTimer
();
~
DebugTimer
()
=
default
;
DebugTimer
(
const
DebugTimer
&
)
=
delete
;
DebugTimer
&
operator
=
(
const
DebugTimer
&
)
=
delete
;
};
// ---------
/*
/*
* Client file system config
* Client file system config
*/
*/
...
...
src/client/gkfs_libc.cpp
View file @
7b92d158
...
@@ -580,7 +580,9 @@ is_gkfs_fd(int fd) {
...
@@ -580,7 +580,9 @@ is_gkfs_fd(int fd) {
#define GKFS_OPERATION(name, ...) \
#define GKFS_OPERATION(name, ...) \
if(CTX->interception_enabled() && is_gkfs_fd(fd)) { \
if(CTX->interception_enabled() && is_gkfs_fd(fd)) { \
\
\
DT.record(#name); \
auto res = gkfs::syscall::gkfs_##name(__VA_ARGS__); \
auto res = gkfs::syscall::gkfs_##name(__VA_ARGS__); \
DT.record(#name); \
DEBUG_INFO("[GKFS] {} -> res {}", fd, res); \
DEBUG_INFO("[GKFS] {} -> res {}", fd, res); \
return res; \
return res; \
}
}
...
@@ -589,9 +591,13 @@ is_gkfs_fd(int fd) {
...
@@ -589,9 +591,13 @@ is_gkfs_fd(int fd) {
if(CTX->interception_enabled()) { \
if(CTX->interception_enabled()) { \
std::string resolved; \
std::string resolved; \
switch(resolve_gkfs_path(dirfd, path, resolved)) { \
switch(resolve_gkfs_path(dirfd, path, resolved)) { \
case PathStatus::Internal:
\
case PathStatus::Internal:
{
\
DEBUG_INFO("[GKFS] {}", resolved); \
DEBUG_INFO("[GKFS] {}", resolved); \
return gkfs::syscall::gkfs_##name(resolved, __VA_ARGS__); \
DT.record(#name); \
auto res = gkfs::syscall::gkfs_##name(resolved, __VA_ARGS__); \
DT.record(#name); \
return res; \
} \
case PathStatus::Error: \
case PathStatus::Error: \
return -1; \
return -1; \
default: \
default: \
...
@@ -603,10 +609,14 @@ is_gkfs_fd(int fd) {
...
@@ -603,10 +609,14 @@ is_gkfs_fd(int fd) {
if(CTX->interception_enabled()) { \
if(CTX->interception_enabled()) { \
std::string resolved; \
std::string resolved; \
switch(resolve_gkfs_path(dirfd, path, resolved)) { \
switch(resolve_gkfs_path(dirfd, path, resolved)) { \
case PathStatus::Internal:
\
case PathStatus::Internal:
{
\
DEBUG_INFO("[GKFS] {}", resolved); \
DEBUG_INFO("[GKFS] {}", resolved); \
return gkfs::syscall::gkfs_##name(dirfd, resolved, \
DT.record(#name); \
auto res = gkfs::syscall::gkfs_##name(dirfd, resolved, \
__VA_ARGS__); \
__VA_ARGS__); \
DT.record(#name); \
return res; \
} \
case PathStatus::Error: \
case PathStatus::Error: \
return -1; \
return -1; \
default: \
default: \
...
@@ -618,9 +628,13 @@ is_gkfs_fd(int fd) {
...
@@ -618,9 +628,13 @@ is_gkfs_fd(int fd) {
if(CTX->interception_enabled()) { \
if(CTX->interception_enabled()) { \
std::string resolved; \
std::string resolved; \
switch(resolve_gkfs_path(dirfd, path, resolved)) { \
switch(resolve_gkfs_path(dirfd, path, resolved)) { \
case PathStatus::Internal:
\
case PathStatus::Internal:
{
\
DEBUG_INFO("[GKFS] {}", resolved); \
DEBUG_INFO("[GKFS] {}", resolved); \
return gkfs::syscall::gkfs_##name(resolved); \
DT.record(#name); \
auto res = gkfs::syscall::gkfs_##name(resolved); \
DT.record(#name); \
return res; \
} \
case PathStatus::Error: \
case PathStatus::Error: \
return -1; \
return -1; \
default: \
default: \
...
@@ -936,7 +950,9 @@ __xstat64(int ver, const char* path, struct stat64* buf) {
...
@@ -936,7 +950,9 @@ __xstat64(int ver, const char* path, struct stat64* buf) {
switch
(
resolve_gkfs_path
(
AT_FDCWD
,
path
,
resolved
))
{
switch
(
resolve_gkfs_path
(
AT_FDCWD
,
path
,
resolved
))
{
case
PathStatus
::
Internal
:
{
case
PathStatus
::
Internal
:
{
DEBUG_INFO
(
"[GKFS] {}"
,
resolved
);
DEBUG_INFO
(
"[GKFS] {}"
,
resolved
);
DT
.
record
(
"__xstat64"
);
auto
res
=
gkfs
::
syscall
::
gkfs_stat
(
resolved
,
&
st
);
auto
res
=
gkfs
::
syscall
::
gkfs_stat
(
resolved
,
&
st
);
DT
.
record
(
"__xstat64"
);
convert
(
&
st
,
buf
);
convert
(
&
st
,
buf
);
return
res
;
return
res
;
}
}
...
@@ -980,7 +996,9 @@ __lxstat(int ver, const char* path, struct stat* buf) {
...
@@ -980,7 +996,9 @@ __lxstat(int ver, const char* path, struct stat* buf) {
switch
(
resolve_gkfs_path
(
AT_FDCWD
,
path
,
resolved
,
0
,
false
))
{
switch
(
resolve_gkfs_path
(
AT_FDCWD
,
path
,
resolved
,
0
,
false
))
{
case
PathStatus
::
Internal
:
{
case
PathStatus
::
Internal
:
{
DEBUG_INFO
(
"[GKFS] {}"
,
resolved
);
DEBUG_INFO
(
"[GKFS] {}"
,
resolved
);
DT
.
record
(
"__lxstat"
);
auto
res
=
gkfs
::
syscall
::
gkfs_stat
(
resolved
,
buf
,
false
);
auto
res
=
gkfs
::
syscall
::
gkfs_stat
(
resolved
,
buf
,
false
);
DT
.
record
(
"__lxstat"
);
return
res
;
return
res
;
}
}
case
PathStatus
::
Error
:
{
case
PathStatus
::
Error
:
{
...
@@ -1003,7 +1021,9 @@ __lxstat64(int ver, const char* path, struct stat64* buf) {
...
@@ -1003,7 +1021,9 @@ __lxstat64(int ver, const char* path, struct stat64* buf) {
switch
(
resolve_gkfs_path
(
AT_FDCWD
,
path
,
resolved
))
{
switch
(
resolve_gkfs_path
(
AT_FDCWD
,
path
,
resolved
))
{
case
PathStatus
::
Internal
:
{
case
PathStatus
::
Internal
:
{
DEBUG_INFO
(
"[GKFS] {}"
,
resolved
);
DEBUG_INFO
(
"[GKFS] {}"
,
resolved
);
DT
.
record
(
"__lxstat64"
);
auto
res
=
gkfs
::
syscall
::
gkfs_stat
(
resolved
,
&
st
,
false
);
auto
res
=
gkfs
::
syscall
::
gkfs_stat
(
resolved
,
&
st
,
false
);
DT
.
record
(
"__lxstat64"
);
convert
(
&
st
,
buf
);
convert
(
&
st
,
buf
);
return
res
;
return
res
;
}
}
...
@@ -1042,8 +1062,10 @@ __fxstat64(int ver, int fd, struct stat64* buf) {
...
@@ -1042,8 +1062,10 @@ __fxstat64(int ver, int fd, struct stat64* buf) {
if
(
CTX
->
interception_enabled
()
&&
is_gkfs_fd
(
fd
))
{
if
(
CTX
->
interception_enabled
()
&&
is_gkfs_fd
(
fd
))
{
struct
stat
st
;
struct
stat
st
;
DEBUG_INFO
(
"[GKFS] {}"
,
CTX
->
file_map
()
->
get
(
fd
)
->
path
());
DEBUG_INFO
(
"[GKFS] {}"
,
CTX
->
file_map
()
->
get
(
fd
)
->
path
());
DT
.
record
(
"__fxstat64"
);
int
res
=
gkfs
::
syscall
::
gkfs_stat
(
CTX
->
file_map
()
->
get
(
fd
)
->
path
(),
int
res
=
gkfs
::
syscall
::
gkfs_stat
(
CTX
->
file_map
()
->
get
(
fd
)
->
path
(),
&
st
,
true
,
true
);
&
st
,
true
,
true
);
DT
.
record
(
"__fxstat64"
);
if
(
res
==
0
)
if
(
res
==
0
)
convert
(
&
st
,
buf
);
convert
(
&
st
,
buf
);
return
res
;
return
res
;
...
@@ -1057,8 +1079,10 @@ fstat64(int fd, struct stat64* buf) {
...
@@ -1057,8 +1079,10 @@ fstat64(int fd, struct stat64* buf) {
if
(
CTX
->
interception_enabled
()
&&
is_gkfs_fd
(
fd
))
{
if
(
CTX
->
interception_enabled
()
&&
is_gkfs_fd
(
fd
))
{
struct
stat
st
;
struct
stat
st
;
DEBUG_INFO
(
"[GKFS] {}"
,
CTX
->
file_map
()
->
get
(
fd
)
->
path
());
DEBUG_INFO
(
"[GKFS] {}"
,
CTX
->
file_map
()
->
get
(
fd
)
->
path
());
DT
.
record
(
"fstat64"
);
int
res
=
gkfs
::
syscall
::
gkfs_stat
(
CTX
->
file_map
()
->
get
(
fd
)
->
path
(),
int
res
=
gkfs
::
syscall
::
gkfs_stat
(
CTX
->
file_map
()
->
get
(
fd
)
->
path
(),
&
st
,
true
,
true
);
&
st
,
true
,
true
);
DT
.
record
(
"fstat64"
);
if
(
res
==
0
)
if
(
res
==
0
)
convert
(
&
st
,
buf
);
convert
(
&
st
,
buf
);
return
res
;
return
res
;
...
@@ -1074,8 +1098,10 @@ fstat(int fd, struct stat* buf) {
...
@@ -1074,8 +1098,10 @@ fstat(int fd, struct stat* buf) {
// The fd could be a renamed file, thus when doing gkfs_stat we will get
// The fd could be a renamed file, thus when doing gkfs_stat we will get
// a is not found.
// a is not found.
DT
.
record
(
"fstat"
);
int
res
=
gkfs
::
syscall
::
gkfs_stat
(
CTX
->
file_map
()
->
get
(
fd
)
->
path
(),
int
res
=
gkfs
::
syscall
::
gkfs_stat
(
CTX
->
file_map
()
->
get
(
fd
)
->
path
(),
buf
,
true
,
true
);
buf
,
true
,
true
);
DT
.
record
(
"fstat"
);
return
res
;
return
res
;
}
}
GKFS_FALLBACK
(
fstat
,
fd
,
buf
);
GKFS_FALLBACK
(
fstat
,
fd
,
buf
);
...
@@ -1092,8 +1118,10 @@ __fxstatat64(int ver, int dfd, const char* path, struct stat64* buf,
...
@@ -1092,8 +1118,10 @@ __fxstatat64(int ver, int dfd, const char* path, struct stat64* buf,
case
PathStatus
::
Internal
:
{
case
PathStatus
::
Internal
:
{
DEBUG_INFO
(
"[GKFS] {}"
,
resolved
);
DEBUG_INFO
(
"[GKFS] {}"
,
resolved
);
bool
follow
=
(
flags
&
AT_SYMLINK_NOFOLLOW
)
==
0
;
bool
follow
=
(
flags
&
AT_SYMLINK_NOFOLLOW
)
==
0
;
DT
.
record
(
"__fxstatat64"
);
auto
res
=
gkfs
::
syscall
::
gkfs_stat
(
resolved
,
&
st
,
follow
);
auto
res
=
gkfs
::
syscall
::
gkfs_stat
(
resolved
,
&
st
,
follow
);
convert
(
&
st
,
buf
);
convert
(
&
st
,
buf
);
DT
.
record
(
"__fxstatat64"
);
return
res
;
return
res
;
}
}
case
PathStatus
::
Error
:
{
case
PathStatus
::
Error
:
{
...
@@ -1122,8 +1150,10 @@ stat64(const char* path, struct stat64* buf) {
...
@@ -1122,8 +1150,10 @@ stat64(const char* path, struct stat64* buf) {
switch
(
resolve_gkfs_path
(
AT_FDCWD
,
path
,
resolved
))
{
switch
(
resolve_gkfs_path
(
AT_FDCWD
,
path
,
resolved
))
{
case
PathStatus
::
Internal
:
{
case
PathStatus
::
Internal
:
{
DEBUG_INFO
(
"[GKFS] {}"
,
resolved
);
DEBUG_INFO
(
"[GKFS] {}"
,
resolved
);
DT
.
record
(
"stat64"
);
auto
res
=
gkfs
::
syscall
::
gkfs_stat
(
resolved
,
&
st
);
auto
res
=
gkfs
::
syscall
::
gkfs_stat
(
resolved
,
&
st
);
convert
(
&
st
,
buf
);
convert
(
&
st
,
buf
);
DT
.
record
(
"stat64"
);
return
res
;
return
res
;
}
}
case
PathStatus
::
Error
:
{
case
PathStatus
::
Error
:
{
...
@@ -1148,7 +1178,9 @@ fstatat(int dfd, const char* path, struct stat* buf, int flags) {
...
@@ -1148,7 +1178,9 @@ fstatat(int dfd, const char* path, struct stat* buf, int flags) {
case
PathStatus
::
Internal
:
{
case
PathStatus
::
Internal
:
{
DEBUG_INFO
(
"[GKFS] {}"
,
resolved
);
DEBUG_INFO
(
"[GKFS] {}"
,
resolved
);
bool
follow
=
(
flags
&
AT_SYMLINK_NOFOLLOW
)
==
0
;
bool
follow
=
(
flags
&
AT_SYMLINK_NOFOLLOW
)
==
0
;
DT
.
record
(
"fstatat"
);
auto
res
=
gkfs
::
syscall
::
gkfs_stat
(
resolved
,
buf
,
follow
);
auto
res
=
gkfs
::
syscall
::
gkfs_stat
(
resolved
,
buf
,
follow
);
DT
.
record
(
"fstatat"
);
return
res
;
return
res
;
}
}
case
PathStatus
::
Error
:
{
case
PathStatus
::
Error
:
{
...
...
src/client/preload.cpp
View file @
7b92d158
...
@@ -96,6 +96,7 @@ exit_error_msg(int errcode, const string& msg) {
...
@@ -96,6 +96,7 @@ exit_error_msg(int errcode, const string& msg) {
bool
bool
init_hermes_client
()
{
init_hermes_client
()
{
DT
.
record
(
"init_hermes_client"
);
try
{
try
{
hermes
::
engine_options
opts
{};
hermes
::
engine_options
opts
{};
...
@@ -130,6 +131,7 @@ init_hermes_client() {
...
@@ -130,6 +131,7 @@ init_hermes_client() {
return
false
;
return
false
;
}
}
}
}
DT
.
record
(
"init_hermes_client"
);
return
true
;
return
true
;
}
}
...
@@ -209,6 +211,7 @@ namespace gkfs::preload {
...
@@ -209,6 +211,7 @@ namespace gkfs::preload {
void
void
init_environment
()
{
init_environment
()
{
DT
.
record
(
"init_environment"
);
vector
<
pair
<
string
,
string
>>
hosts
{};
vector
<
pair
<
string
,
string
>>
hosts
{};
try
{
try
{
LOG
(
INFO
,
"Loading peer addresses..."
);
LOG
(
INFO
,
"Loading peer addresses..."
);
...
@@ -353,6 +356,7 @@ init_environment() {
...
@@ -353,6 +356,7 @@ init_environment() {
srand
(
time
(
nullptr
));
srand
(
time
(
nullptr
));
}
}
DT
.
record
(
"init_environment"
);
LOG
(
INFO
,
"Environment initialization successful."
);
LOG
(
INFO
,
"Environment initialization successful."
);
}
}
...
@@ -369,6 +373,7 @@ void
...
@@ -369,6 +373,7 @@ void
init_preload
()
{
init_preload
()
{
// The original errno value will be restored after initialization to not
// The original errno value will be restored after initialization to not
// leak internal error codes
// leak internal error codes
DT
.
record
(
"init_preload"
);
auto
oerrno
=
errno
;
auto
oerrno
=
errno
;
if
(
atomic_exchange
(
&
init
,
1
)
==
0
)
{
if
(
atomic_exchange
(
&
init
,
1
)
==
0
)
{
pthread_atfork
(
&
at_fork_syscall
,
&
at_parent_syscall
,
&
at_child_syscall
);
pthread_atfork
(
&
at_fork_syscall
,
&
at_parent_syscall
,
&
at_child_syscall
);
...
@@ -415,6 +420,7 @@ init_preload() {
...
@@ -415,6 +420,7 @@ init_preload() {
if
(
!
forwarding_map_file
.
empty
())
{
if
(
!
forwarding_map_file
.
empty
())
{
init_forwarding_mapper
();
init_forwarding_mapper
();
}
}
DT
.
record
(
"init_preload"
);
gkfs
::
preload
::
start_interception
();
gkfs
::
preload
::
start_interception
();
errno
=
oerrno
;
errno
=
oerrno
;
...
@@ -430,6 +436,7 @@ init_preload() {
...
@@ -430,6 +436,7 @@ init_preload() {
*/
*/
void
void
destroy_preload
()
{
destroy_preload
()
{
DT
.
record
(
"destroy_preload"
);
auto
forwarding_map_file
=
gkfs
::
env
::
get_var
(
auto
forwarding_map_file
=
gkfs
::
env
::
get_var
(
gkfs
::
env
::
FORWARDING_MAP_FILE
,
gkfs
::
config
::
forwarding_file_path
);
gkfs
::
env
::
FORWARDING_MAP_FILE
,
gkfs
::
config
::
forwarding_file_path
);
if
(
!
forwarding_map_file
.
empty
())
{
if
(
!
forwarding_map_file
.
empty
())
{
...
@@ -461,6 +468,8 @@ destroy_preload() {
...
@@ -461,6 +468,8 @@ destroy_preload() {
LOG
(
DEBUG
,
"Syscall interception stopped"
);
LOG
(
DEBUG
,
"Syscall interception stopped"
);
}
}
DT
.
record
(
"destroy_preload"
);
DT
.
write_stats
(
"/tmp/gkfs_stats.txt"
);
LOG
(
INFO
,
"All subsystems shut down. Client shutdown complete."
);
LOG
(
INFO
,
"All subsystems shut down. Client shutdown complete."
);
}
}
...
@@ -471,6 +480,7 @@ destroy_preload() {
...
@@ -471,6 +480,7 @@ destroy_preload() {
*/
*/
extern
"C"
int
extern
"C"
int
gkfs_init
()
{
gkfs_init
()
{
DT
.
record
(
"gkfs_init"
);
CTX
->
init_logging
();
CTX
->
init_logging
();
// from here ownwards it is safe to print messages
// from here ownwards it is safe to print messages
LOG
(
DEBUG
,
"Logging subsystem initialized"
);
LOG
(
DEBUG
,
"Logging subsystem initialized"
);
...
@@ -488,6 +498,7 @@ gkfs_init() {
...
@@ -488,6 +498,7 @@ gkfs_init() {
if
(
CTX
->
protect_fds
())
if
(
CTX
->
protect_fds
())
CTX
->
unprotect_user_fds
();
CTX
->
unprotect_user_fds
();
DT
.
record
(
"gkfs_init"
);
return
0
;
return
0
;
}
}
...
@@ -543,6 +554,7 @@ init_libc() {
...
@@ -543,6 +554,7 @@ init_libc() {
void
void
destroy_libc
()
{
destroy_libc
()
{
DT
.
write_stats
(
"/tmp/gkfs_libc_stats.txt"
);
CTX
->
disable_interception
();
CTX
->
disable_interception
();
#ifdef GKFS_ENABLE_CLIENT_METRICS
#ifdef GKFS_ENABLE_CLIENT_METRICS
LOG
(
INFO
,
"Flushing final metrics..."
);
LOG
(
INFO
,
"Flushing final metrics..."
);
...
...
src/client/preload_context.cpp
View file @
7b92d158
...
@@ -71,6 +71,62 @@ namespace gkfs {
...
@@ -71,6 +71,62 @@ namespace gkfs {
namespace
preload
{
namespace
preload
{
DebugTimer
::
DebugTimer
()
{
this
->
start_time
=
std
::
chrono
::
high_resolution_clock
::
now
();
LOG
(
DEBUG
,
"Create DebugTimer"
);
}
// Debug timer
void
DebugTimer
::
record
(
const
std
::
string
&
name
)
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
mutex_
);
auto
now
=
std
::
chrono
::
high_resolution_clock
::
now
();
auto
&
stat
=
stats_
[
name
];
if
(
stat
.
lastTime
.
time_since_epoch
().
count
()
!=
0
)
{
auto
duration
=
std
::
chrono
::
duration
<
double
,
std
::
milli
>
(
now
-
stat
.
lastTime
)
.
count
();
stat
.
callCount
++
;
if
(
duration
>
stat
.
maxDuration
)
stat
.
maxDuration
=
duration
;
stat
.
totalDuration
+=
duration
;
}
stat
.
lastTime
=
now
;
}
void
DebugTimer
::
write_stats
(
const
std
::
string
&
file
)
{
LOG
(
DEBUG
,
"Write DebugTimer stats"
);
std
::
lock_guard
<
std
::
mutex
>
lock
(
mutex_
);
std
::
ofstream
myfile
(
file
,
std
::
ios_base
::
app
);
auto
now
=
std
::
chrono
::
high_resolution_clock
::
now
();
auto
duration
=
std
::
chrono
::
duration
<
double
,
std
::
milli
>
(
now
-
this
->
start_time
)
.
count
();
if
(
myfile
.
is_open
())
{
myfile
<<
"-----"
<<
program_invocation_name
<<
"-----"
<<
std
::
endl
;
myfile
<<
"timestamp: "
<<
now
.
time_since_epoch
().
count
()
<<
std
::
endl
;
myfile
<<
"duration: "
<<
duration
<<
"ms"
<<
std
::
endl
<<
std
::
endl
;
for
(
const
auto
&
[
name
,
stat
]
:
stats_
)
{
myfile
<<
"Name: "
<<
name
<<
"
\n
Calls: "
<<
stat
.
callCount
<<
"
\n
Max duration: "
<<
stat
.
maxDuration
<<
" ms"
<<
"
\n
Avg duration: "
<<
(
stat
.
callCount
?
stat
.
totalDuration
/
stat
.
callCount
:
0
)
<<
" ms
\n
"
;
}
myfile
.
close
();
}
else
{
LOG
(
DEBUG
,
"could not write stats o.0"
);
}
}
// ---------
decltype
(
PreloadContext
::
MIN_INTERNAL_FD
)
constexpr
PreloadContext
::
decltype
(
PreloadContext
::
MIN_INTERNAL_FD
)
constexpr
PreloadContext
::
MIN_INTERNAL_FD
;
MIN_INTERNAL_FD
;
decltype
(
PreloadContext
::
MAX_USER_FDS
)
constexpr
PreloadContext
::
MAX_USER_FDS
;
decltype
(
PreloadContext
::
MAX_USER_FDS
)
constexpr
PreloadContext
::
MAX_USER_FDS
;
...
...