From patchwork Thu Jan 30 19:58:20 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22710 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 2AC0CBD808 for ; Thu, 30 Jan 2025 19:58:27 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E22E76856A; Thu, 30 Jan 2025 20:58:26 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="yP+zyg4A"; dkim-atps=neutral Received: from mail-4322.protonmail.ch (mail-4322.protonmail.ch [185.70.43.22]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4775A6851B for ; Thu, 30 Jan 2025 20:58:25 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1738267104; x=1738526304; bh=Phu7SN3abKjZBHbL7ofD5wQ30GlV8Co9upy+TiCllhg=; h=Date:To:From:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=yP+zyg4AUSChpmXkwazJ3NgqpTurmF1AgyH5wU70K2xQlkfcv3N5vir7XaA4Eke3i XpJggL0F5susn7feNsQHAeV0OiR13BSovvZXcn/qPkmXGr8JuKZJ5Di0MWU8rCKchp B8FkungKyG+L0w+rhRPNFIlKs82/gsE9hFM3sEsyfgdH8GO8IxKKXYH5wasouoEaDL a2ahCjnnA0UQCHh8+5gXlIWAySeEgoNOCNWht4++j9uwZnWwpdv1m5s/o7fTYfrgsQ FREfNfbQQ4brut9kapoIp7LCrGC9TN03cr/JF+8M30iDfXQCdxMeCgFbf3eKyoRtps dh7fCinT3KSug== Date: Thu, 30 Jan 2025 19:58:20 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Subject: [RFC PATCH v2 1/9] libcamera: base: log: Remove move constructor Message-ID: <20250130195811.1230581-2-pobrn@protonmail.com> In-Reply-To: <20250130195811.1230581-1-pobrn@protonmail.com> References: <20250130195811.1230581-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: 6f232791b5610ed0a95bc20c539d33a8e5f12867 MIME-Version: 1.0 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" C++17 guarantees move and copy elision in certain cases, such as when returning a prvalue of the same type as the return type of the function. This is what the `_log()` functions do, thus there is no need for the move constructor, so remove it. Furthermore, do not just remove the implementation, but instead delete it as well. Signed-off-by: Barnabás Pőcze Reviewed-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- include/libcamera/base/log.h | 4 +--- src/libcamera/base/log.cpp | 19 ------------------- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/include/libcamera/base/log.h b/include/libcamera/base/log.h index 620930125..b3050eedb 100644 --- a/include/libcamera/base/log.h +++ b/include/libcamera/base/log.h @@ -61,8 +61,6 @@ public: LogMessage(const char *fileName, unsigned int line, const LogCategory &category, LogSeverity severity, const std::string &prefix = std::string()); - - LogMessage(LogMessage &&); ~LogMessage(); std::ostream &stream() { return msgStream_; } @@ -75,7 +73,7 @@ public: const std::string msg() const { return msgStream_.str(); } private: - LIBCAMERA_DISABLE_COPY(LogMessage) + LIBCAMERA_DISABLE_COPY_AND_MOVE(LogMessage) void init(const char *fileName, unsigned int line); diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp index 3a656b8f0..1917c3254 100644 --- a/src/libcamera/base/log.cpp +++ b/src/libcamera/base/log.cpp @@ -880,25 +880,6 @@ LogMessage::LogMessage(const char *fileName, unsigned int line, init(fileName, line); } -/** - * \brief Move-construct a log message - * \param[in] other The other message - * - * The move constructor is meant to support the _log() functions. Thanks to copy - * elision it will likely never be called, but C++11 only permits copy elision, - * it doesn't enforce it unlike C++17. To avoid potential link errors depending - * on the compiler type and version, and optimization level, the move - * constructor is defined even if it will likely never be called, and ensures - * that the destructor of the \a other message will not output anything to the - * log by setting the severity to LogInvalid. - */ -LogMessage::LogMessage(LogMessage &&other) - : msgStream_(std::move(other.msgStream_)), category_(other.category_), - severity_(other.severity_) -{ - other.severity_ = LogInvalid; -} - void LogMessage::init(const char *fileName, unsigned int line) { /* Log the timestamp, severity and file information. */ From patchwork Thu Jan 30 19:58:25 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22711 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 7CBCFBD808 for ; Thu, 30 Jan 2025 19:58:31 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3AEE468559; Thu, 30 Jan 2025 20:58:31 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="isG4+t0C"; dkim-atps=neutral Received: from mail-40131.protonmail.ch (mail-40131.protonmail.ch [185.70.40.131]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3A3D56851B for ; Thu, 30 Jan 2025 20:58:29 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1738267108; x=1738526308; bh=Yvna53yt/HQw1uHbYeWGvCuXgx4bhd5mjGikNp4XWSo=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=isG4+t0CAWWtokWTrGVuor1s74eNU3lkVtXWm5AGA3G+0f3Av1NvZ+9xCLA6zgW7Y hecIuEBo5eEtnVGZhesValIBH6lpLBAJRCvXAOqVyrLpMRWLbH47FwM5Eh2a/r4+PF wlg4OP3Gww557dm0W+tUraIbBtCN+/VElNBpmHTv2pLZ/K+dHEN1bAefDKKzb0fj0e vX55OVLoeTZ7NTihEbD8HdfXiXivrBA+xKntIxGDUrRor975K77wLRGwB6sHr0m1lm sfhxikhYji91W/7H3d02aBHn9H6QWVfmLYuRE6KlgPil+6hR0w+yJ3GZJa1gWvCXdD zQYjjU57XMLug== Date: Thu, 30 Jan 2025 19:58:25 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Cc: Laurent Pinchart Subject: [RFC PATCH v2 2/9] libcamera: base: log: Use `std::from_chars()` Message-ID: <20250130195811.1230581-3-pobrn@protonmail.com> In-Reply-To: <20250130195811.1230581-1-pobrn@protonmail.com> References: <20250130195811.1230581-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: c221c145c7abd54da2e19574ba62b6cc8b2780d4 MIME-Version: 1.0 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" Use the `std::from_chars()` function from `` to parse the integral log level instead of `strtoul` as it provides an easier to use interface and better type safety. Signed-off-by: Barnabás Pőcze Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- src/libcamera/base/log.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp index 1917c3254..31053aee1 100644 --- a/src/libcamera/base/log.cpp +++ b/src/libcamera/base/log.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -685,12 +686,11 @@ LogSeverity Logger::parseLogLevel(const std::string &level) "FATAL", }; - int severity; + unsigned int severity; if (std::isdigit(level[0])) { - char *endptr; - severity = strtoul(level.c_str(), &endptr, 10); - if (*endptr != '\0' || severity > LogFatal) + auto [end, ec] = std::from_chars(level.data(), level.data() + level.size(), severity); + if (ec != std::errc() || *end != '\0' || severity > LogFatal) severity = LogInvalid; } else { severity = LogInvalid; From patchwork Thu Jan 30 19:58:29 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22712 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 54D6EBD808 for ; Thu, 30 Jan 2025 19:58:36 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 052466856F; Thu, 30 Jan 2025 20:58:36 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="m5pQN/lb"; dkim-atps=neutral Received: from mail-10631.protonmail.ch (mail-10631.protonmail.ch [79.135.106.31]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CADF86851B for ; Thu, 30 Jan 2025 20:58:34 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1738267113; x=1738526313; bh=oTBK7RJ1NZawKYjOPU9CPCk4DQ19ntVzH0LoVi2ujRc=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=m5pQN/lbczLqul8GlwoGI6NRIRSkomiOFxsmfzJFJYFgMD+grz8byUQ149nHRkmRS ef/IxhPpBxXLwa48d+wP/j02yExwJuX6ghzmCzwfHimDEST8rnMx9gYka/k1rfwSTV MbQLWYwMdAgMwcEpm3xSGiqI94gHpflar1gYcSLRMYrH4RONlxWpxv5SpBRp8jONwO dTATfHem0p37YbZdMbLyKNErbZd5llgyeswPkQYXBVe6a5+mGyyDQNsv3QgkkSUSDl NoxChqkCnELHwiVLUf7PyFAd32JE3nHbioCjrMSHe68JGVyG3+p0Cia2OYMx7eCXzK eDTnQ8nDvS97w== Date: Thu, 30 Jan 2025 19:58:29 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Cc: Laurent Pinchart Subject: [RFC PATCH v2 3/9] libcamera: base: log: Remove `LogMessage::init()` Message-ID: <20250130195811.1230581-4-pobrn@protonmail.com> In-Reply-To: <20250130195811.1230581-1-pobrn@protonmail.com> References: <20250130195811.1230581-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: d10034f6c9556a43ba3149076683d15dd6c345b6 MIME-Version: 1.0 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" It is a short function that can be merged into the constructor with essentially no change in observable behaviour, so do that. Signed-off-by: Barnabás Pőcze Reviewed-by: Laurent Pinchart --- include/libcamera/base/log.h | 2 -- src/libcamera/base/log.cpp | 13 +++---------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/include/libcamera/base/log.h b/include/libcamera/base/log.h index b3050eedb..6d2c93019 100644 --- a/include/libcamera/base/log.h +++ b/include/libcamera/base/log.h @@ -75,8 +75,6 @@ public: private: LIBCAMERA_DISABLE_COPY_AND_MOVE(LogMessage) - void init(const char *fileName, unsigned int line); - std::ostringstream msgStream_; const LogCategory &category_; LogSeverity severity_; diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp index 31053aee1..51a5cd470 100644 --- a/src/libcamera/base/log.cpp +++ b/src/libcamera/base/log.cpp @@ -875,19 +875,12 @@ const LogCategory &LogCategory::defaultCategory() LogMessage::LogMessage(const char *fileName, unsigned int line, const LogCategory &category, LogSeverity severity, const std::string &prefix) - : category_(category), severity_(severity), prefix_(prefix) + : category_(category), severity_(severity), + timestamp_(utils::clock::now()), prefix_(prefix) { - init(fileName, line); -} - -void LogMessage::init(const char *fileName, unsigned int line) -{ - /* Log the timestamp, severity and file information. */ - timestamp_ = utils::clock::now(); - std::ostringstream ossFileInfo; ossFileInfo << utils::basename(fileName) << ":" << line; - fileInfo_ = ossFileInfo.str(); + fileInfo_ = std::move(ossFileInfo).str(); } LogMessage::~LogMessage() From patchwork Thu Jan 30 19:58:34 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22713 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 58756BD808 for ; Thu, 30 Jan 2025 19:58:42 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 137D06856F; Thu, 30 Jan 2025 20:58:42 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="BgVsQQ2q"; dkim-atps=neutral Received: from mail-10629.protonmail.ch (mail-10629.protonmail.ch [79.135.106.29]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 03F166851B for ; Thu, 30 Jan 2025 20:58:41 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1738267120; x=1738526320; bh=ogl2WScHcyFWH3L1pUmaSWWgssplSkNDwDid+6wzrdc=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=BgVsQQ2q/orX/7W1Gkby3a7yPPIcQcrEFXlNrVJ+xTRDgapzKT9Jtbk8hjX07rG6u 67g0XFNNCumbUB/E0KG4r7Sl3MMuB0nRfBlaoeMC1qSnr7InSSMfq2y1ZWsiQWakO+ EP0/ErfvDI31vqfUyacyWXD1Bm20fJOwrxKsxC+T9ZmqD3MSmOFvO++zNOL4Tw+tR/ 54MOOM0e/aDo8I/HiLqEdlLIO949s025PZvermAPBoDV6OjGXFjuHCzDdfCtoGTWyn 7j3UdY3F3K72pJwifk8InPi+ABaylmLtZ6KTDNGpiBLriv557uEgdXek+ykeVed2N4 2qLdhzD7ldTZg== Date: Thu, 30 Jan 2025 19:58:34 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Cc: Laurent Pinchart Subject: [RFC PATCH v2 4/9] libcamera: base: log: Make `LogCategory::severity_` atomic Message-ID: <20250130195811.1230581-5-pobrn@protonmail.com> In-Reply-To: <20250130195811.1230581-1-pobrn@protonmail.com> References: <20250130195811.1230581-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: 28b4c3e62c3505b2fd92e5c51468b1bafcc919bd MIME-Version: 1.0 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" The severity of a log category may be changed from a different thread, so it is important to ensure that the reads and writes happen atomically. Using `std::memory_order_relaxed` should not introduce any synchronization overhead, it should only guarantee that the operation itself is atomic. Secondly, inline `LogCategory::setSeverity()`, as it is merely an assignment, so going through a DSO call is a big pessimization. `LogCategory` is not part of the public API, so this change has no external effects. Thirdly, assert that the atomic variable is lock free so as to ensure it won't silently fall back to libatomic (or similar) on any platform. If this assertion fails, this needs to be revisited. Signed-off-by: Barnabás Pőcze Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- include/libcamera/base/log.h | 9 ++++++--- src/libcamera/base/log.cpp | 5 +---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/libcamera/base/log.h b/include/libcamera/base/log.h index 6d2c93019..4137d87a4 100644 --- a/include/libcamera/base/log.h +++ b/include/libcamera/base/log.h @@ -7,6 +7,7 @@ #pragma once +#include #include #include @@ -31,8 +32,8 @@ public: static LogCategory *create(const char *name); const std::string &name() const { return name_; } - LogSeverity severity() const { return severity_; } - void setSeverity(LogSeverity severity); + LogSeverity severity() const { return severity_.load(std::memory_order_relaxed); } + void setSeverity(LogSeverity severity) { severity_.store(severity, std::memory_order_relaxed); } static const LogCategory &defaultCategory(); @@ -40,7 +41,9 @@ private: explicit LogCategory(const char *name); const std::string name_; - LogSeverity severity_; + + std::atomic severity_; + static_assert(decltype(severity_)::is_always_lock_free); }; #define LOG_DECLARE_CATEGORY(name) \ diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp index 51a5cd470..2abbad478 100644 --- a/src/libcamera/base/log.cpp +++ b/src/libcamera/base/log.cpp @@ -824,15 +824,12 @@ LogCategory::LogCategory(const char *name) */ /** + * \fn LogCategory::setSeverity(LogSeverity severity) * \brief Set the severity of the log category * * Messages of severity higher than or equal to the severity of the log category * are printed, other messages are discarded. */ -void LogCategory::setSeverity(LogSeverity severity) -{ - severity_ = severity; -} /** * \brief Retrieve the default log category From patchwork Thu Jan 30 19:58:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22714 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 60389BD808 for ; Thu, 30 Jan 2025 19:58:48 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1BD7068572; Thu, 30 Jan 2025 20:58:48 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="wN8PeKGr"; dkim-atps=neutral Received: from mail-4322.protonmail.ch (mail-4322.protonmail.ch [185.70.43.22]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 560AC6851B for ; Thu, 30 Jan 2025 20:58:46 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1738267125; x=1738526325; bh=lUpm/1QNowLSz3JziR4VCi/4wAJywYeIWioU9X+eg+0=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=wN8PeKGrqrcWIIwo7iJ+iHPapxyA3S5Kafz1DLQiNk05I5eKCwiRzR3SfK9pkvAda sVvdDzCdofmnyA6lKI4m+6xC7EBeFiLiGvUdotmgd+xozyUqhCWwUcOCoaHlbzQR3p Wl5uZDjmetIcup9xqHHWxLm2efyXC3OxDUaKmu9QjhW1UzZXm4DS5/LQuH1QKEFG9Y II476hchEbHvp2sfIYtHqu6ymTs0u8z8f65Lx/yc4+0Cf8/O0lpMJIkAuItRxtjy3T BNcrMVg5JEAMrH531pPbxWD6uP6xRbnjUU83gdZVk9fsnMtbVDK6z449vRehSrGQkd XAzCF105D1BGw== Date: Thu, 30 Jan 2025 19:58:41 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Cc: Laurent Pinchart Subject: [RFC PATCH v2 5/9] libcamera: base: log: Use `std::string_view` to avoid some copies Message-ID: <20250130195811.1230581-6-pobrn@protonmail.com> In-Reply-To: <20250130195811.1230581-1-pobrn@protonmail.com> References: <20250130195811.1230581-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: e3bf1bcbf4e43f9c453191ef29587c44cb99a65e MIME-Version: 1.0 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" Use `std::string_view` to avoid some largely unnecessary copies, and to make string comparisong potentially faster by eliminating repeated `strlen()` calls. Signed-off-by: Barnabás Pőcze Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- include/libcamera/base/log.h | 5 +++-- src/libcamera/base/log.cpp | 25 +++++++++++++------------ 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/include/libcamera/base/log.h b/include/libcamera/base/log.h index 4137d87a4..acef24203 100644 --- a/include/libcamera/base/log.h +++ b/include/libcamera/base/log.h @@ -9,6 +9,7 @@ #include #include +#include #include @@ -29,7 +30,7 @@ enum LogSeverity { class LogCategory { public: - static LogCategory *create(const char *name); + static LogCategory *create(std::string_view name); const std::string &name() const { return name_; } LogSeverity severity() const { return severity_.load(std::memory_order_relaxed); } @@ -38,7 +39,7 @@ public: static const LogCategory &defaultCategory(); private: - explicit LogCategory(const char *name); + explicit LogCategory(std::string_view name); const std::string name_; diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp index 2abbad478..9415b6937 100644 --- a/src/libcamera/base/log.cpp +++ b/src/libcamera/base/log.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -312,11 +313,11 @@ private: void parseLogFile(); void parseLogLevels(); - static LogSeverity parseLogLevel(const std::string &level); + static LogSeverity parseLogLevel(std::string_view level); friend LogCategory; void registerCategory(LogCategory *category); - LogCategory *findCategory(const char *name) const; + LogCategory *findCategory(std::string_view name) const; static bool destroyed_; @@ -641,17 +642,17 @@ void Logger::parseLogLevels() if (!len) continue; - std::string category; - std::string level; + std::string_view category; + std::string_view level; const char *colon = static_cast(memchr(pair, ':', len)); if (!colon) { /* 'x' is a shortcut for '*:x'. */ category = "*"; - level = std::string(pair, len); + level = std::string_view(pair, len); } else { - category = std::string(pair, colon - pair); - level = std::string(colon + 1, comma - colon - 1); + category = std::string_view(pair, colon - pair); + level = std::string_view(colon + 1, comma - colon - 1); } /* Both the category and the level must be specified. */ @@ -662,7 +663,7 @@ void Logger::parseLogLevels() if (severity == LogInvalid) continue; - levels_.push_back({ category, severity }); + levels_.emplace_back(category, severity); } } @@ -676,7 +677,7 @@ void Logger::parseLogLevels() * * \return The log severity, or LogInvalid if the string is invalid */ -LogSeverity Logger::parseLogLevel(const std::string &level) +LogSeverity Logger::parseLogLevel(std::string_view level) { static const char *const names[] = { "DEBUG", @@ -743,7 +744,7 @@ void Logger::registerCategory(LogCategory *category) * \param[in] name Name of the log category * \return The pointer to the found log category or nullptr if not found */ -LogCategory *Logger::findCategory(const char *name) const +LogCategory *Logger::findCategory(std::string_view name) const { if (auto it = std::find_if(categories_.begin(), categories_.end(), [name](auto c) { return c->name() == name; }); @@ -787,7 +788,7 @@ LogCategory *Logger::findCategory(const char *name) const * * \return The pointer to the LogCategory */ -LogCategory *LogCategory::create(const char *name) +LogCategory *LogCategory::create(std::string_view name) { static Mutex mutex_; MutexLocker locker(mutex_); @@ -805,7 +806,7 @@ LogCategory *LogCategory::create(const char *name) * \brief Construct a log category * \param[in] name The category name */ -LogCategory::LogCategory(const char *name) +LogCategory::LogCategory(std::string_view name) : name_(name), severity_(LogSeverity::LogInfo) { } From patchwork Thu Jan 30 19:58:47 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22715 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 52A1BBD808 for ; Thu, 30 Jan 2025 19:58:55 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 15B7C68574; Thu, 30 Jan 2025 20:58:55 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="qFNEtj3p"; dkim-atps=neutral Received: from mail-10631.protonmail.ch (mail-10631.protonmail.ch [79.135.106.31]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3C7406851B for ; Thu, 30 Jan 2025 20:58:53 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1738267132; x=1738526332; bh=wWWSvTBWzUt3mMvSNWgsAgb9RJeXwkMcnIay0f3fFDw=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=qFNEtj3pFXJbE81nfEv0YwdU3zrbHZkQivw2L/Ga/0yUwmXZuw/j9l0fj42H041hN EWxXyMElGbmjkKLeP7meTox7jAOCJPZDBTsS1jZVPchOgBfKw/uoz9uqQ4+2Vt8eLl S5QLh3CZWqsWu8iKIKJnD9phE6dUtW2vHK1QNvn7rCBTu3ct0lnFfEIVzaPZuFpqFa bH8/AwvZgtXpFNyFNzzP/mj5Qfkxg/qWY9UnQemwJ9qg9XeereWfKwjSZg25ScQhU/ dLBbRKG9N2S17CWOPmfNMAqg7dLwgcmQ9ZIkNEBDyKxBu7ksbwvWnHdnkkFlzYIceF HH/OYZRIxPbrA== Date: Thu, 30 Jan 2025 19:58:47 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Cc: Laurent Pinchart Subject: [RFC PATCH v2 6/9] libcamera: base: log: Pass dynamic prefix through Message-ID: <20250130195811.1230581-7-pobrn@protonmail.com> In-Reply-To: <20250130195811.1230581-1-pobrn@protonmail.com> References: <20250130195811.1230581-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: f7c5cdebdb8bce63116dffcb783b8c597c6fea9e MIME-Version: 1.0 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" Use move construction to essentially pass through the string returned by `Loggable::logPrefix()` to avoid an unnecessary copy. Signed-off-by: Barnabás Pőcze Reviewed-by: Laurent Pinchart --- include/libcamera/base/log.h | 2 +- src/libcamera/base/log.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/libcamera/base/log.h b/include/libcamera/base/log.h index acef24203..1fb92603f 100644 --- a/include/libcamera/base/log.h +++ b/include/libcamera/base/log.h @@ -64,7 +64,7 @@ class LogMessage public: LogMessage(const char *fileName, unsigned int line, const LogCategory &category, LogSeverity severity, - const std::string &prefix = std::string()); + std::string prefix = {}); ~LogMessage(); std::ostream &stream() { return msgStream_; } diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp index 9415b6937..0dfdb0e9b 100644 --- a/src/libcamera/base/log.cpp +++ b/src/libcamera/base/log.cpp @@ -872,9 +872,9 @@ const LogCategory &LogCategory::defaultCategory() */ LogMessage::LogMessage(const char *fileName, unsigned int line, const LogCategory &category, LogSeverity severity, - const std::string &prefix) + std::string prefix) : category_(category), severity_(severity), - timestamp_(utils::clock::now()), prefix_(prefix) + timestamp_(utils::clock::now()), prefix_(std::move(prefix)) { std::ostringstream ossFileInfo; ossFileInfo << utils::basename(fileName) << ":" << line; From patchwork Thu Jan 30 19:58:52 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22716 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 18DA2BD808 for ; Thu, 30 Jan 2025 19:59:00 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C861468564; Thu, 30 Jan 2025 20:58:59 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="Ajdm5gxc"; dkim-atps=neutral Received: from mail-10629.protonmail.ch (mail-10629.protonmail.ch [79.135.106.29]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6AF2B6856F for ; Thu, 30 Jan 2025 20:58:58 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1738267137; x=1738526337; bh=sOcbDhjCFmdl5MxKIQQEFCEZ3nO9fdZCIVttUxbqR44=; h=Date:To:From:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=Ajdm5gxcxRDkEpGNr+Tb/RcmW/swWI7CJBZ36icITKthRdgBtq+jbhEgZsggwXZhI /+4hTGiK80TiBIqshMazDZ+z0zAWPV9O5NvAMKmSisKfeZji/1M6ZgQpdhwxlrCFo5 I3WR1tmp9ViQr5NroipXrByU8XYkOUqHq0c4qj/bVEm21r1r4oz+1vsl4Vr9Zp7Cpj DkoGBghZ3b+extctcK+Imtdk6H3gnFcAjK238heZyjmBwxEciXg3AHg+Msa6lCuZbT LdGnHfXSy9wsdPpI+gyM/wKkoM9W5yzowY3+0YSgUuqpcdeWdVVxr2hV66rPRIG/HL fxcEpx4ix1XQw== Date: Thu, 30 Jan 2025 19:58:52 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Subject: [RFC PATCH v2 7/9] libcamera: base: log: Split `parseLogLevel[s]()` Message-ID: <20250130195811.1230581-8-pobrn@protonmail.com> In-Reply-To: <20250130195811.1230581-1-pobrn@protonmail.com> References: <20250130195811.1230581-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: 84e67e1b18e4f8175b8574f38da31f60e38c132a MIME-Version: 1.0 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" These two functions do not need to be exposed in any way, nor do they need to be a member of the `Logger` class. So move them into an anonymous namespace. Signed-off-by: Barnabás Pőcze Reviewed-by: Jacopo Mondi --- src/libcamera/base/log.cpp | 186 ++++++++++++++++++------------------- 1 file changed, 93 insertions(+), 93 deletions(-) diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp index 0dfdb0e9b..19fc5cc67 100644 --- a/src/libcamera/base/log.cpp +++ b/src/libcamera/base/log.cpp @@ -65,7 +65,9 @@ namespace libcamera { -static int log_severity_to_syslog(LogSeverity severity) +namespace { + +int log_severity_to_syslog(LogSeverity severity) { switch (severity) { case LogDebug: @@ -83,7 +85,7 @@ static int log_severity_to_syslog(LogSeverity severity) } } -static const char *log_severity_name(LogSeverity severity) +const char *log_severity_name(LogSeverity severity) { static const char *const names[] = { "DEBUG", @@ -99,6 +101,92 @@ static const char *log_severity_name(LogSeverity severity) return "UNKWN"; } +/** + * \brief Parse a log level string into a LogSeverity + * \param[in] level The log level string + * + * Log levels can be specified as an integer value in the range from LogDebug to + * LogFatal, or as a string corresponding to the severity name in uppercase. Any + * other value is invalid. + * + * \return The log severity, or LogInvalid if the string is invalid + */ +LogSeverity parseLogLevel(std::string_view level) +{ + static const char *const names[] = { + "DEBUG", + "INFO", + "WARN", + "ERROR", + "FATAL", + }; + + unsigned int severity; + + if (std::isdigit(level[0])) { + auto [end, ec] = std::from_chars(level.data(), level.data() + level.size(), severity); + if (ec != std::errc() || *end != '\0' || severity > LogFatal) + severity = LogInvalid; + } else { + severity = LogInvalid; + for (unsigned int i = 0; i < std::size(names); ++i) { + if (names[i] == level) { + severity = i; + break; + } + } + } + + return static_cast(severity); +} + +/** + * \brief Parse the log levels from the environment + * + * The log levels are stored in the LIBCAMERA_LOG_LEVELS environment variable + * as a list of "category:level" pairs, separated by commas (','). Parse the + * variable and store the levels to configure all log categories. + */ +void parseLogLevels(const char *line, std::list> &levels) +{ + for (const char *pair = line; *line != '\0'; pair = line) { + const char *comma = strchrnul(line, ','); + size_t len = comma - pair; + + /* Skip over the comma. */ + line = *comma == ',' ? comma + 1 : comma; + + /* Skip to the next pair if the pair is empty. */ + if (!len) + continue; + + std::string_view category; + std::string_view level; + + const char *colon = static_cast(memchr(pair, ':', len)); + if (!colon) { + /* 'x' is a shortcut for '*:x'. */ + category = "*"; + level = std::string_view(pair, len); + } else { + category = std::string_view(pair, colon - pair); + level = std::string_view(colon + 1, comma - colon - 1); + } + + /* Both the category and the level must be specified. */ + if (category.empty() || level.empty()) + continue; + + LogSeverity severity = parseLogLevel(level); + if (severity == LogInvalid) + continue; + + levels.emplace_back(category, severity); + } +} + +} /* namespace */ + /** * \brief Log output * @@ -312,8 +400,6 @@ private: Logger(); void parseLogFile(); - void parseLogLevels(); - static LogSeverity parseLogLevel(std::string_view level); friend LogCategory; void registerCategory(LogCategory *category); @@ -592,7 +678,9 @@ Logger::Logger() logSetStream(&std::cerr, color); parseLogFile(); - parseLogLevels(); + + if (const char *debug = utils::secure_getenv("LIBCAMERA_LOG_LEVELS")) + parseLogLevels(debug, levels_); } /** @@ -618,94 +706,6 @@ void Logger::parseLogFile() logSetFile(file, false); } -/** - * \brief Parse the log levels from the environment - * - * The log levels are stored in the LIBCAMERA_LOG_LEVELS environment variable - * as a list of "category:level" pairs, separated by commas (','). Parse the - * variable and store the levels to configure all log categories. - */ -void Logger::parseLogLevels() -{ - const char *debug = utils::secure_getenv("LIBCAMERA_LOG_LEVELS"); - if (!debug) - return; - - for (const char *pair = debug; *debug != '\0'; pair = debug) { - const char *comma = strchrnul(debug, ','); - size_t len = comma - pair; - - /* Skip over the comma. */ - debug = *comma == ',' ? comma + 1 : comma; - - /* Skip to the next pair if the pair is empty. */ - if (!len) - continue; - - std::string_view category; - std::string_view level; - - const char *colon = static_cast(memchr(pair, ':', len)); - if (!colon) { - /* 'x' is a shortcut for '*:x'. */ - category = "*"; - level = std::string_view(pair, len); - } else { - category = std::string_view(pair, colon - pair); - level = std::string_view(colon + 1, comma - colon - 1); - } - - /* Both the category and the level must be specified. */ - if (category.empty() || level.empty()) - continue; - - LogSeverity severity = parseLogLevel(level); - if (severity == LogInvalid) - continue; - - levels_.emplace_back(category, severity); - } -} - -/** - * \brief Parse a log level string into a LogSeverity - * \param[in] level The log level string - * - * Log levels can be specified as an integer value in the range from LogDebug to - * LogFatal, or as a string corresponding to the severity name in uppercase. Any - * other value is invalid. - * - * \return The log severity, or LogInvalid if the string is invalid - */ -LogSeverity Logger::parseLogLevel(std::string_view level) -{ - static const char *const names[] = { - "DEBUG", - "INFO", - "WARN", - "ERROR", - "FATAL", - }; - - unsigned int severity; - - if (std::isdigit(level[0])) { - auto [end, ec] = std::from_chars(level.data(), level.data() + level.size(), severity); - if (ec != std::errc() || *end != '\0' || severity > LogFatal) - severity = LogInvalid; - } else { - severity = LogInvalid; - for (unsigned int i = 0; i < std::size(names); ++i) { - if (names[i] == level) { - severity = i; - break; - } - } - } - - return static_cast(severity); -} - /** * \brief Register a log category with the logger * \param[in] category The log category From patchwork Thu Jan 30 19:58:57 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22717 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 A2C95BD808 for ; Thu, 30 Jan 2025 19:59:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 563F168574; Thu, 30 Jan 2025 20:59:01 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="enXbmsrZ"; dkim-atps=neutral Received: from mail-40133.protonmail.ch (mail-40133.protonmail.ch [185.70.40.133]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4F5DD68564 for ; Thu, 30 Jan 2025 20:58:59 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1738267138; x=1738526338; bh=sZE2KOGbSBN3Vmzmtw3niI/Hu81qYNu7iaBrkn0Uux0=; h=Date:To:From:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=enXbmsrZ2KngK7mSvkIpe3p/Rq91zRhvQVlKaKz8GfkIaP5eNsJMUvoHXsZGQrt08 LNg5ZV4BbU8BxARkU/PPuLiNFo9pfUmq7lU35j/JG1ldKKxCGXghCOhw1qQt/9TNj/ TpPJfYrgbutfUVyiVvawTMSJGF/HC5rxJ5CdWgTsCcOuxS7Cvue+rLLR7He2oQ+12A epyWJYq44atQ7kHpzTvDCG5CmY2Nlk1wSTbBMb3ClJ4TmrbVNxLkFoi4yfSTibQPH3 UvJm5jTcO+cCCuZeOdTafD0jCy7P1YjY5RMSeQqwXCbZcQnKnY5c6BieSSKLm33WDz By/V66BnX+VAg== Date: Thu, 30 Jan 2025 19:58:57 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Subject: [RFC PATCH v2 8/9] libcamera: base: log: Protect log categories with lock Message-ID: <20250130195811.1230581-9-pobrn@protonmail.com> In-Reply-To: <20250130195811.1230581-1-pobrn@protonmail.com> References: <20250130195811.1230581-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: 2e2a475dd5ae2b3250d6eb6c09094d6ee26e9c28 MIME-Version: 1.0 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" Log categories may be added from any thread, so it is important to synchronize access to the `Logger::categories_` list between its two users: `Logger::findOrCreateCategory()` and `Logger::logSetLevel()`. To achieve that, `Logger::{find,register}Category()` are merged into a single function: `Logger::findOrCreateCategory()`; and the mutex from `LogCategory::create()` is moved into the `Logger` class. Furthermore, appropriate `MutexLocker`s are placed in `Logger::findOrCreateCategory()` and `Logger::logSetLevel()`. Signed-off-by: Barnabás Pőcze Reviewed-by: Jacopo Mondi --- include/libcamera/base/log.h | 2 +- src/libcamera/base/log.cpp | 53 ++++++++++++------------------------ 2 files changed, 19 insertions(+), 36 deletions(-) diff --git a/include/libcamera/base/log.h b/include/libcamera/base/log.h index 1fb92603f..b32ec4516 100644 --- a/include/libcamera/base/log.h +++ b/include/libcamera/base/log.h @@ -30,6 +30,7 @@ enum LogSeverity { class LogCategory { public: + explicit LogCategory(std::string_view name); static LogCategory *create(std::string_view name); const std::string &name() const { return name_; } @@ -39,7 +40,6 @@ public: static const LogCategory &defaultCategory(); private: - explicit LogCategory(std::string_view name); const std::string name_; diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp index 19fc5cc67..69aa16c4c 100644 --- a/src/libcamera/base/log.cpp +++ b/src/libcamera/base/log.cpp @@ -402,11 +402,11 @@ private: void parseLogFile(); friend LogCategory; - void registerCategory(LogCategory *category); - LogCategory *findCategory(std::string_view name) const; + LogCategory *findOrCreateCategory(std::string_view name); static bool destroyed_; + Mutex mutex_; std::vector categories_; std::list> levels_; @@ -657,6 +657,8 @@ void Logger::logSetLevel(const char *category, const char *level) if (severity == LogInvalid) return; + MutexLocker locker(mutex_); + for (LogCategory *c : categories_) { if (c->name() == category) { c->setSeverity(severity); @@ -707,17 +709,21 @@ void Logger::parseLogFile() } /** - * \brief Register a log category with the logger - * \param[in] category The log category - * - * Log categories must have unique names. It is invalid to call this function - * if a log category with the same name already exists. + * \brief Find an existing log category with the given name or create one + * \param[in] name Name of the log category + * \return The pointer to the log category found or created */ -void Logger::registerCategory(LogCategory *category) +LogCategory *Logger::findOrCreateCategory(std::string_view name) { - categories_.push_back(category); + MutexLocker locker(mutex_); + + for (LogCategory *category : categories_) { + if (category->name() == name) + return category; + } + + LogCategory *category = categories_.emplace_back(new LogCategory(name)); - const std::string &name = category->name(); for (const std::pair &level : levels_) { bool match = true; @@ -737,22 +743,8 @@ void Logger::registerCategory(LogCategory *category) break; } } -} -/** - * \brief Find an existing log category with the given name - * \param[in] name Name of the log category - * \return The pointer to the found log category or nullptr if not found - */ -LogCategory *Logger::findCategory(std::string_view name) const -{ - if (auto it = std::find_if(categories_.begin(), categories_.end(), - [name](auto c) { return c->name() == name; }); - it != categories_.end()) { - return *it; - } - - return nullptr; + return category; } /** @@ -790,16 +782,7 @@ LogCategory *Logger::findCategory(std::string_view name) const */ LogCategory *LogCategory::create(std::string_view name) { - static Mutex mutex_; - MutexLocker locker(mutex_); - LogCategory *category = Logger::instance()->findCategory(name); - - if (!category) { - category = new LogCategory(name); - Logger::instance()->registerCategory(category); - } - - return category; + return Logger::instance()->findOrCreateCategory(name); } /** From patchwork Mon Feb 3 17:59:39 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22726 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 2F8C9BD80A for ; Mon, 3 Feb 2025 17:59:47 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 458E86859D; Mon, 3 Feb 2025 18:59:46 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="Fl+gSCjd"; dkim-atps=neutral Received: from mail-10630.protonmail.ch (mail-10630.protonmail.ch [79.135.106.30]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C40D761876 for ; Mon, 3 Feb 2025 18:59:44 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1738605583; x=1738864783; bh=iS7KFwtgjtdLe3sYFbSNvmj0wqHbsFaZ+7FduZfw03c=; h=Date:To:From:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=Fl+gSCjdD3ZRkS96j2znUC3VjR3UJOpW9QNocRJ7D18WNXbsKEtzMZp68sFeM09uy JxEm4oJurVvBuamBjKWDBEgT8VJT93SmDrZQBcumHHfabbGWMcvk8xGbSXSvzIhJyk iwgronNvdv3akJEQQe9ByDL07NEKSmK/SD3mZmpe/PI5RfHoj5rk2yypUF5I8eNIxP dKZNKcL/oY2S8WCUXx+Bh17RXokmxTCqtb+yK3OJIiNjlsA+S8wjKpJykV/uWixEjD WpPL46k0DG3ublQC1R6L/1EmSVdeFqJ+aryIRBuv1rCvHCjMjAZ0l1t5oqa2BvXg// UeQ3QpVbkUWbw== Date: Mon, 03 Feb 2025 17:59:39 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Subject: [RFC PATCH v2 9/9] libcamera: base: log: Store categories in list Message-ID: <20250203175936.206161-1-pobrn@protonmail.com> In-Reply-To: <20250130195811.1230581-1-pobrn@protonmail.com> References: <20250130195811.1230581-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: f931f503d745fcf4965e1180b2ff1189a3d7bfee MIME-Version: 1.0 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" Store the `LogCategory` objects in an `std::list`. This eliminates the need for manually deleting them in the destructor while guaranteeing address stability. Signed-off-by: Barnabás Pőcze Reviewed-by: Jacopo Mondi --- src/libcamera/base/log.cpp | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp index 69aa16c4c..003e2cf3a 100644 --- a/src/libcamera/base/log.cpp +++ b/src/libcamera/base/log.cpp @@ -407,7 +407,7 @@ private: static bool destroyed_; Mutex mutex_; - std::vector categories_; + std::list categories_; std::list> levels_; std::shared_ptr output_; @@ -524,9 +524,6 @@ void logSetLevel(const char *category, const char *level) Logger::~Logger() { destroyed_ = true; - - for (LogCategory *category : categories_) - delete category; } /** @@ -659,9 +656,9 @@ void Logger::logSetLevel(const char *category, const char *level) MutexLocker locker(mutex_); - for (LogCategory *c : categories_) { - if (c->name() == category) { - c->setSeverity(severity); + for (LogCategory &c : categories_) { + if (c.name() == category) { + c.setSeverity(severity); break; } } @@ -717,12 +714,12 @@ LogCategory *Logger::findOrCreateCategory(std::string_view name) { MutexLocker locker(mutex_); - for (LogCategory *category : categories_) { - if (category->name() == name) - return category; + for (LogCategory &category : categories_) { + if (category.name() == name) + return &category; } - LogCategory *category = categories_.emplace_back(new LogCategory(name)); + LogCategory &category = categories_.emplace_back(name); for (const std::pair &level : levels_) { bool match = true; @@ -739,12 +736,12 @@ LogCategory *Logger::findOrCreateCategory(std::string_view name) } if (match) { - category->setSeverity(level.second); + category.setSeverity(level.second); break; } } - return category; + return &category; } /**