From 010e6c73baf3772c00d72ca4098f8ce5992cfa6c Mon Sep 17 00:00:00 2001 From: vityaman Date: Sat, 30 Aug 2025 20:26:03 +0300 Subject: [PATCH 01/13] Draft test framework (#8) Signed-off-by: vityaman --- lab/vtpc/.clang-format | 16 ++++ lab/vtpc/.clang-tidy | 21 ++++++ lab/vtpc/.gitignore | 8 ++ lab/vtpc/.vscode/settings.json | 7 ++ lab/vtpc/CMakeLists.txt | 12 +++ lab/vtpc/README.md | 47 ++++++++++++ lab/vtpc/lib/CMakeLists.txt | 11 +++ lab/vtpc/lib/vtpc.c | 28 +++++++ lab/vtpc/lib/vtpc.h | 10 +++ lab/vtpc/test/CMakeLists.txt | 9 +++ lab/vtpc/test/lib/CMakeLists.txt | 10 +++ lab/vtpc/test/lib/cmp_file.cpp | 69 +++++++++++++++++ lab/vtpc/test/lib/cmp_file.hpp | 24 ++++++ lab/vtpc/test/lib/exception.cpp | 1 + lab/vtpc/test/lib/exception.hpp | 34 +++++++++ lab/vtpc/test/lib/file.cpp | 123 +++++++++++++++++++++++++++++++ lab/vtpc/test/lib/file.hpp | 33 +++++++++ lab/vtpc/test/test_basic.cpp | 33 +++++++++ 18 files changed, 496 insertions(+) create mode 100644 lab/vtpc/.clang-format create mode 100644 lab/vtpc/.clang-tidy create mode 100644 lab/vtpc/.gitignore create mode 100644 lab/vtpc/.vscode/settings.json create mode 100644 lab/vtpc/CMakeLists.txt create mode 100644 lab/vtpc/README.md create mode 100644 lab/vtpc/lib/CMakeLists.txt create mode 100644 lab/vtpc/lib/vtpc.c create mode 100644 lab/vtpc/lib/vtpc.h create mode 100644 lab/vtpc/test/CMakeLists.txt create mode 100644 lab/vtpc/test/lib/CMakeLists.txt create mode 100644 lab/vtpc/test/lib/cmp_file.cpp create mode 100644 lab/vtpc/test/lib/cmp_file.hpp create mode 100644 lab/vtpc/test/lib/exception.cpp create mode 100644 lab/vtpc/test/lib/exception.hpp create mode 100644 lab/vtpc/test/lib/file.cpp create mode 100644 lab/vtpc/test/lib/file.hpp create mode 100644 lab/vtpc/test/test_basic.cpp diff --git a/lab/vtpc/.clang-format b/lab/vtpc/.clang-format new file mode 100644 index 0000000..dd99110 --- /dev/null +++ b/lab/vtpc/.clang-format @@ -0,0 +1,16 @@ +BasedOnStyle: Google + +AccessModifierOffset: -2 + +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false + +DerivePointerAlignment: false +BreakConstructorInitializers: BeforeComma +AlignAfterOpenBracket: BlockIndent + +BinPackArguments: false +BinPackParameters: false + +AlignArrayOfStructures: Right diff --git a/lab/vtpc/.clang-tidy b/lab/vtpc/.clang-tidy new file mode 100644 index 0000000..07e1c89 --- /dev/null +++ b/lab/vtpc/.clang-tidy @@ -0,0 +1,21 @@ +Checks: | + -*, + bugprone-*, + -bugprone-easily-swappable-parameters, + cert-*, + clang-analyzer-*, + concurrency-*, + cppcoreguidelines-*, + -cppcoreguidelines-avoid-non-const-global-variables, + -cppcoreguidelines-special-member-functions, + google-*, + hicpp-*, + -hicpp-special-member-functions, + misc-*, + modernize-*, + performance-*, + portability-*, + readability-* + -readability-identifier-length +WarningsAsErrors: '*' +FormatStyle: file diff --git a/lab/vtpc/.gitignore b/lab/vtpc/.gitignore new file mode 100644 index 0000000..fb90d94 --- /dev/null +++ b/lab/vtpc/.gitignore @@ -0,0 +1,8 @@ +# CMake +build/ + +# Clangd +.cache/ + +# Python +__pycache__/ diff --git a/lab/vtpc/.vscode/settings.json b/lab/vtpc/.vscode/settings.json new file mode 100644 index 0000000..db30e90 --- /dev/null +++ b/lab/vtpc/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "clangd.arguments": [ + "-compile-commands-dir=./build", + "-header-insertion=never", + ], + "files.eol": "\n", +} diff --git a/lab/vtpc/CMakeLists.txt b/lab/vtpc/CMakeLists.txt new file mode 100644 index 0000000..478cbae --- /dev/null +++ b/lab/vtpc/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.12) + +project( + vtpc + VERSION 0.1 + DESCRIPTION "VT Page Cache" +) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +add_subdirectory(lib) +add_subdirectory(test) diff --git a/lab/vtpc/README.md b/lab/vtpc/README.md new file mode 100644 index 0000000..78e4047 --- /dev/null +++ b/lab/vtpc/README.md @@ -0,0 +1,47 @@ +# Базовый трек. Лабораторная работа 2 + +## Задание + +Для оптимизации работы с блочными устройствами в ОС существует кэш страниц с данными, которыми мы производим операции чтения и записи на диск. Такой кэш позволяет избежать высоких задержек при повторном доступе к данным, так как операция будет выполнена с данными в RAM, а не на диске (вспомним пирамиду памяти). + +В данной лабораторной работе необходимо реализовать блочный кэш в пространстве пользователя в виде динамической библиотеки. Политику вытеснения страниц и другие элементы задания необходимо получить у преподавателя. + +При выполнении работы необходимо реализовать простой API для работы с файлами, предоставляющий пользователю следующие возможности: + +1. Открытие файла по заданному пути файла, доступного для чтения. Процедура возвращает некоторый хэндл на файл. Пример: `int lab2_open(const char *path)`. + +2. Закрытие файла по хэндлу. Пример: `int lab2_close(int fd)`. + +3. Чтение данных из файла. Пример: `ssize_t lab2_read(int fd, void buf[.count], size_t count)`. + +4. Запись данных в файл. Пример: `ssize_t lab2_write(int fd, const void buf[.count], size_t count)`. + +5. Перестановка позиции указателя на данные файла. Достаточно поддержать только абсолютные координаты. Пример: `​​​​​​​off_t lab2_lseek(int fd, off_t offset, int whence)`. + +6. Синхронизация данных из кэша с диском. Пример: `int lab2_fsync(int fd)`. + +Операции с диском разработанного блочного кеша должны производиться в обход page cache ОС. + +В рамках проверки работоспособности разработанного блочного кэша необходимо адаптировать указанную преподавателем программу-загрузчик из ЛР 1, добавив использование кэша. Запустите программу и убедитесь, что она корректно работает. Сравните производительность до и после. + +## Ограничения + +1. Программа (комплекс программ) должна быть реализован на языке C. + +2. Если по выданному варианту задана политика вытеснения Optimal, то необходимо предоставить пользователю возможность подсказать page cache, когда будет совершен следующий доступ к данным. Это можно сделать либо добавив параметр в процедуры `read` и `write` (например, `ssize_t lab2_read(int fd, void buf[.count], size_t count, access_hint_t hint)`), либо добавив еще одну функцию в API (например, `int lab2_advice(int fd, off_t offset, access_hint_t hint)`). `access_hint_t` в данном случае – это абсолютное время или временной интервал, по которому разработанное API будет определять время последующего доступа к данным. + +3. Запрещено использовать высокоуровневые абстракции над системными вызовами. + +## Требования к отчету и защите + +Отчет должен содержать: + +1. титульный лист с указанием номера и названия ЛР, вашего ФИО, ФИО преподавателя практики, номера вашей группы, варианта ЛР; + +2. текст задания в соответствии с вариантом; + +3. краткий обзор кода; + +4. данные о работе программы-нагрузчика до и после внедрения своего page cache; + +5. заключение с анализом результатов и выводом. diff --git a/lab/vtpc/lib/CMakeLists.txt b/lab/vtpc/lib/CMakeLists.txt new file mode 100644 index 0000000..e904b37 --- /dev/null +++ b/lab/vtpc/lib/CMakeLists.txt @@ -0,0 +1,11 @@ +add_library( + vtpc + STATIC + vtpc.c +) + +target_include_directories( + vtpc + PUBLIC + . +) diff --git a/lab/vtpc/lib/vtpc.c b/lab/vtpc/lib/vtpc.c new file mode 100644 index 0000000..3b678bd --- /dev/null +++ b/lab/vtpc/lib/vtpc.c @@ -0,0 +1,28 @@ +#include "vtpc.h" + +#include +#include + +int vtpc_open(const char* path, int mode) { + return open(path, mode); +} + +int vtpc_close(int fd) { + return close(fd); +} + +ssize_t vtpc_read(int fd, void* buf, size_t count) { + return read(fd, buf, count); +} + +ssize_t vtpc_write(int fd, const void* buf, size_t count) { + return write(fd, buf, count); +} + +off_t vtpc_lseek(int fd, off_t offset, int whence) { + return lseek(fd, offset, whence); +} + +int vtpc_fsync(int fd) { + return fsync(fd); +} diff --git a/lab/vtpc/lib/vtpc.h b/lab/vtpc/lib/vtpc.h new file mode 100644 index 0000000..fa817e2 --- /dev/null +++ b/lab/vtpc/lib/vtpc.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +int vtpc_open(const char* path, int mode); +int vtpc_close(int fd); +ssize_t vtpc_read(int fd, void* buf, size_t count); +ssize_t vtpc_write(int fd, const void* buf, size_t count); +off_t vtpc_lseek(int fd, off_t offset, int whence); +int vtpc_fsync(int fd); diff --git a/lab/vtpc/test/CMakeLists.txt b/lab/vtpc/test/CMakeLists.txt new file mode 100644 index 0000000..5136fb4 --- /dev/null +++ b/lab/vtpc/test/CMakeLists.txt @@ -0,0 +1,9 @@ +set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +add_subdirectory(lib) + +add_executable(test_basic test_basic.cpp) +target_include_directories(test_basic PUBLIC .) +target_link_libraries(test_basic PRIVATE vt) diff --git a/lab/vtpc/test/lib/CMakeLists.txt b/lab/vtpc/test/lib/CMakeLists.txt new file mode 100644 index 0000000..ec729a6 --- /dev/null +++ b/lab/vtpc/test/lib/CMakeLists.txt @@ -0,0 +1,10 @@ +add_library( + vt + STATIC + cmp_file.cpp + exception.cpp + file.cpp +) + +target_include_directories(vt PUBLIC .) +target_link_libraries(vt PRIVATE vtpc) diff --git a/lab/vtpc/test/lib/cmp_file.cpp b/lab/vtpc/test/lib/cmp_file.cpp new file mode 100644 index 0000000..99221e3 --- /dev/null +++ b/lab/vtpc/test/lib/cmp_file.cpp @@ -0,0 +1,69 @@ +#include "cmp_file.hpp" + +#include + +#include "exception.hpp" +#include "file.hpp" + +namespace vt { + +template +void Compare(A lhs, B rhs) { + std::optional lhs_ex; + std::optional rhs_ex; + + try { + lhs(); + } catch (const vt::file_exception& e) { + lhs_ex = vt::file_exception(e.code()) << e.what(); + } + + try { + rhs(); + } catch (const vt::file_exception& e) { + rhs_ex = vt::file_exception(e.code()) << e.what(); + } + + if (lhs_ex && !rhs_ex) { + throw vt::cmp_file_exception() << "(FAIL, OK): " << lhs_ex->what(); + } + if (!lhs_ex && rhs_ex) { + throw vt::cmp_file_exception() << "(OK, FAIL): " << rhs_ex->what(); + } + if (lhs_ex && rhs_ex && lhs_ex->code() != rhs_ex->code()) { + throw vt::cmp_file_exception() + << "(FAIL, FAIL), but codes differ: " << lhs_ex->what() << ", " + << rhs_ex->what(); + } +} + +cmp_file::cmp_file(std::unique_ptr lhs, std::unique_ptr rhs) + : lhs_(std::move(lhs)), rhs_(std::move(rhs)) { +} + +auto cmp_file::read(char* buffer, size_t count) -> void { + Compare( + [buffer, count, this] { lhs_->read(buffer, count); }, + [buffer, count, this] { lhs_->read(buffer, count); } + ); +} + +auto cmp_file::write(const char* buffer, size_t count) -> void { + Compare( + [buffer, count, this] { lhs_->write(buffer, count); }, + [buffer, count, this] { lhs_->write(buffer, count); } + ); +} + +auto cmp_file::seek(off_t offset) -> void { + Compare( + [offset, this] { lhs_->seek(offset); }, + [offset, this] { lhs_->seek(offset); } + ); +} + +auto cmp_file::sync() -> void { + Compare([this] { lhs_->sync(); }, [this] { rhs_->sync(); }); +} + +} // namespace vt diff --git a/lab/vtpc/test/lib/cmp_file.hpp b/lab/vtpc/test/lib/cmp_file.hpp new file mode 100644 index 0000000..506480e --- /dev/null +++ b/lab/vtpc/test/lib/cmp_file.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include "file.hpp" + +namespace vt { + +class cmp_file_exception : public vt::exception {}; + +class cmp_file final : public file { +public: + cmp_file(std::unique_ptr lhs, std::unique_ptr rhs); + ~cmp_file() override = default; + + auto read(char* buffer, size_t count) -> void override; + auto write(const char* buffer, size_t count) -> void override; + auto seek(off_t offset) -> void override; + auto sync() -> void override; + +private: + std::unique_ptr lhs_; + std::unique_ptr rhs_; +}; + +} // namespace vt diff --git a/lab/vtpc/test/lib/exception.cpp b/lab/vtpc/test/lib/exception.cpp new file mode 100644 index 0000000..a3a2978 --- /dev/null +++ b/lab/vtpc/test/lib/exception.cpp @@ -0,0 +1 @@ +#include "exception.hpp" diff --git a/lab/vtpc/test/lib/exception.hpp b/lab/vtpc/test/lib/exception.hpp new file mode 100644 index 0000000..407e16d --- /dev/null +++ b/lab/vtpc/test/lib/exception.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include +#include + +namespace vt { + +class exception : public std::exception { +public: + exception() = default; + + auto what() const noexcept -> const char* override { + message_ = buffer_.str(); + return message_.c_str(); + } + + template + inline void Append(const T& t) { + buffer_ << t; + } + +private: + mutable std::stringstream buffer_; + mutable std::string message_; +}; + +template +static inline auto operator<<(E&& e [[clang::lifetimebound]], const T& t) + -> std::enable_if_t>, E&&> { + e.Append(t); + return std::forward(e); +} + +} // namespace vt \ No newline at end of file diff --git a/lab/vtpc/test/lib/file.cpp b/lab/vtpc/test/lib/file.cpp new file mode 100644 index 0000000..7a23393 --- /dev/null +++ b/lab/vtpc/test/lib/file.cpp @@ -0,0 +1,123 @@ +#include "file.hpp" + +#include +#include +#include +#include +#include + +#include "exception.hpp" + +extern "C" { +#include "fcntl.h" +#include "unistd.h" +#include "vtpc.h" +} + +namespace vt { + +constexpr auto flags = O_RDWR | O_CREAT; + +file_exception::file_exception(ssize_t code) : code_(code) { + (*this) << "code " << code << ": "; +} + +auto file_exception::code() const -> ssize_t { + return code_; +} + +struct io { + std::function open; + std::function close; + std::function read; + std::function write; + std::function lseek; + std::function fsync; +}; + +template +void robust_do(A action, int fd, auto buf, size_t count) { + size_t total = 0; + while (total < count) { + ssize_t local = action(fd, buf, count); + if (local < 0) { + throw vt::file_exception(local) + << "failed to read/write " << count << "bytes from file with fd " + << fd << ": " << strerror(errno); // NOLINT(concurrency-mt-unsafe); + } + + total += local; + } +} + +class io_file final : public file { +public: + explicit io_file(std::string_view path, io io) + : fd_(io.open(path.data(), flags)), io_(std::move(io)) { + if (fd_ < 0) { + throw vt::file_exception(fd_) + << "failed to open file '" << path << "'" + << ": " << strerror(errno); // NOLINT(concurrency-mt-unsafe); + } + } + + ~io_file() override { + (void)io_.close(fd_); + } + + void read(char* buffer, size_t count) override { + robust_do(io_.read, fd_, buffer, count); + } + + void write(const char* buffer, size_t count) override { + robust_do(io_.write, fd_, buffer, count); + } + + void seek(off_t offset) override { + if (io_.lseek(fd_, offset, SEEK_SET) == -1) { + throw vt::file_exception(-1) + << "failed to seek to offset " << offset << "file with fd " << fd_ + << ": " << strerror(errno); // NOLINT(concurrency-mt-unsafe) + } + } + + void sync() override { + if (io_.fsync(fd_) == -1) { + throw vt::file_exception(-1) + << "failed to fsync file with fd " << fd_ << ": " + << strerror(errno); // NOLINT(concurrency-mt-unsafe) + } + } + +private: + int fd_; + io io_; +}; + +auto file::open_libc(std::string_view path) -> std::unique_ptr { + io io = { + .open = ::open, + .close = ::close, + .read = ::read, + .write = ::write, + .lseek = ::lseek, + .fsync = ::fsync, + }; + + return std::make_unique(path, std::move(io)); +} + +auto file::open_vtpc(std::string_view path) -> std::unique_ptr { + io io = { + .open = ::vtpc_open, + .close = ::vtpc_close, + .read = ::vtpc_read, + .write = ::vtpc_write, + .lseek = ::vtpc_lseek, + .fsync = ::vtpc_fsync, + }; + + return std::make_unique(path, std::move(io)); +} + +} // namespace vt diff --git a/lab/vtpc/test/lib/file.hpp b/lab/vtpc/test/lib/file.hpp new file mode 100644 index 0000000..f0f0d45 --- /dev/null +++ b/lab/vtpc/test/lib/file.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include +#include +#include + +#include "exception.hpp" + +namespace vt { + +class file_exception : public vt::exception { +public: + explicit file_exception(ssize_t code); + + auto code() const -> ssize_t; + +private: + ssize_t code_; +}; + +class file { +public: + virtual ~file() = default; + virtual auto read(char* buffer, size_t count) -> void = 0; + virtual auto write(const char* buffer, size_t count) -> void = 0; + virtual auto seek(off_t offset) -> void = 0; + virtual auto sync() -> void = 0; + + static auto open_libc(std::string_view path) -> std::unique_ptr; + static auto open_vtpc(std::string_view path) -> std::unique_ptr; +}; + +} // namespace vt diff --git a/lab/vtpc/test/test_basic.cpp b/lab/vtpc/test/test_basic.cpp new file mode 100644 index 0000000..2dd0071 --- /dev/null +++ b/lab/vtpc/test/test_basic.cpp @@ -0,0 +1,33 @@ +#include +#include +#include + +#include "cmp_file.hpp" +#include "file.hpp" + +auto write(vt::file& file, std::string_view text) -> void { + file.write(text.data(), text.size()); +} + +auto read(vt::file& file, size_t size) -> std::string { + std::string text(size, 0); + file.read(text.data(), size); + return text; +} + +auto main() -> int try { + auto libc = vt::file::open_libc("/tmp/a"); + auto vtpc = vt::file::open_vtpc("/tmp/b"); + vt::cmp_file cmp(std::move(libc), std::move(vtpc)); + + std::string_view message = "Hello, World!"; + write(cmp, message); + cmp.sync(); + cmp.seek(0); + std::cout << read(cmp, message.size()) << '\n'; + + return 0; +} catch (const std::exception& e) { + std::cerr << "exception: " << e.what() << '\n'; + return 1; +} From 1a4ce699bfc18e62aa0fe2884cec1384400f61e6 Mon Sep 17 00:00:00 2001 From: vityaman Date: Sun, 31 Aug 2025 10:39:31 +0300 Subject: [PATCH 02/13] Fix issues (#8) Signed-off-by: vityaman --- lab/vtpc/lib/vtpc.c | 4 ++-- lab/vtpc/lib/vtpc.h | 2 +- lab/vtpc/test/lib/cmp_file.cpp | 21 ++++++++++++--------- lab/vtpc/test/lib/file.cpp | 5 +++-- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/lab/vtpc/lib/vtpc.c b/lab/vtpc/lib/vtpc.c index 3b678bd..a85829e 100644 --- a/lab/vtpc/lib/vtpc.c +++ b/lab/vtpc/lib/vtpc.c @@ -3,8 +3,8 @@ #include #include -int vtpc_open(const char* path, int mode) { - return open(path, mode); +int vtpc_open(const char* path, int mode, int access) { + return open(path, mode, access); } int vtpc_close(int fd) { diff --git a/lab/vtpc/lib/vtpc.h b/lab/vtpc/lib/vtpc.h index fa817e2..2d4bd40 100644 --- a/lab/vtpc/lib/vtpc.h +++ b/lab/vtpc/lib/vtpc.h @@ -2,7 +2,7 @@ #include -int vtpc_open(const char* path, int mode); +int vtpc_open(const char* path, int mode, int access); int vtpc_close(int fd); ssize_t vtpc_read(int fd, void* buf, size_t count); ssize_t vtpc_write(int fd, const void* buf, size_t count); diff --git a/lab/vtpc/test/lib/cmp_file.cpp b/lab/vtpc/test/lib/cmp_file.cpp index 99221e3..4d02ef9 100644 --- a/lab/vtpc/test/lib/cmp_file.cpp +++ b/lab/vtpc/test/lib/cmp_file.cpp @@ -1,3 +1,4 @@ + #include "cmp_file.hpp" #include @@ -42,28 +43,30 @@ cmp_file::cmp_file(std::unique_ptr lhs, std::unique_ptr rhs) } auto cmp_file::read(char* buffer, size_t count) -> void { + std::string lhs(count, ' '); + std::string rhs(count, ' '); Compare( - [buffer, count, this] { lhs_->read(buffer, count); }, - [buffer, count, this] { lhs_->read(buffer, count); } + [&] { lhs_->read(lhs.data(), count); }, + [&] { rhs_->read(rhs.data(), count); } ); + if (lhs != rhs) { + throw vt::cmp_file_exception() << "'" << lhs << "' != '" << rhs << "'"; + } + std::memcpy(buffer, lhs.data(), count); } auto cmp_file::write(const char* buffer, size_t count) -> void { Compare( - [buffer, count, this] { lhs_->write(buffer, count); }, - [buffer, count, this] { lhs_->write(buffer, count); } + [&] { lhs_->write(buffer, count); }, [&] { rhs_->write(buffer, count); } ); } auto cmp_file::seek(off_t offset) -> void { - Compare( - [offset, this] { lhs_->seek(offset); }, - [offset, this] { lhs_->seek(offset); } - ); + Compare([&] { lhs_->seek(offset); }, [&] { rhs_->seek(offset); }); } auto cmp_file::sync() -> void { - Compare([this] { lhs_->sync(); }, [this] { rhs_->sync(); }); + Compare([&] { lhs_->sync(); }, [this] { rhs_->sync(); }); } } // namespace vt diff --git a/lab/vtpc/test/lib/file.cpp b/lab/vtpc/test/lib/file.cpp index 7a23393..a3dee36 100644 --- a/lab/vtpc/test/lib/file.cpp +++ b/lab/vtpc/test/lib/file.cpp @@ -17,6 +17,7 @@ extern "C" { namespace vt { constexpr auto flags = O_RDWR | O_CREAT; +constexpr auto access = 0777; file_exception::file_exception(ssize_t code) : code_(code) { (*this) << "code " << code << ": "; @@ -27,7 +28,7 @@ auto file_exception::code() const -> ssize_t { } struct io { - std::function open; + std::function open; std::function close; std::function read; std::function write; @@ -53,7 +54,7 @@ void robust_do(A action, int fd, auto buf, size_t count) { class io_file final : public file { public: explicit io_file(std::string_view path, io io) - : fd_(io.open(path.data(), flags)), io_(std::move(io)) { + : fd_(io.open(path.data(), flags, access)), io_(std::move(io)) { if (fd_ < 0) { throw vt::file_exception(fd_) << "failed to open file '" << path << "'" From f817d7ff682b5cecdfee811706065353a15c3bc4 Mon Sep 17 00:00:00 2001 From: vityaman Date: Sun, 31 Aug 2025 10:43:32 +0300 Subject: [PATCH 03/13] Add convinience (#8) Signed-off-by: vityaman --- lab/vtpc/test/lib/cmp_file.hpp | 3 +++ lab/vtpc/test/lib/file.hpp | 10 ++++++++++ lab/vtpc/test/test_basic.cpp | 14 ++------------ 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/lab/vtpc/test/lib/cmp_file.hpp b/lab/vtpc/test/lib/cmp_file.hpp index 506480e..77b97a8 100644 --- a/lab/vtpc/test/lib/cmp_file.hpp +++ b/lab/vtpc/test/lib/cmp_file.hpp @@ -8,6 +8,9 @@ class cmp_file_exception : public vt::exception {}; class cmp_file final : public file { public: + using file::write; + using file::read; + cmp_file(std::unique_ptr lhs, std::unique_ptr rhs); ~cmp_file() override = default; diff --git a/lab/vtpc/test/lib/file.hpp b/lab/vtpc/test/lib/file.hpp index f0f0d45..376d6e1 100644 --- a/lab/vtpc/test/lib/file.hpp +++ b/lab/vtpc/test/lib/file.hpp @@ -26,6 +26,16 @@ class file { virtual auto seek(off_t offset) -> void = 0; virtual auto sync() -> void = 0; + auto write(std::string_view text) -> void { + return write(text.data(), text.size()); + } + + auto read(size_t size) -> std::string { + std::string text(size, 0); + read(text.data(), size); + return text; + } + static auto open_libc(std::string_view path) -> std::unique_ptr; static auto open_vtpc(std::string_view path) -> std::unique_ptr; }; diff --git a/lab/vtpc/test/test_basic.cpp b/lab/vtpc/test/test_basic.cpp index 2dd0071..edaf7f3 100644 --- a/lab/vtpc/test/test_basic.cpp +++ b/lab/vtpc/test/test_basic.cpp @@ -5,26 +5,16 @@ #include "cmp_file.hpp" #include "file.hpp" -auto write(vt::file& file, std::string_view text) -> void { - file.write(text.data(), text.size()); -} - -auto read(vt::file& file, size_t size) -> std::string { - std::string text(size, 0); - file.read(text.data(), size); - return text; -} - auto main() -> int try { auto libc = vt::file::open_libc("/tmp/a"); auto vtpc = vt::file::open_vtpc("/tmp/b"); vt::cmp_file cmp(std::move(libc), std::move(vtpc)); std::string_view message = "Hello, World!"; - write(cmp, message); + cmp.write(message); cmp.sync(); cmp.seek(0); - std::cout << read(cmp, message.size()) << '\n'; + std::cout << cmp.read(message.size()) << '\n'; return 0; } catch (const std::exception& e) { From 9959bfd0ae2ac3b9dbadfbb62757802facdc8b96 Mon Sep 17 00:00:00 2001 From: vityaman Date: Sun, 31 Aug 2025 11:20:28 +0300 Subject: [PATCH 04/13] Add seq test (#8) Signed-off-by: vityaman --- lab/vtpc/test/CMakeLists.txt | 4 ++++ lab/vtpc/test/test_seq.cpp | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 lab/vtpc/test/test_seq.cpp diff --git a/lab/vtpc/test/CMakeLists.txt b/lab/vtpc/test/CMakeLists.txt index 5136fb4..1a6d21a 100644 --- a/lab/vtpc/test/CMakeLists.txt +++ b/lab/vtpc/test/CMakeLists.txt @@ -7,3 +7,7 @@ add_subdirectory(lib) add_executable(test_basic test_basic.cpp) target_include_directories(test_basic PUBLIC .) target_link_libraries(test_basic PRIVATE vt) + +add_executable(test_seq test_seq.cpp) +target_include_directories(test_seq PUBLIC .) +target_link_libraries(test_seq PRIVATE vt) diff --git a/lab/vtpc/test/test_seq.cpp b/lab/vtpc/test/test_seq.cpp new file mode 100644 index 0000000..4ab68f6 --- /dev/null +++ b/lab/vtpc/test/test_seq.cpp @@ -0,0 +1,36 @@ +#include +#include +#include + +#include "cmp_file.hpp" +#include "file.hpp" + +auto main() -> int try { + constexpr size_t count = 1024; + + auto libc = vt::file::open_libc("/tmp/a"); + auto vtpc = vt::file::open_vtpc("/tmp/b"); + vt::cmp_file cmp(std::move(libc), std::move(vtpc)); + + cmp.seek(0); + for (size_t i = 0; i < count; ++i) { + std::string text = std::to_string(i); + cmp.write(text); + } + + cmp.seek(0); + for (size_t i = 0; i < count; ++i) { + std::string expected = std::to_string(i); + std::string actual = cmp.read(expected.size()); + if (expected != actual) { + throw vt::exception() << "'" << expected << "' != '" << actual << "'"; + } + } + + cmp.sync(); + + return 0; +} catch (const std::exception& e) { + std::cerr << "exception: " << e.what() << '\n'; + return 1; +} From dbf5b0aac8631b7fbed03a4df1af4f94441e32e5 Mon Sep 17 00:00:00 2001 From: vityaman Date: Sun, 31 Aug 2025 13:35:07 +0300 Subject: [PATCH 05/13] Add random test (#8) Signed-off-by: vityaman --- lab/vtpc/test/CMakeLists.txt | 4 ++ lab/vtpc/test/lib/CMakeLists.txt | 1 + lab/vtpc/test/lib/cmp_file.cpp | 14 ++++--- lab/vtpc/test/lib/cmp_file.hpp | 2 +- lab/vtpc/test/lib/file.cpp | 8 +++- lab/vtpc/test/lib/log_file.cpp | 32 +++++++++++++++ lab/vtpc/test/lib/log_file.hpp | 24 +++++++++++ lab/vtpc/test/test_random.cpp | 70 ++++++++++++++++++++++++++++++++ 8 files changed, 147 insertions(+), 8 deletions(-) create mode 100644 lab/vtpc/test/lib/log_file.cpp create mode 100644 lab/vtpc/test/lib/log_file.hpp create mode 100644 lab/vtpc/test/test_random.cpp diff --git a/lab/vtpc/test/CMakeLists.txt b/lab/vtpc/test/CMakeLists.txt index 1a6d21a..4c59001 100644 --- a/lab/vtpc/test/CMakeLists.txt +++ b/lab/vtpc/test/CMakeLists.txt @@ -11,3 +11,7 @@ target_link_libraries(test_basic PRIVATE vt) add_executable(test_seq test_seq.cpp) target_include_directories(test_seq PUBLIC .) target_link_libraries(test_seq PRIVATE vt) + +add_executable(test_random test_random.cpp) +target_include_directories(test_random PUBLIC .) +target_link_libraries(test_random PRIVATE vt) diff --git a/lab/vtpc/test/lib/CMakeLists.txt b/lab/vtpc/test/lib/CMakeLists.txt index ec729a6..9aca5ff 100644 --- a/lab/vtpc/test/lib/CMakeLists.txt +++ b/lab/vtpc/test/lib/CMakeLists.txt @@ -4,6 +4,7 @@ add_library( cmp_file.cpp exception.cpp file.cpp + log_file.cpp ) target_include_directories(vt PUBLIC .) diff --git a/lab/vtpc/test/lib/cmp_file.cpp b/lab/vtpc/test/lib/cmp_file.cpp index 4d02ef9..f740c2a 100644 --- a/lab/vtpc/test/lib/cmp_file.cpp +++ b/lab/vtpc/test/lib/cmp_file.cpp @@ -36,10 +36,14 @@ void Compare(A lhs, B rhs) { << "(FAIL, FAIL), but codes differ: " << lhs_ex->what() << ", " << rhs_ex->what(); } + if (lhs_ex && rhs_ex) { + const vt::file_exception& e = *lhs_ex; + throw vt::file_exception(e.code()) << e.what(); + } } cmp_file::cmp_file(std::unique_ptr lhs, std::unique_ptr rhs) - : lhs_(std::move(lhs)), rhs_(std::move(rhs)) { + : lhs_(std::move(lhs)), file_(std::move(rhs)) { } auto cmp_file::read(char* buffer, size_t count) -> void { @@ -47,7 +51,7 @@ auto cmp_file::read(char* buffer, size_t count) -> void { std::string rhs(count, ' '); Compare( [&] { lhs_->read(lhs.data(), count); }, - [&] { rhs_->read(rhs.data(), count); } + [&] { file_->read(rhs.data(), count); } ); if (lhs != rhs) { throw vt::cmp_file_exception() << "'" << lhs << "' != '" << rhs << "'"; @@ -57,16 +61,16 @@ auto cmp_file::read(char* buffer, size_t count) -> void { auto cmp_file::write(const char* buffer, size_t count) -> void { Compare( - [&] { lhs_->write(buffer, count); }, [&] { rhs_->write(buffer, count); } + [&] { lhs_->write(buffer, count); }, [&] { file_->write(buffer, count); } ); } auto cmp_file::seek(off_t offset) -> void { - Compare([&] { lhs_->seek(offset); }, [&] { rhs_->seek(offset); }); + Compare([&] { lhs_->seek(offset); }, [&] { file_->seek(offset); }); } auto cmp_file::sync() -> void { - Compare([&] { lhs_->sync(); }, [this] { rhs_->sync(); }); + Compare([&] { lhs_->sync(); }, [this] { file_->sync(); }); } } // namespace vt diff --git a/lab/vtpc/test/lib/cmp_file.hpp b/lab/vtpc/test/lib/cmp_file.hpp index 77b97a8..7d79d10 100644 --- a/lab/vtpc/test/lib/cmp_file.hpp +++ b/lab/vtpc/test/lib/cmp_file.hpp @@ -21,7 +21,7 @@ class cmp_file final : public file { private: std::unique_ptr lhs_; - std::unique_ptr rhs_; + std::unique_ptr file_; }; } // namespace vt diff --git a/lab/vtpc/test/lib/file.cpp b/lab/vtpc/test/lib/file.cpp index a3dee36..504e204 100644 --- a/lab/vtpc/test/lib/file.cpp +++ b/lab/vtpc/test/lib/file.cpp @@ -20,7 +20,6 @@ constexpr auto flags = O_RDWR | O_CREAT; constexpr auto access = 0777; file_exception::file_exception(ssize_t code) : code_(code) { - (*this) << "code " << code << ": "; } auto file_exception::code() const -> ssize_t { @@ -43,9 +42,14 @@ void robust_do(A action, int fd, auto buf, size_t count) { ssize_t local = action(fd, buf, count); if (local < 0) { throw vt::file_exception(local) - << "failed to read/write " << count << "bytes from file with fd " + << "failed to read/write " << count << " bytes from file with fd " << fd << ": " << strerror(errno); // NOLINT(concurrency-mt-unsafe); } + if (local == 0) { + throw vt::file_exception(0) << "failed to read/write " << count + << " bytes from file with fd " << fd << ": " + << "EOF after reading " << total << " bytes"; + } total += local; } diff --git a/lab/vtpc/test/lib/log_file.cpp b/lab/vtpc/test/lib/log_file.cpp new file mode 100644 index 0000000..afc0730 --- /dev/null +++ b/lab/vtpc/test/lib/log_file.cpp @@ -0,0 +1,32 @@ +#include "log_file.hpp" + +#include + +#include "file.hpp" + +namespace vt { + +log_file::log_file(std::unique_ptr file) : file_(std::move(file)) { +} + +auto log_file::read(char* buffer, size_t count) -> void { + std::cerr << "[vt] read count " << count << "\n"; + file_->read(buffer, count); +} + +auto log_file::write(const char* buffer, size_t count) -> void { + std::cerr << "[vt] write count " << count << "\n"; + file_->write(buffer, count); +} + +auto log_file::seek(off_t offset) -> void { + std::cerr << "[vt] seek offset " << offset << "\n"; + file_->seek(offset); +} + +auto log_file::sync() -> void { + std::cerr << "[vt] sync\n"; + file_->sync(); +} + +} // namespace vt diff --git a/lab/vtpc/test/lib/log_file.hpp b/lab/vtpc/test/lib/log_file.hpp new file mode 100644 index 0000000..c999bc8 --- /dev/null +++ b/lab/vtpc/test/lib/log_file.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include "file.hpp" + +namespace vt { + +class log_file final : public file { +public: + using file::write; + using file::read; + + explicit log_file(std::unique_ptr file); + ~log_file() override = default; + + auto read(char* buffer, size_t count) -> void override; + auto write(const char* buffer, size_t count) -> void override; + auto seek(off_t offset) -> void override; + auto sync() -> void override; + +private: + std::unique_ptr file_; +}; + +} // namespace vt diff --git a/lab/vtpc/test/test_random.cpp b/lab/vtpc/test/test_random.cpp new file mode 100644 index 0000000..1129f81 --- /dev/null +++ b/lab/vtpc/test/test_random.cpp @@ -0,0 +1,70 @@ +#include +#include +#include +#include + +#include "cmp_file.hpp" +#include "file.hpp" +#include "log_file.hpp" + +auto main() -> int try { + constexpr size_t seed = 1; + constexpr size_t steps = (1U << 16U); + constexpr size_t size = (1U << 12U); + constexpr size_t interval = 100; + + std::unique_ptr file = [] { + auto libc = vt::file::open_libc("/tmp/a"); + auto vtpc = vt::file::open_vtpc("/tmp/b"); + auto cmp = std::make_unique(std::move(libc), std::move(vtpc)); + auto log = std::make_unique(std::move(cmp)); + return log; + }(); + + std::default_random_engine random(seed); // NOLINT + + std::uniform_int_distribution action_dist(0, 100); // NOLINT + std::uniform_int_distribution offset_dist(0, size); + std::uniform_int_distribution batch_dist(0, size / 4); + std::uniform_int_distribution char_dist(0); + + const auto random_string = [&](size_t size) { + std::string string(size, ' '); + for (char& c : string) { + c = static_cast(char_dist(random)); + } + return string; + }; + + file->seek(0); + file->write(std::string(size, ' ')); + + file->seek(0); + for (size_t i = 0; i < steps; ++i) { + if (i % interval == 0) { + std::cerr << "i = " << i << '\n'; + } + + try { + size_t point = action_dist(random); + if (point < 40) { // NOLINT + size_t batch = batch_dist(random); + file->read(batch); + } else if (point < 75) { // NOLINT + size_t batch = batch_dist(random); + file->write(random_string(batch)); + } else if (point < 95) { // NOLINT + file->seek(offset_dist(random)); + } else { + file->sync(); + } + } catch (vt::file_exception& e) { // NOLINT + // Do nothing + } + } + + return 0; +} catch (const std::exception& e) { + std::cerr << "exception: " << e.what() << '\n'; + return 1; +} From c631283f98bb3da3e2222b03c1afc32fa0b5c3db Mon Sep 17 00:00:00 2001 From: vityaman Date: Sun, 31 Aug 2025 13:38:49 +0300 Subject: [PATCH 06/13] Add GitHub Flow (#8) Signed-off-by: vityaman --- .github/workflows/vtpc.yml | 51 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 .github/workflows/vtpc.yml diff --git a/.github/workflows/vtpc.yml b/.github/workflows/vtpc.yml new file mode 100644 index 0000000..933788f --- /dev/null +++ b/.github/workflows/vtpc.yml @@ -0,0 +1,51 @@ +name: Test VT Page Cache + +on: + push: + branches: + - main + pull_request: + paths: + - 'lab/vtpc/**' + +jobs: + build: + strategy: + matrix: + cmake_build_type: + - Asan + - Release + runs-on: ubuntu-latest + container: + image: silkeh/clang:latest + defaults: + run: + working-directory: ./lab/vtpc + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Clang Format + run: | + find . -path ./build -prune -o \( -iname '*.c' -o -iname '*.h' -o -iname '*.cpp' -o -iname '*.hpp' \) -exec \ + clang-format --style=file --dry-run --verbose {} \; + + - name: Configure + run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.cmake_build_type }} + + - name: Build + run: cmake --build build + + - name: Clang Tidy + run: | + find . -path ./build -prune -o \( -iname '*.c' -o -iname '*.h' -o -iname '*.cpp' -o -iname '*.hpp' \) -exec \ + clang-tidy -p . {} \; + + - name: Test Basic + run: ./build/test/test_basic + + - name: Test Sequential + run: ./build/test/test_seq + + - name: Test Random + run: ./build/test/test_random From 1aee6a5b48c1a587fb4ee5ca38a91a70e6b5580b Mon Sep 17 00:00:00 2001 From: vityaman Date: Sun, 31 Aug 2025 13:40:31 +0300 Subject: [PATCH 07/13] Fix build (#8) Signed-off-by: vityaman --- lab/vtpc/test/lib/cmp_file.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lab/vtpc/test/lib/cmp_file.cpp b/lab/vtpc/test/lib/cmp_file.cpp index f740c2a..bbb04a6 100644 --- a/lab/vtpc/test/lib/cmp_file.cpp +++ b/lab/vtpc/test/lib/cmp_file.cpp @@ -56,7 +56,7 @@ auto cmp_file::read(char* buffer, size_t count) -> void { if (lhs != rhs) { throw vt::cmp_file_exception() << "'" << lhs << "' != '" << rhs << "'"; } - std::memcpy(buffer, lhs.data(), count); + memcpy(buffer, lhs.data(), count); } auto cmp_file::write(const char* buffer, size_t count) -> void { From 0126386392a895cab8ac54fe25cbc2a456d8c012 Mon Sep 17 00:00:00 2001 From: vityaman Date: Sun, 31 Aug 2025 13:42:07 +0300 Subject: [PATCH 08/13] Format (#8) Signed-off-by: vityaman --- lab/vtpc/test/lib/cmp_file.cpp | 1 - lab/vtpc/test/lib/cmp_file.hpp | 2 +- lab/vtpc/test/lib/log_file.hpp | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lab/vtpc/test/lib/cmp_file.cpp b/lab/vtpc/test/lib/cmp_file.cpp index bbb04a6..adb3fa7 100644 --- a/lab/vtpc/test/lib/cmp_file.cpp +++ b/lab/vtpc/test/lib/cmp_file.cpp @@ -1,4 +1,3 @@ - #include "cmp_file.hpp" #include diff --git a/lab/vtpc/test/lib/cmp_file.hpp b/lab/vtpc/test/lib/cmp_file.hpp index 7d79d10..5b8d121 100644 --- a/lab/vtpc/test/lib/cmp_file.hpp +++ b/lab/vtpc/test/lib/cmp_file.hpp @@ -8,8 +8,8 @@ class cmp_file_exception : public vt::exception {}; class cmp_file final : public file { public: - using file::write; using file::read; + using file::write; cmp_file(std::unique_ptr lhs, std::unique_ptr rhs); ~cmp_file() override = default; diff --git a/lab/vtpc/test/lib/log_file.hpp b/lab/vtpc/test/lib/log_file.hpp index c999bc8..53ab6dc 100644 --- a/lab/vtpc/test/lib/log_file.hpp +++ b/lab/vtpc/test/lib/log_file.hpp @@ -6,8 +6,8 @@ namespace vt { class log_file final : public file { public: - using file::write; using file::read; + using file::write; explicit log_file(std::unique_ptr file); ~log_file() override = default; From bd2bdd542dcefcff2ed558e2fbe63dc9a963e39b Mon Sep 17 00:00:00 2001 From: vityaman Date: Sun, 31 Aug 2025 13:44:02 +0300 Subject: [PATCH 09/13] Fix build (#8) Signed-off-by: vityaman --- lab/vtpc/test/lib/cmp_file.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lab/vtpc/test/lib/cmp_file.cpp b/lab/vtpc/test/lib/cmp_file.cpp index adb3fa7..d3dafe3 100644 --- a/lab/vtpc/test/lib/cmp_file.cpp +++ b/lab/vtpc/test/lib/cmp_file.cpp @@ -1,6 +1,7 @@ #include "cmp_file.hpp" #include +#include #include "exception.hpp" #include "file.hpp" From 407b09149d717854e343f9a5ea907ccbdb1a1170 Mon Sep 17 00:00:00 2001 From: vityaman Date: Sun, 31 Aug 2025 13:45:32 +0300 Subject: [PATCH 10/13] Fix build (#8) Signed-off-by: vityaman --- lab/vtpc/test/lib/file.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lab/vtpc/test/lib/file.cpp b/lab/vtpc/test/lib/file.cpp index 504e204..ff33c89 100644 --- a/lab/vtpc/test/lib/file.cpp +++ b/lab/vtpc/test/lib/file.cpp @@ -1,6 +1,7 @@ #include "file.hpp" #include +#include #include #include #include From a193eed53618f9a88e6d80adc6956eb7a52d10ac Mon Sep 17 00:00:00 2001 From: vityaman Date: Sun, 31 Aug 2025 14:01:21 +0300 Subject: [PATCH 11/13] Fix style (#8) Signed-off-by: vityaman --- lab/vtpc/.clang-tidy | 1 + lab/vtpc/compile_commands.json | 50 +++++++++++++++++++++++++++++++++ lab/vtpc/test/lib/cmp_file.cpp | 2 +- lab/vtpc/test/lib/cmp_file.hpp | 1 + lab/vtpc/test/lib/exception.hpp | 3 +- lab/vtpc/test/lib/file.hpp | 2 +- 6 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 lab/vtpc/compile_commands.json diff --git a/lab/vtpc/.clang-tidy b/lab/vtpc/.clang-tidy index 07e1c89..6cdbcfb 100644 --- a/lab/vtpc/.clang-tidy +++ b/lab/vtpc/.clang-tidy @@ -15,6 +15,7 @@ Checks: | modernize-*, performance-*, portability-*, + -portability-avoid-pragma-once, readability-* -readability-identifier-length WarningsAsErrors: '*' diff --git a/lab/vtpc/compile_commands.json b/lab/vtpc/compile_commands.json new file mode 100644 index 0000000..093a2f6 --- /dev/null +++ b/lab/vtpc/compile_commands.json @@ -0,0 +1,50 @@ +[ +{ + "directory": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/build/lib", + "command": "/usr/bin/cc -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/lib/. -arch arm64 -o CMakeFiles/vtpc.dir/vtpc.c.o -c /Users/vitya-smirnov/itmo/os-course/lab/vtpc/lib/vtpc.c", + "file": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/lib/vtpc.c", + "output": "lib/CMakeFiles/vtpc.dir/vtpc.c.o" +}, +{ + "directory": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/build/test", + "command": "/usr/bin/c++ -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/. -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/. -std=c++2b -arch arm64 -o CMakeFiles/test_basic.dir/test_basic.cpp.o -c /Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/test_basic.cpp", + "file": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/test_basic.cpp", + "output": "test/CMakeFiles/test_basic.dir/test_basic.cpp.o" +}, +{ + "directory": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/build/test", + "command": "/usr/bin/c++ -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/. -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/. -std=c++2b -arch arm64 -o CMakeFiles/test_seq.dir/test_seq.cpp.o -c /Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/test_seq.cpp", + "file": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/test_seq.cpp", + "output": "test/CMakeFiles/test_seq.dir/test_seq.cpp.o" +}, +{ + "directory": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/build/test", + "command": "/usr/bin/c++ -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/. -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/. -std=c++2b -arch arm64 -o CMakeFiles/test_random.dir/test_random.cpp.o -c /Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/test_random.cpp", + "file": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/test_random.cpp", + "output": "test/CMakeFiles/test_random.dir/test_random.cpp.o" +}, +{ + "directory": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/build/test/lib", + "command": "/usr/bin/c++ -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/. -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/lib/. -std=c++2b -arch arm64 -o CMakeFiles/vt.dir/cmp_file.cpp.o -c /Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/cmp_file.cpp", + "file": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/cmp_file.cpp", + "output": "test/lib/CMakeFiles/vt.dir/cmp_file.cpp.o" +}, +{ + "directory": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/build/test/lib", + "command": "/usr/bin/c++ -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/. -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/lib/. -std=c++2b -arch arm64 -o CMakeFiles/vt.dir/exception.cpp.o -c /Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/exception.cpp", + "file": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/exception.cpp", + "output": "test/lib/CMakeFiles/vt.dir/exception.cpp.o" +}, +{ + "directory": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/build/test/lib", + "command": "/usr/bin/c++ -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/. -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/lib/. -std=c++2b -arch arm64 -o CMakeFiles/vt.dir/file.cpp.o -c /Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/file.cpp", + "file": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/file.cpp", + "output": "test/lib/CMakeFiles/vt.dir/file.cpp.o" +}, +{ + "directory": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/build/test/lib", + "command": "/usr/bin/c++ -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/. -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/lib/. -std=c++2b -arch arm64 -o CMakeFiles/vt.dir/log_file.cpp.o -c /Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/log_file.cpp", + "file": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/log_file.cpp", + "output": "test/lib/CMakeFiles/vt.dir/log_file.cpp.o" +} +] \ No newline at end of file diff --git a/lab/vtpc/test/lib/cmp_file.cpp b/lab/vtpc/test/lib/cmp_file.cpp index d3dafe3..d24fe6e 100644 --- a/lab/vtpc/test/lib/cmp_file.cpp +++ b/lab/vtpc/test/lib/cmp_file.cpp @@ -1,7 +1,7 @@ #include "cmp_file.hpp" -#include #include +#include #include "exception.hpp" #include "file.hpp" diff --git a/lab/vtpc/test/lib/cmp_file.hpp b/lab/vtpc/test/lib/cmp_file.hpp index 5b8d121..1454cd7 100644 --- a/lab/vtpc/test/lib/cmp_file.hpp +++ b/lab/vtpc/test/lib/cmp_file.hpp @@ -1,5 +1,6 @@ #pragma once +#include "exception.hpp" #include "file.hpp" namespace vt { diff --git a/lab/vtpc/test/lib/exception.hpp b/lab/vtpc/test/lib/exception.hpp index 407e16d..d0cde05 100644 --- a/lab/vtpc/test/lib/exception.hpp +++ b/lab/vtpc/test/lib/exception.hpp @@ -9,13 +9,14 @@ class exception : public std::exception { public: exception() = default; + [[nodiscard]] auto what() const noexcept -> const char* override { message_ = buffer_.str(); return message_.c_str(); } template - inline void Append(const T& t) { + void Append(const T& t) { buffer_ << t; } diff --git a/lab/vtpc/test/lib/file.hpp b/lab/vtpc/test/lib/file.hpp index 376d6e1..28ea1c5 100644 --- a/lab/vtpc/test/lib/file.hpp +++ b/lab/vtpc/test/lib/file.hpp @@ -12,7 +12,7 @@ class file_exception : public vt::exception { public: explicit file_exception(ssize_t code); - auto code() const -> ssize_t; + [[nodiscard]] auto code() const -> ssize_t; private: ssize_t code_; From b970881d1e8862c1347fbaa3232f9f2450d8faea Mon Sep 17 00:00:00 2001 From: vityaman Date: Sun, 31 Aug 2025 15:15:12 +0300 Subject: [PATCH 12/13] What? (#8) Signed-off-by: vityaman --- .github/workflows/vtpc.yml | 2 +- .github/workflows/vtsh.yml | 2 +- lab/vtpc/compile_commands.json | 50 ---------------------------------- 3 files changed, 2 insertions(+), 52 deletions(-) delete mode 100644 lab/vtpc/compile_commands.json diff --git a/.github/workflows/vtpc.yml b/.github/workflows/vtpc.yml index 933788f..6cf950a 100644 --- a/.github/workflows/vtpc.yml +++ b/.github/workflows/vtpc.yml @@ -39,7 +39,7 @@ jobs: - name: Clang Tidy run: | find . -path ./build -prune -o \( -iname '*.c' -o -iname '*.h' -o -iname '*.cpp' -o -iname '*.hpp' \) -exec \ - clang-tidy -p . {} \; + clang-tidy -p ./build {} \; - name: Test Basic run: ./build/test/test_basic diff --git a/.github/workflows/vtsh.yml b/.github/workflows/vtsh.yml index c1ec7cf..a0304ce 100644 --- a/.github/workflows/vtsh.yml +++ b/.github/workflows/vtsh.yml @@ -39,7 +39,7 @@ jobs: - name: Clang Tidy run: | find . -path ./build -prune -o \( -iname '*.c' -o -iname '*.h' \) -exec \ - clang-tidy -p . {} \; + clang-tidy -p ./build {} \; - name: Test working-directory: ./lab/vtsh/test diff --git a/lab/vtpc/compile_commands.json b/lab/vtpc/compile_commands.json deleted file mode 100644 index 093a2f6..0000000 --- a/lab/vtpc/compile_commands.json +++ /dev/null @@ -1,50 +0,0 @@ -[ -{ - "directory": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/build/lib", - "command": "/usr/bin/cc -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/lib/. -arch arm64 -o CMakeFiles/vtpc.dir/vtpc.c.o -c /Users/vitya-smirnov/itmo/os-course/lab/vtpc/lib/vtpc.c", - "file": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/lib/vtpc.c", - "output": "lib/CMakeFiles/vtpc.dir/vtpc.c.o" -}, -{ - "directory": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/build/test", - "command": "/usr/bin/c++ -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/. -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/. -std=c++2b -arch arm64 -o CMakeFiles/test_basic.dir/test_basic.cpp.o -c /Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/test_basic.cpp", - "file": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/test_basic.cpp", - "output": "test/CMakeFiles/test_basic.dir/test_basic.cpp.o" -}, -{ - "directory": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/build/test", - "command": "/usr/bin/c++ -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/. -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/. -std=c++2b -arch arm64 -o CMakeFiles/test_seq.dir/test_seq.cpp.o -c /Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/test_seq.cpp", - "file": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/test_seq.cpp", - "output": "test/CMakeFiles/test_seq.dir/test_seq.cpp.o" -}, -{ - "directory": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/build/test", - "command": "/usr/bin/c++ -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/. -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/. -std=c++2b -arch arm64 -o CMakeFiles/test_random.dir/test_random.cpp.o -c /Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/test_random.cpp", - "file": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/test_random.cpp", - "output": "test/CMakeFiles/test_random.dir/test_random.cpp.o" -}, -{ - "directory": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/build/test/lib", - "command": "/usr/bin/c++ -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/. -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/lib/. -std=c++2b -arch arm64 -o CMakeFiles/vt.dir/cmp_file.cpp.o -c /Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/cmp_file.cpp", - "file": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/cmp_file.cpp", - "output": "test/lib/CMakeFiles/vt.dir/cmp_file.cpp.o" -}, -{ - "directory": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/build/test/lib", - "command": "/usr/bin/c++ -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/. -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/lib/. -std=c++2b -arch arm64 -o CMakeFiles/vt.dir/exception.cpp.o -c /Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/exception.cpp", - "file": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/exception.cpp", - "output": "test/lib/CMakeFiles/vt.dir/exception.cpp.o" -}, -{ - "directory": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/build/test/lib", - "command": "/usr/bin/c++ -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/. -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/lib/. -std=c++2b -arch arm64 -o CMakeFiles/vt.dir/file.cpp.o -c /Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/file.cpp", - "file": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/file.cpp", - "output": "test/lib/CMakeFiles/vt.dir/file.cpp.o" -}, -{ - "directory": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/build/test/lib", - "command": "/usr/bin/c++ -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/. -I/Users/vitya-smirnov/itmo/os-course/lab/vtpc/lib/. -std=c++2b -arch arm64 -o CMakeFiles/vt.dir/log_file.cpp.o -c /Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/log_file.cpp", - "file": "/Users/vitya-smirnov/itmo/os-course/lab/vtpc/test/lib/log_file.cpp", - "output": "test/lib/CMakeFiles/vt.dir/log_file.cpp.o" -} -] \ No newline at end of file From 31ec6a603d107dbb6fb6edbdf5a8932571e6210c Mon Sep 17 00:00:00 2001 From: vityaman Date: Sun, 31 Aug 2025 12:49:19 +0000 Subject: [PATCH 13/13] Style (#8) Signed-off-by: vityaman --- .github/workflows/vtpc.yml | 9 ++++++--- .github/workflows/vtsh.yml | 9 ++++++--- lab/vtpc/lib/vtpc.c | 2 ++ lab/vtpc/test/lib/cmp_file.cpp | 6 ++++++ lab/vtpc/test/lib/cmp_file.hpp | 5 +++++ lab/vtpc/test/lib/exception.cpp | 2 +- lab/vtpc/test/lib/exception.hpp | 5 +++-- lab/vtpc/test/lib/file.cpp | 20 ++++++++++++-------- lab/vtpc/test/lib/file.hpp | 5 ++++- lab/vtpc/test/lib/log_file.cpp | 5 +++++ lab/vtpc/test/lib/log_file.hpp | 5 +++++ lab/vtpc/test/test_basic.cpp | 1 + lab/vtpc/test/test_random.cpp | 6 ++++++ lab/vtpc/test/test_seq.cpp | 3 +++ 14 files changed, 65 insertions(+), 18 deletions(-) diff --git a/.github/workflows/vtpc.yml b/.github/workflows/vtpc.yml index 6cf950a..979f74e 100644 --- a/.github/workflows/vtpc.yml +++ b/.github/workflows/vtpc.yml @@ -27,8 +27,9 @@ jobs: - name: Clang Format run: | - find . -path ./build -prune -o \( -iname '*.c' -o -iname '*.h' -o -iname '*.cpp' -o -iname '*.hpp' \) -exec \ - clang-format --style=file --dry-run --verbose {} \; + find . -path ./build -prune -o \ + \( -iname '*.c' -o -iname '*.h' -o -iname '*.cpp' -o -iname '*.hpp' \) \ + -exec clang-format --style=file --dry-run --verbose {} \; - name: Configure run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.cmake_build_type }} @@ -37,8 +38,10 @@ jobs: run: cmake --build build - name: Clang Tidy + if: matrix.cmake_build_type == 'Release' run: | - find . -path ./build -prune -o \( -iname '*.c' -o -iname '*.h' -o -iname '*.cpp' -o -iname '*.hpp' \) -exec \ + find . -path ./build -prune -o \ + \( -iname '*.c' -o -iname '*.h' -o -iname '*.cpp' -o -iname '*.hpp' \) -exec \ clang-tidy -p ./build {} \; - name: Test Basic diff --git a/.github/workflows/vtsh.yml b/.github/workflows/vtsh.yml index a0304ce..2fbfefe 100644 --- a/.github/workflows/vtsh.yml +++ b/.github/workflows/vtsh.yml @@ -27,8 +27,9 @@ jobs: - name: Clang Format run: | - find . -path ./build -prune -o \( -iname '*.c' -o -iname '*.h' \) -exec \ - clang-format --style=file --dry-run --verbose {} \; + find . -path ./build -prune -o \ + \( -iname '*.c' -o -iname '*.h' -o -iname '*.cpp' -o -iname '*.hpp' \) \ + -exec clang-format --style=file --dry-run --verbose {} \; - name: Configure run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.cmake_build_type }} @@ -37,8 +38,10 @@ jobs: run: cmake --build build - name: Clang Tidy + if: matrix.cmake_build_type == 'Release' run: | - find . -path ./build -prune -o \( -iname '*.c' -o -iname '*.h' \) -exec \ + find . -path ./build -prune -o \ + \( -iname '*.c' -o -iname '*.h' -o -iname '*.cpp' -o -iname '*.hpp' \) -exec \ clang-tidy -p ./build {} \; - name: Test diff --git a/lab/vtpc/lib/vtpc.c b/lab/vtpc/lib/vtpc.c index a85829e..173ab1b 100644 --- a/lab/vtpc/lib/vtpc.c +++ b/lab/vtpc/lib/vtpc.c @@ -1,6 +1,8 @@ #include "vtpc.h" #include +#include +#include #include int vtpc_open(const char* path, int mode, int access) { diff --git a/lab/vtpc/test/lib/cmp_file.cpp b/lab/vtpc/test/lib/cmp_file.cpp index d24fe6e..db42e63 100644 --- a/lab/vtpc/test/lib/cmp_file.cpp +++ b/lab/vtpc/test/lib/cmp_file.cpp @@ -1,7 +1,13 @@ #include "cmp_file.hpp" +#include + +#include #include +#include #include +#include +#include #include "exception.hpp" #include "file.hpp" diff --git a/lab/vtpc/test/lib/cmp_file.hpp b/lab/vtpc/test/lib/cmp_file.hpp index 1454cd7..b984ae1 100644 --- a/lab/vtpc/test/lib/cmp_file.hpp +++ b/lab/vtpc/test/lib/cmp_file.hpp @@ -1,5 +1,10 @@ #pragma once +#include + +#include +#include + #include "exception.hpp" #include "file.hpp" diff --git a/lab/vtpc/test/lib/exception.cpp b/lab/vtpc/test/lib/exception.cpp index a3a2978..18042a1 100644 --- a/lab/vtpc/test/lib/exception.cpp +++ b/lab/vtpc/test/lib/exception.cpp @@ -1 +1 @@ -#include "exception.hpp" +#include "exception.hpp" // NOLINT diff --git a/lab/vtpc/test/lib/exception.hpp b/lab/vtpc/test/lib/exception.hpp index d0cde05..9dd8d6d 100644 --- a/lab/vtpc/test/lib/exception.hpp +++ b/lab/vtpc/test/lib/exception.hpp @@ -2,6 +2,7 @@ #include #include +#include namespace vt { @@ -26,8 +27,8 @@ class exception : public std::exception { }; template -static inline auto operator<<(E&& e [[clang::lifetimebound]], const T& t) - -> std::enable_if_t>, E&&> { + requires std::is_base_of_v> +static auto operator<<(E&& e [[clang::lifetimebound]], const T& t) -> E&& { e.Append(t); return std::forward(e); } diff --git a/lab/vtpc/test/lib/file.cpp b/lab/vtpc/test/lib/file.cpp index ff33c89..dff8ed9 100644 --- a/lab/vtpc/test/lib/file.cpp +++ b/lab/vtpc/test/lib/file.cpp @@ -1,6 +1,8 @@ #include "file.hpp" +#include #include +#include #include #include #include @@ -10,8 +12,10 @@ #include "exception.hpp" extern "C" { -#include "fcntl.h" -#include "unistd.h" +#include +#include +#include + #include "vtpc.h" } @@ -40,16 +44,16 @@ template void robust_do(A action, int fd, auto buf, size_t count) { size_t total = 0; while (total < count) { - ssize_t local = action(fd, buf, count); + const ssize_t local = action(fd, buf, count); if (local < 0) { throw vt::file_exception(local) << "failed to read/write " << count << " bytes from file with fd " << fd << ": " << strerror(errno); // NOLINT(concurrency-mt-unsafe); } if (local == 0) { - throw vt::file_exception(0) << "failed to read/write " << count - << " bytes from file with fd " << fd << ": " - << "EOF after reading " << total << " bytes"; + throw vt::file_exception(0) + << "failed to read/write " << count << " bytes from file with fd " + << fd << ": " << "EOF after reading " << total << " bytes"; } total += local; @@ -62,8 +66,8 @@ class io_file final : public file { : fd_(io.open(path.data(), flags, access)), io_(std::move(io)) { if (fd_ < 0) { throw vt::file_exception(fd_) - << "failed to open file '" << path << "'" - << ": " << strerror(errno); // NOLINT(concurrency-mt-unsafe); + << "failed to open file '" << path << "'" << ": " + << strerror(errno); // NOLINT(concurrency-mt-unsafe); } } diff --git a/lab/vtpc/test/lib/file.hpp b/lab/vtpc/test/lib/file.hpp index 28ea1c5..378aedd 100644 --- a/lab/vtpc/test/lib/file.hpp +++ b/lab/vtpc/test/lib/file.hpp @@ -1,7 +1,10 @@ #pragma once +#include + #include #include +#include #include #include "exception.hpp" @@ -27,7 +30,7 @@ class file { virtual auto sync() -> void = 0; auto write(std::string_view text) -> void { - return write(text.data(), text.size()); + write(text.data(), text.size()); } auto read(size_t size) -> std::string { diff --git a/lab/vtpc/test/lib/log_file.cpp b/lab/vtpc/test/lib/log_file.cpp index afc0730..499eca1 100644 --- a/lab/vtpc/test/lib/log_file.cpp +++ b/lab/vtpc/test/lib/log_file.cpp @@ -1,6 +1,11 @@ #include "log_file.hpp" +#include + +#include #include +#include +#include #include "file.hpp" diff --git a/lab/vtpc/test/lib/log_file.hpp b/lab/vtpc/test/lib/log_file.hpp index 53ab6dc..d5c8aa9 100644 --- a/lab/vtpc/test/lib/log_file.hpp +++ b/lab/vtpc/test/lib/log_file.hpp @@ -1,5 +1,10 @@ #pragma once +#include + +#include +#include + #include "file.hpp" namespace vt { diff --git a/lab/vtpc/test/test_basic.cpp b/lab/vtpc/test/test_basic.cpp index edaf7f3..74c0855 100644 --- a/lab/vtpc/test/test_basic.cpp +++ b/lab/vtpc/test/test_basic.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "cmp_file.hpp" #include "file.hpp" diff --git a/lab/vtpc/test/test_random.cpp b/lab/vtpc/test/test_random.cpp index 1129f81..9d91208 100644 --- a/lab/vtpc/test/test_random.cpp +++ b/lab/vtpc/test/test_random.cpp @@ -1,7 +1,13 @@ +#include + +#include +#include #include #include #include #include +#include +#include #include "cmp_file.hpp" #include "file.hpp" diff --git a/lab/vtpc/test/test_seq.cpp b/lab/vtpc/test/test_seq.cpp index 4ab68f6..3aa417a 100644 --- a/lab/vtpc/test/test_seq.cpp +++ b/lab/vtpc/test/test_seq.cpp @@ -1,6 +1,9 @@ +#include #include #include #include +#include +#include #include "cmp_file.hpp" #include "file.hpp"