[libcamera-devel] [PATCH 07/10] libcamera: pipeline_handler: Split request queueing
Jacopo Mondi
jacopo at jmondi.org
Tue Nov 9 18:42:54 CET 2021
Hi Kieran
On Tue, Nov 09, 2021 at 02:39:31PM +0000, Kieran Bingham wrote:
> Quoting Jacopo Mondi (2021-10-28 12:15:17)
> > In order to prepare to handle synchronization fences at Request
> > queueing time, split the PipelineHandler::queueRequest() function in
> > two, by creating a list of waiting requests and introducing a new
> > doQueueDevice() function that queues Requests to the device in the
> > order the pipeline has received them.
> >
> > Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
> > ---
> > include/libcamera/internal/pipeline_handler.h | 7 ++++
> > src/libcamera/pipeline_handler.cpp | 35 +++++++++++++++++--
> > 2 files changed, 39 insertions(+), 3 deletions(-)
> >
> > diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h
> > index 41cba44d990f..afb7990ea21b 100644
> > --- a/include/libcamera/internal/pipeline_handler.h
> > +++ b/include/libcamera/internal/pipeline_handler.h
> > @@ -7,7 +7,9 @@
> > #ifndef __LIBCAMERA_INTERNAL_PIPELINE_HANDLER_H__
> > #define __LIBCAMERA_INTERNAL_PIPELINE_HANDLER_H__
> >
> > +#include <list>
> > #include <memory>
> > +#include <mutex>
> > #include <set>
> > #include <string>
> > #include <sys/types.h>
> > @@ -76,9 +78,14 @@ private:
> > void mediaDeviceDisconnected(MediaDevice *media);
> > virtual void disconnect();
> >
> > + void doQueueRequest();
> > +
> > std::vector<std::shared_ptr<MediaDevice>> mediaDevices_;
> > std::vector<std::weak_ptr<Camera>> cameras_;
> >
> > + std::mutex waitingRequestsMutex_;
> > + std::list<Request *> waitingRequests_;
> > +
> > const char *name_;
> >
> > friend class PipelineHandlerFactory;
> > diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp
> > index cada864687ff..38edd00cebad 100644
> > --- a/src/libcamera/pipeline_handler.cpp
> > +++ b/src/libcamera/pipeline_handler.cpp
> > @@ -10,6 +10,7 @@
> > #include <sys/sysmacros.h>
> >
> > #include <libcamera/base/log.h>
> > +#include <libcamera/base/thread.h>
> > #include <libcamera/base/utils.h>
> >
> > #include <libcamera/camera.h>
> > @@ -312,17 +313,45 @@ void PipelineHandler::queueRequest(Request *request)
> > {
> > LIBCAMERA_TRACEPOINT(request_queue, request);
>
> Should we add a new TRACEPOINT for when the request gets queued to the
> device now?
>
Dunno, this seems internal stuff, while I assumed tracepoints are
meant to track public API interactions ? Am I mistaken ?
> >
> > + {
> > + MutexLocker lock(waitingRequestsMutex_);
> > + waitingRequests_.push_back(request);
> > + }
> > +
> > + doQueueRequest();
> > +}
> > +
> > +/**
> > + * \brief Queue a request to the device
> > + */
> > +void PipelineHandler::doQueueRequest()
> > +{
> > + Request *request = nullptr;
> > + {
> > + MutexLocker lock(waitingRequestsMutex_);
> > +
> > + if (!waitingRequests_.size())
> > + return;
> > +
> > + request = waitingRequests_.front();
> > + waitingRequests_.pop_front();
> > + }
> > +
> > + /* Queue Request to the pipeline handler. */
> > Camera *camera = request->_d()->camera();
> > - Camera::Private *data = camera->_d();
> > - data->queuedRequests_.push_back(request);
> > + Camera::Private *camData = camera->_d();
>
> Is this rename data -> camData required? it would simplify the diff if
> it was done separately. Otherwise - perhaps mention in the
> commit-message.
It's probably a leftover, I'll keep using 'data'.
>
>
> >
> > - request->sequence_ = data->requestSequence_++;
> > + request->sequence_ = camData->requestSequence_++;
> > + camData->queuedRequests_.push_back(request);
> >
> > int ret = queueRequestDevice(camera, request);
>
> So we have a queue before we queue now... ;-)
>
> We probably need to update/create some new block diagrams for the
> Pipeline Handler documentation to show how the internal queuing works ...
>
> So I think this is now
> queueRequest(); // Add to the queue
> -> doQueueRequest(); // See if we're allowed to queue
> -> queueRequestDevice(); // Add to the kernel/hw queue ...
>
it's more like
queueRequest();
if (ready)
doQueueRequest()
queueRequestDevice()
else
waitOnFences()
if (fencesDone)
doQueueRequest()
queueRequestDevice()
> > if (ret) {
> > request->cancel();
> > completeRequest(request);
> > }
> > +
> > + /* Try to queue the next Request in the queue, if ready. */
> > + doQueueRequest();
>
> Hrm... I get a little scared/pessimistic when I see recursion. Is this
> better handled as a loop some how?
>
Why so ? It's one more level of indendation and I'm not sure what
benefits it would bring :)
>
> > }
> >
> > /**
> > --
> > 2.33.1
> >
More information about the libcamera-devel
mailing list