From 12241d3b3be9ef911600194255904fbffeadc377 Mon Sep 17 00:00:00 2001 From: Umang Jain Date: Mon, 10 May 2021 22:52:47 +0530 Subject: stats: Import SharedItemPool for stats' grid buffers Import the SharedItemPool implementation to managed grid buffers. Signed-off-by: Umang Jain --- meson.build | 1 + stats/meson.build | 6 +++ stats/shared_item_pool.cpp | 129 +++++++++++++++++++++++++++++++++++++++++++++ stats/shared_item_pool.h | 114 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 250 insertions(+) create mode 100644 stats/meson.build create mode 100644 stats/shared_item_pool.cpp create mode 100644 stats/shared_item_pool.h diff --git a/meson.build b/meson.build index ae51789..5516434 100644 --- a/meson.build +++ b/meson.build @@ -95,6 +95,7 @@ ipu3_ipa_deps = [ subdir('aiq') subdir('data') subdir('src') +subdir('stats') mod = shared_module(ipa_name, [ipu3_ipa_files, libcamera_helpers], diff --git a/stats/meson.build b/stats/meson.build new file mode 100644 index 0000000..9707630 --- /dev/null +++ b/stats/meson.build @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: CC0-1.0 + +ipu3_ipa_files += files([ + 'shared_item_pool.cpp', +]) + diff --git a/stats/shared_item_pool.cpp b/stats/shared_item_pool.cpp new file mode 100644 index 0000000..326a400 --- /dev/null +++ b/stats/shared_item_pool.cpp @@ -0,0 +1,129 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright (C) 2014-2018 Intel Corporation + * + * This implementation is highly derived from ChromeOS: + * platform2/camera/hal/intel/ipu3/common/SharedItemPool.cpp + */ + +#include + +#include + +#include "shared_item_pool.h" + +namespace libcamera { + +LOG_DEFINE_CATEGORY(SharedItemPool) + +template +SharedItemPool::SharedItemPool(const char *name) + : allocated_(nullptr), capacity_(0), deleter_(this), poolName_(name), + resetter_(nullptr) +{ +} + +template +SharedItemPool::~SharedItemPool() +{ + deInit(); +} + +template +int SharedItemPool::init(int32_t capacity, void (*resetter)(ItemType *)) +{ + if (capacity_ != 0) { + LOG(SharedItemPool, Error) << "Pool initialized already"; + return -ENOSYS; + } + std::lock_guard l(mutex_); + resetter_ = resetter; + capacity_ = capacity; + available_.reserve(capacity); + allocated_ = new ItemType[capacity]; + + for (int32_t i = 0; i < capacity; i++) + available_.push_back(&allocated_[i]); + + LOG(SharedItemPool, Debug) << "Shared pool " << poolName_ << "init with " << capacity << " items"; + + return 0; +} + +template +bool SharedItemPool::isFull() +{ + std::lock_guard l(mutex_); + bool ret = (available_.size() == capacity_); + return ret; +} + +template +int SharedItemPool::deInit() +{ + std::lock_guard l(mutex_); + if (capacity_ == 0) { + LOG(SharedItemPool, Debug) << "Shared pool " << poolName_ + << " isn't initialized or already de-initialized"; + return 0; + } + if (available_.size() != capacity_) { + LOG(SharedItemPool, Error) << "Not all items are returned " + << "when destroying pool " << poolName_ + << "(" << available_.size() << "/" << capacity_ << ")"; + } + + delete[] allocated_; + allocated_ = nullptr; + available_.clear(); + capacity_ = 0; + LOG(SharedItemPool, Debug) << "Shared pool " << poolName_ + << " deinit done"; + + return 0; +} + +template +int SharedItemPool::acquireItem(std::shared_ptr &item) +{ + item.reset(); + std::lock_guard l(mutex_); + if (available_.empty()) { + LOG(SharedItemPool, Error) << "Shared pool " << poolName_ + << "is empty"; + return -ENOSYS; + } + + std::shared_ptr sh(available_[0], deleter_); + available_.erase(available_.begin()); + item = sh; + LOG(SharedItemPool, Debug) << "Shared pool " << poolName_ + << "acquire items " << sh.get(); + return 0; +} + +template +size_t SharedItemPool::availableItems() +{ + std::lock_guard l(mutex_); + size_t ret = available_.size(); + return ret; +} + +template +int SharedItemPool::_releaseItem(ItemType *item) +{ + std::lock_guard l(mutex_); + if (resetter_) + resetter_(item); + + LOG(SharedItemPool, Debug) << "Shared pool " << poolName_ + << "returning item " << item; + + available_.push_back(item); + return 0; +} + +template class SharedItemPool; +template class SharedItemPool; +} /* namespace libcamera */ diff --git a/stats/shared_item_pool.h b/stats/shared_item_pool.h new file mode 100644 index 0000000..89dc9b3 --- /dev/null +++ b/stats/shared_item_pool.h @@ -0,0 +1,114 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright (C) 2014-2018 Intel Corporation + * + * This implementation is highly derived from ChromeOS: + * platform2/camera/hal/intel/ipu3/common/SharedItemPool.h + */ + +#ifndef SHARED_ITEM_POOL_H +#define SHARED_ITEM_POOL_H + +#include +#include +#include +#include + +/** + * \class SharedItemPool + * + * Pool of ref counted items. This class creates a pool of items and manages + * the acquisition of them. When all references to this item have disappeared + * The item is returned to the pool. + * + * This class is thread safe, i.e. it can be called from multiple threads. + * When the element is recycled to the pool it can be reset via a client + * provided method. + * + */ + +namespace libcamera { + +template +class SharedItemPool +{ +public: + SharedItemPool(const char *name = "Unnamed"); + ~SharedItemPool(); + + /** + * Initializes the capacity of the pool. It allocates the objects. + * optionally it will take function to reset the item before recycling + * it to the pool. + * This method is thread safe. + * + * \param capacity[IN]: Number of items the pool will hold + * \param resetter[IN]: Function to reset the item before recycling to the + * pool. + * \return -ENOSYS if trying to initialize twice + * \return 0 If everything went ok. + */ + int init(int32_t capacity, void (*resetter)(ItemType *) = nullptr); + + bool isFull(); + + /** + * Free the resources of the pool + * + * \return 0 on success + */ + int deInit(); + + /** + * Acquire an item from the pool. + * This method is thread safe. Access to the internal acquire/release + * methods are protected. + * BUT the thread-safety for the utilization of the item after it has been + * acquired is the user's responsibility. + * Be careful not to provide the same item to multiple threads that write + * into it. + * + * \param item[OUT] shared pointer to an item. + * \return 0 on success + */ + int acquireItem(std::shared_ptr &item); + + /** + * Returns the number of currently available items + * It there would be issues acquiring the lock the method returns 0 + * available items. + * + * \return item count + */ + size_t availableItems(); + +private: + int _releaseItem(ItemType *item); + + class ItemDeleter + { + public: + ItemDeleter(SharedItemPool *pool) + : mPool(pool) {} + void operator()(ItemType *item) const + { + mPool->_releaseItem(item); + } + + private: + SharedItemPool *mPool; + }; + + std::vector available_; /* SharedItemPool doesn't have ownership */ + ItemType *allocated_; + size_t capacity_; + ItemDeleter deleter_; + std::mutex mutex_; /* protects available_, allocated_, capacity_ */ + const char *poolName_; + void (*resetter_)(ItemType *); +}; + +} /* namespace libcamera */ + +#endif /* SHARED_ITEM_POOL_H */ + -- cgit v1.2.1