Added fspp profiling
This commit is contained in:
parent
a6088aae29
commit
a7e8be1e04
@ -21,14 +21,78 @@ using boost::none;
|
||||
|
||||
namespace bf = boost::filesystem;
|
||||
|
||||
#ifdef FSPP_PROFILE
|
||||
#include "Profiler.h"
|
||||
#include <iomanip>
|
||||
#include <ios>
|
||||
#define PROFILE(name) Profiler profiler_##name(&name);
|
||||
#else
|
||||
#define PROFILE(name)
|
||||
#endif
|
||||
|
||||
FilesystemImpl::FilesystemImpl(Device *device)
|
||||
:_device(device), _open_files() {
|
||||
:
|
||||
#ifdef FSPP_PROFILE
|
||||
_loadFileNanosec(0), _loadDirNanosec(0), _loadSymlinkNanosec(0), _openFileNanosec(0), _flushNanosec(0),
|
||||
_closeFileNanosec(0), _lstatNanosec(0), _fstatNanosec(0), _chmodNanosec(0), _chownNanosec(0), _truncateNanosec(0),
|
||||
_ftruncateNanosec(0), _readNanosec(0), _writeNanosec(0), _fsyncNanosec(0), _fdatasyncNanosec(0), _accessNanosec(0),
|
||||
_createAndOpenFileNanosec(0), _createAndOpenFileNanosec_withoutLoading(0), _mkdirNanosec(0),
|
||||
_mkdirNanosec_withoutLoading(0), _rmdirNanosec(0), _rmdirNanosec_withoutLoading(0), _unlinkNanosec(0),
|
||||
_unlinkNanosec_withoutLoading(0), _renameNanosec(0), _readDirNanosec(0), _readDirNanosec_withoutLoading(0),
|
||||
_utimensNanosec(0), _statfsNanosec(0), _createSymlinkNanosec(0), _createSymlinkNanosec_withoutLoading(0),
|
||||
_readSymlinkNanosec(0), _readSymlinkNanosec_withoutLoading(0),
|
||||
#endif
|
||||
_device(device), _open_files()
|
||||
{
|
||||
}
|
||||
|
||||
FilesystemImpl::~FilesystemImpl() {
|
||||
#ifdef FSPP_PROFILE
|
||||
std::cout
|
||||
<< "---------------------------------------------------------------------------\n"
|
||||
<< "Profiler Information\n"
|
||||
<< "---------------------------------------------------------------------------\n"
|
||||
<< std::fixed << std::setprecision(6)
|
||||
<< std::setw(40) << "LoadFile: " << static_cast<double>(_loadFileNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "LoadDir: " << static_cast<double>(_loadDirNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "LoadSymlink: " << static_cast<double>(_loadSymlinkNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "OpenFile: " << static_cast<double>(_openFileNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "Flush: " << static_cast<double>(_flushNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "CloseFile: " << static_cast<double>(_closeFileNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "Lstat: " << static_cast<double>(_lstatNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "Fstat: " << static_cast<double>(_fstatNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "Chmod: " << static_cast<double>(_chmodNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "Chown: " << static_cast<double>(_chownNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "Truncate: " << static_cast<double>(_truncateNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "Ftruncate: " << static_cast<double>(_ftruncateNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "Read: " << static_cast<double>(_readNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "Write: " << static_cast<double>(_writeNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "Fsync: " << static_cast<double>(_fsyncNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "Fdatasync: " << static_cast<double>(_fdatasyncNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "Access: " << static_cast<double>(_accessNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "CreateAndOpenFile: " << static_cast<double>(_createAndOpenFileNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "CreateAndOpenFile (without loading): " << static_cast<double>(_createAndOpenFileNanosec_withoutLoading)/1000000000 << "\n"
|
||||
<< std::setw(40) << "Mkdir: " << static_cast<double>(_mkdirNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "Mkdir (without loading): " << static_cast<double>(_mkdirNanosec_withoutLoading)/1000000000 << "\n"
|
||||
<< std::setw(40) << "Rmdir: " << static_cast<double>(_rmdirNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "Rmdir (without loading): " << static_cast<double>(_rmdirNanosec_withoutLoading)/1000000000 << "\n"
|
||||
<< std::setw(40) << "Unlink: " << static_cast<double>(_unlinkNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "Unlink (without loading): " << static_cast<double>(_unlinkNanosec_withoutLoading)/1000000000 << "\n"
|
||||
<< std::setw(40) << "Rename: " << static_cast<double>(_renameNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "ReadDir: " << static_cast<double>(_readDirNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "ReadDir (without loading): " << static_cast<double>(_readDirNanosec_withoutLoading)/1000000000 << "\n"
|
||||
<< std::setw(40) << "Utimens: " << static_cast<double>(_utimensNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "Statfs: " << static_cast<double>(_statfsNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "CreateSymlink: " << static_cast<double>(_createSymlinkNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "CreateSymlink (without loading): " << static_cast<double>(_createSymlinkNanosec_withoutLoading)/1000000000 << "\n"
|
||||
<< std::setw(40) << "ReadSymlink: " << static_cast<double>(_readSymlinkNanosec)/1000000000 << "\n"
|
||||
<< std::setw(40) << "ReadSymlink (without loading): " << static_cast<double>(_readSymlinkNanosec_withoutLoading)/1000000000 << "\n"
|
||||
<< "---------------------------------------------------------------------------\n" << std::flush;
|
||||
#endif
|
||||
}
|
||||
|
||||
unique_ref<File> FilesystemImpl::LoadFile(const bf::path &path) {
|
||||
PROFILE(_loadFileNanosec);
|
||||
auto node = _device->Load(path);
|
||||
if (node == none) {
|
||||
throw fuse::FuseErrnoException(EIO);
|
||||
@ -41,6 +105,7 @@ unique_ref<File> FilesystemImpl::LoadFile(const bf::path &path) {
|
||||
}
|
||||
|
||||
unique_ref<Dir> FilesystemImpl::LoadDir(const bf::path &path) {
|
||||
PROFILE(_loadDirNanosec);
|
||||
auto node = _device->Load(path);
|
||||
if (node == none) {
|
||||
throw fuse::FuseErrnoException(EIO);
|
||||
@ -53,6 +118,7 @@ unique_ref<Dir> FilesystemImpl::LoadDir(const bf::path &path) {
|
||||
}
|
||||
|
||||
unique_ref<Symlink> FilesystemImpl::LoadSymlink(const bf::path &path) {
|
||||
PROFILE(_loadSymlinkNanosec);
|
||||
auto node = _device->Load(path);
|
||||
if (node == none) {
|
||||
throw fuse::FuseErrnoException(EIO);
|
||||
@ -70,18 +136,22 @@ int FilesystemImpl::openFile(const bf::path &path, int flags) {
|
||||
}
|
||||
|
||||
int FilesystemImpl::openFile(const File &file, int flags) {
|
||||
PROFILE(_openFileNanosec);
|
||||
return _open_files.open(file.open(flags));
|
||||
}
|
||||
|
||||
void FilesystemImpl::flush(int descriptor) {
|
||||
PROFILE(_flushNanosec);
|
||||
_open_files.get(descriptor)->flush();
|
||||
}
|
||||
|
||||
void FilesystemImpl::closeFile(int descriptor) {
|
||||
PROFILE(_closeFileNanosec);
|
||||
_open_files.close(descriptor);
|
||||
}
|
||||
|
||||
void FilesystemImpl::lstat(const bf::path &path, struct ::stat *stbuf) {
|
||||
PROFILE(_lstatNanosec);
|
||||
auto node = _device->Load(path);
|
||||
if(node == none) {
|
||||
throw fuse::FuseErrnoException(ENOENT);
|
||||
@ -91,10 +161,12 @@ void FilesystemImpl::lstat(const bf::path &path, struct ::stat *stbuf) {
|
||||
}
|
||||
|
||||
void FilesystemImpl::fstat(int descriptor, struct ::stat *stbuf) {
|
||||
PROFILE(_fstatNanosec);
|
||||
_open_files.get(descriptor)->stat(stbuf);
|
||||
}
|
||||
|
||||
void FilesystemImpl::chmod(const boost::filesystem::path &path, mode_t mode) {
|
||||
PROFILE(_chmodNanosec);
|
||||
auto node = _device->Load(path);
|
||||
if(node == none) {
|
||||
throw fuse::FuseErrnoException(ENOENT);
|
||||
@ -104,6 +176,7 @@ void FilesystemImpl::chmod(const boost::filesystem::path &path, mode_t mode) {
|
||||
}
|
||||
|
||||
void FilesystemImpl::chown(const boost::filesystem::path &path, uid_t uid, gid_t gid) {
|
||||
PROFILE(_chownNanosec);
|
||||
auto node = _device->Load(path);
|
||||
if(node == none) {
|
||||
throw fuse::FuseErrnoException(ENOENT);
|
||||
@ -113,30 +186,37 @@ void FilesystemImpl::chown(const boost::filesystem::path &path, uid_t uid, gid_t
|
||||
}
|
||||
|
||||
void FilesystemImpl::truncate(const bf::path &path, off_t size) {
|
||||
PROFILE(_truncateNanosec);
|
||||
LoadFile(path)->truncate(size);
|
||||
}
|
||||
|
||||
void FilesystemImpl::ftruncate(int descriptor, off_t size) {
|
||||
PROFILE(_ftruncateNanosec);
|
||||
_open_files.get(descriptor)->truncate(size);
|
||||
}
|
||||
|
||||
int FilesystemImpl::read(int descriptor, void *buf, size_t count, off_t offset) {
|
||||
PROFILE(_readNanosec);
|
||||
return _open_files.get(descriptor)->read(buf, count, offset);
|
||||
}
|
||||
|
||||
void FilesystemImpl::write(int descriptor, const void *buf, size_t count, off_t offset) {
|
||||
PROFILE(_writeNanosec);
|
||||
_open_files.get(descriptor)->write(buf, count, offset);
|
||||
}
|
||||
|
||||
void FilesystemImpl::fsync(int descriptor) {
|
||||
PROFILE(_fsyncNanosec);
|
||||
_open_files.get(descriptor)->fsync();
|
||||
}
|
||||
|
||||
void FilesystemImpl::fdatasync(int descriptor) {
|
||||
PROFILE(_fdatasyncNanosec);
|
||||
_open_files.get(descriptor)->fdatasync();
|
||||
}
|
||||
|
||||
void FilesystemImpl::access(const bf::path &path, int mask) {
|
||||
PROFILE(_accessNanosec);
|
||||
auto node = _device->Load(path);
|
||||
if(node == none) {
|
||||
throw fuse::FuseErrnoException(ENOENT);
|
||||
@ -148,27 +228,36 @@ void FilesystemImpl::access(const bf::path &path, int mask) {
|
||||
int FilesystemImpl::createAndOpenFile(const bf::path &path, mode_t mode, uid_t uid, gid_t gid) {
|
||||
//TODO Creating the file opens and closes it. We then reopen it afterwards.
|
||||
// This is slow. Improve!
|
||||
PROFILE(_createAndOpenFileNanosec);
|
||||
auto dir = LoadDir(path.parent_path());
|
||||
PROFILE(_createAndOpenFileNanosec_withoutLoading);
|
||||
auto file = dir->createAndOpenFile(path.filename().native(), mode, uid, gid);
|
||||
return _open_files.open(std::move(file));
|
||||
}
|
||||
|
||||
void FilesystemImpl::mkdir(const bf::path &path, mode_t mode, uid_t uid, gid_t gid) {
|
||||
PROFILE(_mkdirNanosec);
|
||||
auto dir = LoadDir(path.parent_path());
|
||||
PROFILE(_mkdirNanosec_withoutLoading);
|
||||
dir->createDir(path.filename().native(), mode, uid, gid);
|
||||
}
|
||||
|
||||
void FilesystemImpl::rmdir(const bf::path &path) {
|
||||
PROFILE(_rmdirNanosec);
|
||||
auto dir = LoadDir(path);
|
||||
PROFILE(_rmdirNanosec_withoutLoading);
|
||||
dir->remove();
|
||||
}
|
||||
|
||||
void FilesystemImpl::unlink(const bf::path &path) {
|
||||
PROFILE(_unlinkNanosec);
|
||||
auto file = LoadFile(path);
|
||||
PROFILE(_unlinkNanosec_withoutLoading);
|
||||
file->remove();
|
||||
}
|
||||
|
||||
void FilesystemImpl::rename(const bf::path &from, const bf::path &to) {
|
||||
PROFILE(_renameNanosec);
|
||||
auto node = _device->Load(from);
|
||||
if(node == none) {
|
||||
throw fuse::FuseErrnoException(ENOENT);
|
||||
@ -178,11 +267,14 @@ void FilesystemImpl::rename(const bf::path &from, const bf::path &to) {
|
||||
}
|
||||
|
||||
unique_ref<vector<Dir::Entry>> FilesystemImpl::readDir(const bf::path &path) {
|
||||
PROFILE(_readDirNanosec);
|
||||
auto dir = LoadDir(path);
|
||||
PROFILE(_readDirNanosec_withoutLoading);
|
||||
return dir->children();
|
||||
}
|
||||
|
||||
void FilesystemImpl::utimens(const bf::path &path, const timespec times[2]) {
|
||||
PROFILE(_utimensNanosec);
|
||||
auto node = _device->Load(path);
|
||||
if(node == none) {
|
||||
throw fuse::FuseErrnoException(ENOENT);
|
||||
@ -192,16 +284,21 @@ void FilesystemImpl::utimens(const bf::path &path, const timespec times[2]) {
|
||||
}
|
||||
|
||||
void FilesystemImpl::statfs(const bf::path &path, struct statvfs *fsstat) {
|
||||
PROFILE(_statfsNanosec);
|
||||
_device->statfs(path, fsstat);
|
||||
}
|
||||
|
||||
void FilesystemImpl::createSymlink(const bf::path &to, const bf::path &from, uid_t uid, gid_t gid) {
|
||||
PROFILE(_createSymlinkNanosec);
|
||||
auto parent = LoadDir(from.parent_path());
|
||||
PROFILE(_createSymlinkNanosec_withoutLoading);
|
||||
parent->createSymlink(from.filename().native(), to, uid, gid);
|
||||
}
|
||||
|
||||
void FilesystemImpl::readSymlink(const bf::path &path, char *buf, size_t size) {
|
||||
PROFILE(_readSymlinkNanosec);
|
||||
string target = LoadSymlink(path)->target().native();
|
||||
PROFILE(_readSymlinkNanosec_withoutLoading);
|
||||
std::memcpy(buf, target.c_str(), std::min(target.size()+1, size));
|
||||
buf[size-1] = '\0';
|
||||
}
|
||||
|
@ -6,6 +6,10 @@
|
||||
#include "../fuse/Filesystem.h"
|
||||
|
||||
#include <messmer/cpp-utils/pointer/unique_ref.h>
|
||||
#include <atomic>
|
||||
|
||||
//Remove this line if you don't want profiling
|
||||
#define FSPP_PROFILE 1
|
||||
|
||||
namespace fspp {
|
||||
class Node;
|
||||
@ -49,6 +53,43 @@ private:
|
||||
cpputils::unique_ref<Symlink> LoadSymlink(const boost::filesystem::path &path);
|
||||
int openFile(const File &file, int flags);
|
||||
|
||||
#ifdef FSPP_PROFILE
|
||||
std::atomic<uint64_t> _loadFileNanosec;
|
||||
std::atomic<uint64_t> _loadDirNanosec;
|
||||
std::atomic<uint64_t> _loadSymlinkNanosec;
|
||||
std::atomic<uint64_t> _openFileNanosec;
|
||||
std::atomic<uint64_t> _flushNanosec;
|
||||
std::atomic<uint64_t> _closeFileNanosec;
|
||||
std::atomic<uint64_t> _lstatNanosec;
|
||||
std::atomic<uint64_t> _fstatNanosec;
|
||||
std::atomic<uint64_t> _chmodNanosec;
|
||||
std::atomic<uint64_t> _chownNanosec;
|
||||
std::atomic<uint64_t> _truncateNanosec;
|
||||
std::atomic<uint64_t> _ftruncateNanosec;
|
||||
std::atomic<uint64_t> _readNanosec;
|
||||
std::atomic<uint64_t> _writeNanosec;
|
||||
std::atomic<uint64_t> _fsyncNanosec;
|
||||
std::atomic<uint64_t> _fdatasyncNanosec;
|
||||
std::atomic<uint64_t> _accessNanosec;
|
||||
std::atomic<uint64_t> _createAndOpenFileNanosec;
|
||||
std::atomic<uint64_t> _createAndOpenFileNanosec_withoutLoading;
|
||||
std::atomic<uint64_t> _mkdirNanosec;
|
||||
std::atomic<uint64_t> _mkdirNanosec_withoutLoading;
|
||||
std::atomic<uint64_t> _rmdirNanosec;
|
||||
std::atomic<uint64_t> _rmdirNanosec_withoutLoading;
|
||||
std::atomic<uint64_t> _unlinkNanosec;
|
||||
std::atomic<uint64_t> _unlinkNanosec_withoutLoading;
|
||||
std::atomic<uint64_t> _renameNanosec;
|
||||
std::atomic<uint64_t> _readDirNanosec;
|
||||
std::atomic<uint64_t> _readDirNanosec_withoutLoading;
|
||||
std::atomic<uint64_t> _utimensNanosec;
|
||||
std::atomic<uint64_t> _statfsNanosec;
|
||||
std::atomic<uint64_t> _createSymlinkNanosec;
|
||||
std::atomic<uint64_t> _createSymlinkNanosec_withoutLoading;
|
||||
std::atomic<uint64_t> _readSymlinkNanosec;
|
||||
std::atomic<uint64_t> _readSymlinkNanosec_withoutLoading;
|
||||
#endif
|
||||
|
||||
Device *_device;
|
||||
FuseOpenFileList _open_files;
|
||||
|
||||
|
1
impl/Profiler.cpp
Normal file
1
impl/Profiler.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "Profiler.h"
|
28
impl/Profiler.h
Normal file
28
impl/Profiler.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef FSPP_IMPL_PROFILER_H
|
||||
#define FSPP_IMPL_PROFILER_H
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
|
||||
namespace fspp {
|
||||
class Profiler {
|
||||
public:
|
||||
Profiler(std::atomic_uint_fast64_t *targetForAddingNanosec);
|
||||
~Profiler();
|
||||
|
||||
private:
|
||||
std::atomic_uint_fast64_t *_targetForAddingNanosec;
|
||||
std::chrono::high_resolution_clock::time_point _beginTime;
|
||||
};
|
||||
|
||||
inline Profiler::Profiler(std::atomic_uint_fast64_t *targetForAddingNanosec)
|
||||
: _targetForAddingNanosec(targetForAddingNanosec), _beginTime(std::chrono::high_resolution_clock::now()) {
|
||||
}
|
||||
|
||||
inline Profiler::~Profiler() {
|
||||
uint64_t timeDiff = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - _beginTime).count();
|
||||
*_targetForAddingNanosec += timeDiff;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user