[2/5] libcamera: Add template for pool implementation
diff mbox series

Message ID 20241009074642.2965791-3-chenghaoyang@chromium.org
State New
Headers show
Series
  • Add InfoFrame
Related show

Commit Message

Cheng-Hao Yang Oct. 9, 2024, 7:41 a.m. UTC
Add a template helper class as a Pool, which owns a list of objects that
allows requesting and recycling objects. Mostly used as buffer pools.

Signed-off-by: Han-Lin Chen <hanlinchen@chromium.org>
Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>
Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
---
 include/libcamera/internal/meson.build |   1 +
 include/libcamera/internal/pool.h      | 119 +++++++++++++++++++++++++
 src/libcamera/meson.build              |   1 +
 src/libcamera/pool.cpp                 |  70 +++++++++++++++
 4 files changed, 191 insertions(+)
 create mode 100644 include/libcamera/internal/pool.h
 create mode 100644 src/libcamera/pool.cpp

Patch
diff mbox series

diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build
index 4c1228b95..b78e51d0b 100644
--- a/include/libcamera/internal/meson.build
+++ b/include/libcamera/internal/meson.build
@@ -32,6 +32,7 @@  libcamera_internal_headers = files([
     'media_device.h',
     'media_object.h',
     'pipeline_handler.h',
+    'pool.h',
     'process.h',
     'pub_key.h',
     'request.h',
diff --git a/include/libcamera/internal/pool.h b/include/libcamera/internal/pool.h
new file mode 100644
index 000000000..578c6dd12
--- /dev/null
+++ b/include/libcamera/internal/pool.h
@@ -0,0 +1,119 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2024, Google Inc.
+ *
+ * pool.h - Template class for generic pool
+ *
+ * Common usage:
+ *
+ * Unique tokens:
+ * Pool<uint32_t, BasicContainer<uint32_t>>;
+ *
+ * Auto closed Fds:
+ * Pool<int, UniqueFD>;
+ *
+ * Auto destructed FrameBuffers:
+ * Pool<FrameBuffer *, std::unique_ptr<FrameBuffer>>;
+ */
+
+#pragma once
+
+#include <algorithm>
+#include <deque>
+#include <set>
+#include <string>
+#include <vector>
+
+#include <libcamera/base/log.h>
+#include <libcamera/base/mutex.h>
+
+namespace libcamera {
+
+LOG_DEFINE_CATEGORY(Pool)
+
+template<typename T, typename UniquePtr>
+class Pool : public Loggable
+{
+public:
+	Pool() = default;
+	~Pool() = default;
+
+	/* Loggable */
+	std::string logPrefix() const override { return "Pool"; }
+
+	void setData(std::vector<UniquePtr> &pool)
+	{
+		pool_.swap(pool);
+		free_.clear();
+		inUse_.clear();
+
+		for (auto &fd : pool_) {
+			free_.emplace_back(fd.get());
+		}
+	}
+
+	void release()
+	{
+		pool_.clear();
+		free_.clear();
+		inUse_.clear();
+	}
+
+	std::vector<UniquePtr> &content()
+	{
+		return pool_;
+	}
+
+	size_t size()
+	{
+		return pool_.size();
+	}
+
+	T get()
+	{
+		std::scoped_lock lock(mutex_);
+
+		if (free_.empty())
+			LOG(Pool, Fatal) << "not enough data in the Pool";
+
+		T fd = free_.front();
+		free_.pop_front();
+		inUse_.emplace(fd);
+
+		return fd;
+	}
+
+	void put(T data)
+	{
+		std::scoped_lock lock(mutex_);
+
+		auto iter = std::find(inUse_.begin(), inUse_.end(), data);
+		if (iter == inUse_.end())
+			LOG(Pool, Fatal) << "return data not belonging to the pool";
+
+		inUse_.erase(iter);
+		free_.emplace_front(data);
+	}
+
+private:
+	LIBCAMERA_DISABLE_COPY_AND_MOVE(Pool)
+
+	std::vector<UniquePtr> pool_;
+	std::deque<T> free_;
+	std::set<T> inUse_;
+	Mutex mutex_;
+};
+
+template<typename T>
+class BasicContainer
+{
+public:
+	BasicContainer(T &value)
+		: value_(value) {}
+	T get() { return value_; }
+
+private:
+	T value_;
+};
+
+} /* namespace libcamera */
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index 6c3ef5377..f4403687a 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -43,6 +43,7 @@  libcamera_internal_sources = files([
     'media_device.cpp',
     'media_object.cpp',
     'pipeline_handler.cpp',
+    'pool.cpp',
     'process.cpp',
     'pub_key.cpp',
     'shared_mem_object.cpp',
diff --git a/src/libcamera/pool.cpp b/src/libcamera/pool.cpp
new file mode 100644
index 000000000..122b025d1
--- /dev/null
+++ b/src/libcamera/pool.cpp
@@ -0,0 +1,70 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2024, Google Inc.
+ *
+ * pool.cpp - Template class for generic pool
+ */
+
+/**
+ * \class libcamera::Pool
+ * \brief Pool that owns a list of objects
+ *
+ * A Pool that owns a list of objects, and allows users to request objects and
+ * recycle them. It's mostly used as a buffer pool, holding a list of buffers
+ * as std::unique_ptr.
+ */
+
+/**
+ * \fn Pool::setData(std::vector<UniquePtr> &pool)
+ * \brief Set and claim ownership of objects. Swap the previously owned objects
+ * not empty.
+ * \param[inout] pool The objects to be set and the swapped out ones
+ */
+
+/**
+ * \fn Pool::release()
+ * \brief Release the ownership of objects and reset states
+ */
+
+/**
+ * \fn Pool::content()
+ * \return The reference of objects
+ */
+
+/**
+ * \fn Pool::size()
+ * \brief The size of objects
+ */
+
+/**
+ * \fn Pool::get()
+ * \brief Get one object. Fatal if there's none available
+ *
+ * \return An available object
+ */
+
+/**
+ * \fn Pool::put(T data)
+ * \brief Recycle one object that was retrieved by get()
+ * \param[in] data The object to be recycled
+ */
+
+/**
+ * \class libcamera::BasicContainer
+ * \brief A container for basic types
+ *
+ * When using Pool with a basic type (e.g. `int`), it'd be easier to get an
+ * object by value instead of by pointer. BasicContainer makes it possible as a
+ * helper class.
+ */
+
+/**
+ * \fn BasicContainer::BasicContainer(T &value)
+ * \brief Create a BasicContainer with a value
+ * \param[in] value The value to be contained
+ */
+
+/**
+ * \fn BasicContainer::get()
+ * \return Return the object by value
+ */