diff options
-rw-r--r-- | src/libcamera/include/v4l2_videodevice.h | 7 | ||||
-rw-r--r-- | src/libcamera/v4l2_videodevice.cpp | 23 |
2 files changed, 20 insertions, 10 deletions
diff --git a/src/libcamera/include/v4l2_videodevice.h b/src/libcamera/include/v4l2_videodevice.h index 359b3664..04802012 100644 --- a/src/libcamera/include/v4l2_videodevice.h +++ b/src/libcamera/include/v4l2_videodevice.h @@ -7,11 +7,12 @@ #ifndef __LIBCAMERA_V4L2_VIDEODEVICE_H__ #define __LIBCAMERA_V4L2_VIDEODEVICE_H__ +#include <atomic> +#include <memory> #include <string> #include <vector> #include <linux/videodev2.h> -#include <memory> #include <libcamera/buffer.h> #include <libcamera/geometry.h> @@ -120,11 +121,12 @@ private: { public: Entry(); - Entry(bool free, const FrameBuffer &buffer); + Entry(bool free, uint64_t lastUsed, const FrameBuffer &buffer); bool operator==(const FrameBuffer &buffer) const; bool free; + uint64_t lastUsed; private: struct Plane { @@ -140,6 +142,7 @@ private: std::vector<Plane> planes_; }; + std::atomic_uint64_t lastUsedCounter_; std::vector<Entry> cache_; /* \todo Expose the miss counter through an instrumentation API. */ unsigned int missCounter_; diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index c495de85..ca0d147f 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -162,7 +162,7 @@ LOG_DECLARE_CATEGORY(V4L2) * buffer import, with buffers added to the cache as they are queued. */ V4L2BufferCache::V4L2BufferCache(unsigned int numEntries) - : missCounter_(0) + : lastUsedCounter_(1), missCounter_(0) { cache_.resize(numEntries); } @@ -176,10 +176,12 @@ V4L2BufferCache::V4L2BufferCache(unsigned int numEntries) * allocated. */ V4L2BufferCache::V4L2BufferCache(const std::vector<std::unique_ptr<FrameBuffer>> &buffers) - : missCounter_(0) + : lastUsedCounter_(1), missCounter_(0) { for (const std::unique_ptr<FrameBuffer> &buffer : buffers) - cache_.emplace_back(true, buffer->planes()); + cache_.emplace_back(true, + lastUsedCounter_.fetch_add(1, std::memory_order_acq_rel), + buffer->planes()); } V4L2BufferCache::~V4L2BufferCache() @@ -205,6 +207,7 @@ int V4L2BufferCache::get(const FrameBuffer &buffer) { bool hit = false; int use = -1; + uint64_t oldest = UINT64_MAX; for (unsigned int index = 0; index < cache_.size(); index++) { const Entry &entry = cache_[index]; @@ -219,8 +222,10 @@ int V4L2BufferCache::get(const FrameBuffer &buffer) break; } - if (use < 0) + if (entry.lastUsed < oldest) { use = index; + oldest = entry.lastUsed; + } } if (!hit) @@ -229,7 +234,9 @@ int V4L2BufferCache::get(const FrameBuffer &buffer) if (use < 0) return -ENOENT; - cache_[use] = Entry(false, buffer); + cache_[use] = Entry(false, + lastUsedCounter_.fetch_add(1, std::memory_order_acq_rel), + buffer); return use; } @@ -245,12 +252,12 @@ void V4L2BufferCache::put(unsigned int index) } V4L2BufferCache::Entry::Entry() - : free(true) + : free(true), lastUsed(0) { } -V4L2BufferCache::Entry::Entry(bool free, const FrameBuffer &buffer) - : free(free) +V4L2BufferCache::Entry::Entry(bool free, uint64_t lastUsed, const FrameBuffer &buffer) + : free(free), lastUsed(lastUsed) { for (const FrameBuffer::Plane &plane : buffer.planes()) planes_.emplace_back(plane); |