From patchwork Mon Nov 29 11:44:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hirokazu Honda X-Patchwork-Id: 14841 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 28F9FBF415 for ; Mon, 29 Nov 2021 11:45:15 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D912D605B9; Mon, 29 Nov 2021 12:45:14 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="EEsjJWLh"; dkim-atps=neutral Received: from mail-pf1-x42a.google.com (mail-pf1-x42a.google.com [IPv6:2607:f8b0:4864:20::42a]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4E5BB605B7 for ; Mon, 29 Nov 2021 12:45:10 +0100 (CET) Received: by mail-pf1-x42a.google.com with SMTP id g18so16575233pfk.5 for ; Mon, 29 Nov 2021 03:45:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=yMK8xuOKXl6FNLXZT5HALq7jJoQBO1uNuMrQ9ZfsbSQ=; b=EEsjJWLhNP4snEAM/q4j5YHpeo36W2zOFhBvnjzY4OjHy6/M1v04LlLahKTTsKiSo8 L7iFNn7CwZZ2/FIYmQ7S2mf2SZUfm+WnJiXIYNM8vWIcZUgKkf8xh93nqaD8ptfHSet9 4iLamDBe050ez+eOBm9yj/eesYcGZLI8Y7d0A= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=yMK8xuOKXl6FNLXZT5HALq7jJoQBO1uNuMrQ9ZfsbSQ=; b=OutM8FC1q1OIx8t29twuH/DXaOfT7TTPc81SjMiNf1IlNOGLjdfnGLStzESUPNUG9S R6Ek5uVA4nxjXMNvVrSZdHKeJlE/svUoil42P/uITkQi7eiHeeK4A6eIrFkK6TbYnb7S XgyRXtmiPnIYovfD9W/QEem+dvdA7+37fY3tdhLE6M9pfGf5u9vsWB1PxYxvp+tI0Xnk OzrexlziWoH8QB9wyvZRSiHlizEyuU8ORtW60rSbOnwVj2AziHD2t7pvoKMFZuPMGT4m WHFLPPUsHiNQVqhira6dgg49PMMM+EuF6oV3Hlr+gxZXeXl6yWnceiR21IkGKkEzuP8F vmJg== X-Gm-Message-State: AOAM532EFTSE5S1nLvC6119KoiZpua6rIyTzwFZQy5UMVSn9JCRGG00Y oRV4jpzqr4Geul9KmA6XGvIkgFwY9Ejt4A== X-Google-Smtp-Source: ABdhPJz5xsHrF7mK0qfQvEgD/lsXX/ne7Z8Gptgru8+satJ2OtF6yRUfEgoP+6CUEiWqODcI0v9vjA== X-Received: by 2002:aa7:88d3:0:b0:49f:baac:9b51 with SMTP id k19-20020aa788d3000000b0049fbaac9b51mr38946911pff.44.1638186308275; Mon, 29 Nov 2021 03:45:08 -0800 (PST) Received: from hiroh2.tok.corp.google.com ([2401:fa00:8f:203:f254:cda9:46e8:17b7]) by smtp.gmail.com with ESMTPSA id hg4sm17951966pjb.1.2021.11.29.03.45.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 29 Nov 2021 03:45:07 -0800 (PST) From: Hirokazu Honda To: libcamera-devel@lists.libcamera.org Date: Mon, 29 Nov 2021 20:44:47 +0900 Message-Id: <20211129114453.3186042-6-hiroh@chromium.org> X-Mailer: git-send-email 2.34.0.rc2.393.gf8c9666880-goog In-Reply-To: <20211129114453.3186042-1-hiroh@chromium.org> References: <20211129114453.3186042-1-hiroh@chromium.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 05/11] libcamera: base: Add mutex classes with thread safety annotations X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" This replaces Mutex and MutexLocker with our own defined classes. The classes are annotated by clang thread safety annotations. So we can add annotation to code where the classes are used. v4l2 code needs to be annotated, which violates Mutex capability. Signed-off-by: Hirokazu Honda --- include/libcamera/base/meson.build | 1 + include/libcamera/base/mutex.h | 127 +++++++++++++++++++++++++++++ include/libcamera/base/thread.h | 7 +- src/v4l2/v4l2_camera_proxy.h | 5 +- 4 files changed, 132 insertions(+), 8 deletions(-) create mode 100644 include/libcamera/base/mutex.h diff --git a/include/libcamera/base/meson.build b/include/libcamera/base/meson.build index 1a71ce5a..37c4435a 100644 --- a/include/libcamera/base/meson.build +++ b/include/libcamera/base/meson.build @@ -13,6 +13,7 @@ libcamera_base_headers = files([ 'flags.h', 'log.h', 'message.h', + 'mutex.h', 'object.h', 'private.h', 'semaphore.h', diff --git a/include/libcamera/base/mutex.h b/include/libcamera/base/mutex.h new file mode 100644 index 00000000..55091eb4 --- /dev/null +++ b/include/libcamera/base/mutex.h @@ -0,0 +1,127 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Google Inc. + * + * thread.h - Thread support + */ + +#pragma once + +#include +#include + +#include + +namespace libcamera { + +class ConditionVariable; +class LIBCAMERA_TSA_SCOPED_CAPABILITY MutexLocker; + +/* \todo using Mutex = std::mutex if lib++ is used. */ +class LIBCAMERA_TSA_CAPABILITY("mutex") Mutex final +{ +public: + constexpr Mutex() + { + } + + void lock() LIBCAMERA_TSA_ACQUIRE() + { + mutex_.lock(); + } + + void unlock() LIBCAMERA_TSA_RELEASE() + { + mutex_.unlock(); + } + +private: + friend MutexLocker; + + std::mutex mutex_; +}; + +class LIBCAMERA_TSA_SCOPED_CAPABILITY MutexLocker final +{ +public: + explicit MutexLocker(Mutex &mutex) LIBCAMERA_TSA_ACQUIRE(mutex) + : lock_(mutex.mutex_) + { + } + + MutexLocker(Mutex &mutex, std::defer_lock_t t) noexcept LIBCAMERA_TSA_ACQUIRE(mutex) + : lock_(mutex.mutex_, t) + { + } + + MutexLocker(Mutex &mutex, std::try_to_lock_t t) noexcept LIBCAMERA_TSA_ACQUIRE(mutex) + : lock_(mutex.mutex_, t) + { + } + + MutexLocker(Mutex &mutex, std::adopt_lock_t t) noexcept LIBCAMERA_TSA_ACQUIRE(mutex) + : lock_(mutex.mutex_, t) + { + } + + ~MutexLocker() LIBCAMERA_TSA_RELEASE() + { + } + + void lock() LIBCAMERA_TSA_ACQUIRE() + { + lock_.lock(); + } + + void unlock() LIBCAMERA_TSA_RELEASE() + { + lock_.unlock(); + } + + bool try_lock() LIBCAMERA_TSA_TRY_ACQUIRE(true) + { + return lock_.try_lock(); + } + +private: + friend ConditionVariable; + + std::unique_lock lock_; +}; + +class ConditionVariable final +{ +public: + ConditionVariable() + { + } + + void notify_one() noexcept + { + cv_.notify_one(); + } + + void notify_all() noexcept + { + cv_.notify_all(); + } + + template + void wait(MutexLocker &locker, Predicate stopWaiting) + { + cv_.wait(locker.lock_, stopWaiting); + } + + template + bool wait_for(MutexLocker &locker, + const std::chrono::duration &relTime, + Predicate stopWaiting) + { + return cv_.wait_for(locker.lock_, relTime, stopWaiting); + } + +private: + std::condition_variable cv_; +}; + +} /* namespace libcamera */ diff --git a/include/libcamera/base/thread.h b/include/libcamera/base/thread.h index 1ebf8363..44678c34 100644 --- a/include/libcamera/base/thread.h +++ b/include/libcamera/base/thread.h @@ -7,15 +7,14 @@ #pragma once -#include #include -#include #include #include #include #include +#include #include #include @@ -27,10 +26,6 @@ class Object; class ThreadData; class ThreadMain; -using ConditionVariable = std::condition_variable; -using Mutex = std::mutex; -using MutexLocker = std::unique_lock; - class Thread { public: diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h index 040954dd..23be995d 100644 --- a/src/v4l2/v4l2_camera_proxy.h +++ b/src/v4l2/v4l2_camera_proxy.h @@ -14,7 +14,8 @@ #include #include -#include +#include +#include #include @@ -59,7 +60,7 @@ private: int vidioc_querybuf(V4L2CameraFile *file, struct v4l2_buffer *arg); int vidioc_qbuf(V4L2CameraFile *file, struct v4l2_buffer *arg); int vidioc_dqbuf(V4L2CameraFile *file, struct v4l2_buffer *arg, - libcamera::Mutex *lock); + libcamera::Mutex *lock) LIBCAMERA_TSA_REQUIRES(*lock); int vidioc_streamon(V4L2CameraFile *file, int *arg); int vidioc_streamoff(V4L2CameraFile *file, int *arg);