[libcamera-devel] [PATCH v2 08/12] gstreamer: Use dedicated lock for request queues

Umang Jain umang.jain at ideasonboard.com
Thu Jun 30 10:34:54 CEST 2022


Hi Laurent,

Thank you for the patch,

On 6/30/22 05:32, Laurent Pinchart via libcamera-devel wrote:
> Add a new lock to the GstLibcameraSrcState class to protect the queued
> and completed requests queues. This replaces the GstObject lock, and
> minimizes the lock contention between the request completion handler and
> the task run handler as the former must run as fast as possible.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> Reviewed-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>


Reviewed-by: Umang Jain <umang.jain at ideasonboard.com>

> ---
> Changes since v1:
>
> - Add comment about lock_
> ---
>   src/gstreamer/gstlibcamerasrc.cpp | 44 +++++++++++++++++++++++--------
>   1 file changed, 33 insertions(+), 11 deletions(-)
>
> diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp
> index 8c1cd7017d98..6f9a03c515d2 100644
> --- a/src/gstreamer/gstlibcamerasrc.cpp
> +++ b/src/gstreamer/gstlibcamerasrc.cpp
> @@ -32,6 +32,8 @@
>   #include <queue>
>   #include <vector>
>   
> +#include <libcamera/base/mutex.h>
> +
>   #include <libcamera/camera.h>
>   #include <libcamera/camera_manager.h>
>   #include <libcamera/control_ids.h>
> @@ -111,8 +113,18 @@ struct GstLibcameraSrcState {
>   	std::shared_ptr<Camera> cam_;
>   	std::unique_ptr<CameraConfiguration> config_;
>   	std::vector<GstPad *> srcpads_;
> -	std::queue<std::unique_ptr<RequestWrap>> queuedRequests_;
> -	std::queue<std::unique_ptr<RequestWrap>> completedRequests_;
> +
> +	/*
> +	 * Contention on this lock_ must be minimized, as it has to be taken in
> +	 * the realtime-sensitive requestCompleted() handler to protect
> +	 * queuedRequests_ and completedRequests_.
> +	 */
> +	Mutex lock_;
> +	std::queue<std::unique_ptr<RequestWrap>> queuedRequests_
> +		LIBCAMERA_TSA_GUARDED_BY(lock_);
> +	std::queue<std::unique_ptr<RequestWrap>> completedRequests_
> +		LIBCAMERA_TSA_GUARDED_BY(lock_);
> +
>   	guint group_id_;
>   
>   	void requestCompleted(Request *request);
> @@ -155,12 +167,15 @@ GstStaticPadTemplate request_src_template = {
>   void
>   GstLibcameraSrcState::requestCompleted(Request *request)
>   {
> -	GLibLocker lock(GST_OBJECT(src_));
> -
>   	GST_DEBUG_OBJECT(src_, "buffers are ready");
>   
> -	std::unique_ptr<RequestWrap> wrap = std::move(queuedRequests_.front());
> -	queuedRequests_.pop();
> +	std::unique_ptr<RequestWrap> wrap;
> +
> +	{
> +		MutexLocker locker(lock_);
> +		wrap = std::move(queuedRequests_.front());
> +		queuedRequests_.pop();
> +	}
>   
>   	g_return_if_fail(wrap->request_.get() == request);
>   
> @@ -183,7 +198,10 @@ GstLibcameraSrcState::requestCompleted(Request *request)
>   		wrap->latency_ = sys_now - timestamp;
>   	}
>   
> -	completedRequests_.push(std::move(wrap));
> +	{
> +		MutexLocker locker(lock_);
> +		completedRequests_.push(std::move(wrap));
> +	}
>   
>   	gst_task_resume(src_->task);
>   }
> @@ -289,16 +307,17 @@ gst_libcamera_src_task_run(gpointer user_data)
>   	}
>   
>   	if (wrap) {
> -		GLibLocker lock(GST_OBJECT(self));
>   		GST_TRACE_OBJECT(self, "Requesting buffers");
>   		state->cam_->queueRequest(wrap->request_.get());
> +
> +		MutexLocker locker(state->lock_);
>   		state->queuedRequests_.push(std::move(wrap));
>   
>   		/* The RequestWrap will be deleted in the completion handler. */
>   	}
>   
>   	{
> -		GLibLocker lock(GST_OBJECT(self));
> +		MutexLocker locker(state->lock_);
>   
>   		if (!state->completedRequests_.empty()) {
>   			wrap = std::move(state->completedRequests_.front());
> @@ -358,7 +377,7 @@ gst_libcamera_src_task_run(gpointer user_data)
>   		bool do_pause;
>   
>   		{
> -			GLibLocker lock(GST_OBJECT(self));
> +			MutexLocker locker(state->lock_);
>   			do_pause = state->completedRequests_.empty();
>   		}
>   
> @@ -513,7 +532,10 @@ gst_libcamera_src_task_leave([[maybe_unused]] GstTask *task,
>   
>   	state->cam_->stop();
>   
> -	state->completedRequests_ = {};
> +	{
> +		MutexLocker locker(state->lock_);
> +		state->completedRequests_ = {};
> +	}
>   
>   	for (GstPad *srcpad : state->srcpads_)
>   		gst_libcamera_pad_set_pool(srcpad, nullptr);


More information about the libcamera-devel mailing list