Some fiddeling as a POC

This commit is contained in:
2024-02-01 21:48:04 +01:00
parent d211be1982
commit ff382b0e51
4 changed files with 143 additions and 83 deletions

84
.vscode/settings.json vendored
View File

@@ -2,87 +2,7 @@
"clangd.arguments": ["-background-index", "-compile-commands-dir=builddir/"], "clangd.arguments": ["-background-index", "-compile-commands-dir=builddir/"],
"editor.formatOnType": false, "editor.formatOnType": false,
"editor.formatOnSave": true, "editor.formatOnSave": true,
"files.associations": {
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"array": "cpp",
"atomic": "cpp",
"strstream": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"bitset": "cpp",
"cfenv": "cpp",
"chrono": "cpp",
"codecvt": "cpp",
"compare": "cpp",
"complex": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"cstdint": "cpp",
"deque": "cpp",
"forward_list": "cpp",
"list": "cpp",
"map": "cpp",
"set": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"source_location": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"fstream": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"numbers": "cpp",
"ostream": "cpp",
"semaphore": "cpp",
"shared_mutex": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"stop_token": "cpp",
"streambuf": "cpp",
"thread": "cpp",
"cinttypes": "cpp",
"typeindex": "cpp",
"typeinfo": "cpp",
"valarray": "cpp",
"variant": "cpp",
"csignal": "cpp",
"any": "cpp",
"regex": "cpp",
"future": "cpp",
"charconv": "cpp",
"*.ipp": "cpp"
},
"clang-tidy.buildPath": "builddir/", "clang-tidy.buildPath": "builddir/",
"clangd.onConfigChanged": "restart",] "clangd.onConfigChanged": "restart",
"C_Cpp.default.compileCommands": "/home/moritz/src/shmem/builddir/compile_commands.json"
} }

View File

@@ -1,6 +1,27 @@
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include <chrono>
#include <cstddef>
#include <cstdlib>
#include <ctime>
#include <thread>
#include "shmem.hpp"
class foo {
public:
std::array<uint8_t, 1024 * 1024 * 4> data;
};
int main(int, char**) { int main(int, char**) {
spdlog::info("shmem version {}", PROJ_VERSION); spdlog::info("shmem version {}", PROJ_VERSION);
shmem::shmem_ptr<foo> shmString("/shared_foobaz");
std::srand(std::time(nullptr));
int random_delay = 1 + std::rand() / ((RAND_MAX + 1u) / 30);
spdlog::info("Sleeping for {}s", random_delay);
std::this_thread::sleep_for(std::chrono::seconds(random_delay));
return 0; return 0;
} }

119
src/shmem.hpp Normal file
View File

@@ -0,0 +1,119 @@
#pragma once
#include <fcntl.h>
#include <spdlog/spdlog.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <array>
#include <atomic>
#include <cstdint>
#include <cstring>
#include <exception>
#include <new>
#include <string>
namespace shmem {
struct meminfo {
std::array<char, 5> magic{'s', 'h', 'm', 'e', 'm'};
uint64_t refcount = 0;
std::atomic_bool lock{false};
};
template <class T>
class shmem_ptr {
public:
/**
* @brief Construct a new shmem ptr object using the provided file descriptor
*
* @param fd file descriptor
*/
shmem_ptr(int fd) { spdlog::error("Not implemented"); }
/**
* @brief Constructs a shmem_ptr using the provided name and permissions. If the shared memory does not exist, it will be created. Memory must be read-write and will be created read-write.
*
* @param name shared memory identifier, max 255 chars. Usually begins with /, i.e. /somename
*/
shmem_ptr(const std::string& name)
: mFd(shm_open(name.c_str(), O_RDWR | O_CREAT, 0660)), mName(name) {
spdlog::info("ctor");
if (mFd <= 0) {
spdlog::critical("Bad alloc: {}", strerror(mFd));
throw std::bad_alloc();
}
int ret = ftruncate(mFd, mSize);
if (ret < 0) {
spdlog::critical("Error resizing shared memory: {}", strerror(ret));
throw std::bad_alloc();
}
void* mShmPtr = mmap(nullptr, mSize, PROT_READ | PROT_WRITE, MAP_SHARED, mFd, 0);
if (mShmPtr == MAP_FAILED) {
spdlog::critical("Can't map shared memory: {}", strerror(ret));
throw std::bad_alloc();
}
// the fun begins
mMeminfo = reinterpret_cast<meminfo*>(mShmPtr);
void* rawTPtr = mMeminfo + sizeof(meminfo);
mPtr = reinterpret_cast<T*>(rawTPtr);
if (strncmp("shmem", mMeminfo->magic.data(), 5) != 0) {
spdlog::info("Creating fresh mem info");
meminfo freshMemInfo{};
memcpy(mMeminfo, &freshMemInfo, sizeof(meminfo));
}
// mutex start
while ((mMeminfo->lock.load(std::memory_order_acquire)))
;
mMeminfo->lock.store(true, std::memory_order_release);
++mMeminfo->refcount;
spdlog::info("Refcount is {}", mMeminfo->refcount);
mMeminfo->lock.store(false, std::memory_order_release);
};
shmem_ptr(const shmem_ptr&) { spdlog::error("Not implemented"); }
shmem_ptr& operator=(const shmem_ptr&) { spdlog::error("Not implemented"); }
shmem_ptr(const shmem_ptr&&) { spdlog::error("Not implemented"); }
shmem_ptr& operator=(shmem_ptr&&) { spdlog::error("Not implemented"); }
~shmem_ptr() {
spdlog::info("dtor");
// mutex start
while ((mMeminfo->lock.load(std::memory_order_acquire)))
;
mMeminfo->lock.store(true, std::memory_order_release);
//mMeminfo->refcount = -3;
--mMeminfo->refcount;
spdlog::info("Refcount is {}", mMeminfo->refcount);
if (0 == mMeminfo->refcount) {
munmap(mShmPtr, mSize);
auto ret = shm_unlink(mName.c_str());
if (-1 == ret) {
spdlog::error("Failed unlinking shared memory, nothing we can do about it...");
}
} else {
mMeminfo->lock.store(false, std::memory_order_release);
munmap(mShmPtr, mSize);
}
}
private:
void* mShmPtr{nullptr};
T* mPtr{nullptr};
size_t mSize{sizeof(meminfo) + sizeof(T)};
int mFd{0};
struct meminfo* mMeminfo{nullptr};
std::string mName = "";
};
template <class T, class... Args>
shmem_ptr<T> make_shmem(Args&&... args) {}
} // namespace shmem

View File

@@ -6,7 +6,7 @@ foreach test : tests
executable(test.get(1), executable(test.get(1),
sources: test.get(2), sources: test.get(2),
include_directories: incdir, include_directories: incdir,
dependencies: [gtest_dep, usb_dep, log_dep, pangocairo_dep, cli11_dep] dependencies: [gtest_dep, log_dep]
) )
) )
endforeach endforeach