From bd801907bf3b8b6bcbafb09d73d76018deba4266 Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Tue, 16 Apr 2024 11:13:40 +0200 Subject: libcamera: internal: Move SharedMemObject class to a common directory Move SharedMemObject class out of RPi namespace and put it into include/libcamera/internal so that everyone could use it. Tested-by: Bryan O'Donoghue # sc8280xp Lenovo x13s Tested-by: Pavel Machek Reviewed-by: Pavel Machek Reviewed-by: Milan Zamazal Reviewed-by: Laurent Pinchart Signed-off-by: Andrey Konovalov Signed-off-by: Hans de Goede Signed-off-by: Kieran Bingham --- include/libcamera/internal/meson.build | 1 + include/libcamera/internal/shared_mem_object.h | 124 +++++++++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 include/libcamera/internal/shared_mem_object.h (limited to 'include') diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build index 33eb0fb3..5807dfd9 100644 --- a/include/libcamera/internal/meson.build +++ b/include/libcamera/internal/meson.build @@ -39,6 +39,7 @@ libcamera_internal_headers = files([ 'process.h', 'pub_key.h', 'request.h', + 'shared_mem_object.h', 'source_paths.h', 'sysfs.h', 'v4l2_device.h', diff --git a/include/libcamera/internal/shared_mem_object.h b/include/libcamera/internal/shared_mem_object.h new file mode 100644 index 00000000..98636b44 --- /dev/null +++ b/include/libcamera/internal/shared_mem_object.h @@ -0,0 +1,124 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023, Raspberry Pi Ltd + * + * shared_mem_object.h - Helper class for shared memory allocations + */ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace libcamera { + +template +class SharedMemObject +{ +public: + static constexpr std::size_t SIZE = sizeof(T); + + SharedMemObject() + : obj_(nullptr) + { + } + + template + SharedMemObject(const std::string &name, Args &&...args) + : name_(name), obj_(nullptr) + { + void *mem; + int ret; + + ret = memfd_create(name_.c_str(), MFD_CLOEXEC); + if (ret < 0) + return; + + fd_ = SharedFD(std::move(ret)); + if (!fd_.isValid()) + return; + + ret = ftruncate(fd_.get(), SIZE); + if (ret < 0) + return; + + mem = mmap(nullptr, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, + fd_.get(), 0); + if (mem == MAP_FAILED) + return; + + obj_ = new (mem) T(std::forward(args)...); + } + + SharedMemObject(SharedMemObject &&rhs) + { + this->name_ = std::move(rhs.name_); + this->fd_ = std::move(rhs.fd_); + this->obj_ = rhs.obj_; + rhs.obj_ = nullptr; + } + + ~SharedMemObject() + { + if (obj_) { + obj_->~T(); + munmap(obj_, SIZE); + } + } + + /* Make SharedMemObject non-copyable for now. */ + LIBCAMERA_DISABLE_COPY(SharedMemObject) + + SharedMemObject &operator=(SharedMemObject &&rhs) + { + this->name_ = std::move(rhs.name_); + this->fd_ = std::move(rhs.fd_); + this->obj_ = rhs.obj_; + rhs.obj_ = nullptr; + return *this; + } + + T *operator->() + { + return obj_; + } + + const T *operator->() const + { + return obj_; + } + + T &operator*() + { + return *obj_; + } + + const T &operator*() const + { + return *obj_; + } + + const SharedFD &fd() const + { + return fd_; + } + + explicit operator bool() const + { + return !!obj_; + } + +private: + std::string name_; + SharedFD fd_; + T *obj_; +}; + +} /* namespace libcamera */ -- cgit v1.2.1