Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,13 @@ build:asan_ubsan_lsan --config=with_debug_symbols
build:asan_ubsan_lsan --copt=-fsanitize=undefined,address,leak
build:asan_ubsan_lsan --linkopt=-fsanitize=undefined,address,leak
build:asan_ubsan_lsan --platform_suffix=asan_ubsan_lsan
build:asan_ubsan_lsan --@score_cpp_policies//sanitizers/flags:sanitizer=asan_ubsan_lsan
# score_cpp_policies removed the combined string flag ":sanitizer" in favor of
# per-sanitizer bool flags; the //sanitizers:wrapper run_under target (and its
# constraints/features) only activate when these are set, otherwise every test
# using it is marked incompatible and silently skipped.
build:asan_ubsan_lsan --@score_cpp_policies//sanitizers/flags:asan=True
build:asan_ubsan_lsan --@score_cpp_policies//sanitizers/flags:ubsan=True
build:asan_ubsan_lsan --@score_cpp_policies//sanitizers/flags:lsan=True
test:asan_ubsan_lsan --run_under=@score_cpp_policies//sanitizers:wrapper
test:asan_ubsan_lsan --test_tag_filters=-no-asan,-no-lsan,-no-ubsan
test:asan_ubsan_lsan --build_tests_only
Expand Down
33 changes: 33 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# *******************************************************************************
# Copyright (c) 2026 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************

# Default clang-tidy configuration for S-CORE C++ modules.
# NOTE: the set of enabled checks is yet subject to be tailored per module.
Checks: "-*,clang-analyzer-*,cert-*,cppcoreguidelines-*,bugprone-*,misc-*,performance-*,readability-*,modernize-*,-modernize-use-trailing-return-type"

# NOTE: WarningsAsErrors is yet subject to be expanded per module as compliance increases.
WarningsAsErrors: "clang-analyzer-*"

# HeaderFilterRegex is intentionally absent from the central baseline.
# Each consuming module must set this in their local .clang-tidy to match
# their own source tree (e.g., HeaderFilterRegex: 'score/mw/').
# Setting it here would either suppress all header analysis (empty string)
# or generate noise from external dependency headers (broad regex).
# LLVM's regex engine does not reliably support POSIX lookaheads, so
# negative-lookahead patterns like (?!.*/external/) must not be used here.

FormatStyle: none

# NOTE: CheckOptions are yet subject to be provided for each enabled check per module.
#CheckOptions:
# none yet
22 changes: 16 additions & 6 deletions .github/workflows/clang-tidy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,25 @@ jobs:
| xargs cat 2>/dev/null > clang_tidy_findings.txt || true

- name: Check violation baseline
# Baseline recorded on 2026-07-03. Decrease when violations are fixed.
# Remove this step once https://github.com/eclipse-score/time/issues/111 is resolved.
if: always()
run: |
BASELINE=85
COUNT=$(wc -l < clang_tidy_findings.txt 2>/dev/null || echo 0)
echo "Clang-tidy violations: $COUNT (baseline: $BASELINE)"
if [ "$COUNT" -gt "$BASELINE" ]; then
echo "::error::Clang-tidy violations grew: $COUNT > baseline $BASELINE. Fix new violations before merging."
TIME_DAEMON_BASELINE=0
TIME_DAEMON_COUNT=$(grep -cE "score/time_daemon/[^:]*:[0-9]+:[0-9]+: (warning|error):" clang_tidy_findings.txt 2>/dev/null || true)
TIME_DAEMON_COUNT=${TIME_DAEMON_COUNT:-0}
echo "Clang-tidy violations in score/time_daemon/: $TIME_DAEMON_COUNT (baseline: $TIME_DAEMON_BASELINE)"

OTHER_BASELINE=1050
OTHER_COUNT=$(grep -E ":[0-9]+:[0-9]+: (warning|error):" clang_tidy_findings.txt 2>/dev/null | grep -vcE "score/time_daemon/" || true)
OTHER_COUNT=${OTHER_COUNT:-0}
echo "Clang-tidy violations outside score/time_daemon/: $OTHER_COUNT (baseline: $OTHER_BASELINE)"

if [ "$TIME_DAEMON_COUNT" -gt "$TIME_DAEMON_BASELINE" ]; then
echo "::error::Clang-tidy violations in score/time_daemon/ grew: $TIME_DAEMON_COUNT > baseline $TIME_DAEMON_BASELINE. Fix new violations before merging."
exit 1
fi
if [ "$OTHER_COUNT" -gt "$OTHER_BASELINE" ]; then
echo "::error::Clang-tidy violations outside score/time_daemon/ grew: $OTHER_COUNT > baseline $OTHER_BASELINE. Fix new violations before merging."
exit 1
Comment thread
MaciejSalwa543 marked this conversation as resolved.
fi

Expand Down
2 changes: 2 additions & 0 deletions BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,7 @@ exports_files(
[
# Used by the @score_tooling coverage reporter to locate the workspace root.
"MODULE.bazel",
# Referenced by //tools/lint:linters.bzl as a local_configs entry for the clang-tidy aspect.
".clang-tidy",
],
)
1 change: 1 addition & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ llvm = use_extension(
)
llvm.toolchain(
llvm_version = "19.1.7",
stdlib = {"": "stdc++"},
)

# Coverage-only Clang instance (covmap instrumentation for the LLVM coverage
Expand Down
31 changes: 17 additions & 14 deletions score/time_daemon/src/application/job_runner/job_runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,23 @@
#include "score/time_daemon/src/application/job_runner/job_runner.h"
#include "score/concurrency/interruptible_wait.h"
#include "score/mw/log/logging.h"
#include "score/stop_token.hpp"
#include "score/time_daemon/src/common/logging_contexts.h"
#include <chrono>
#include <mutex>
#include <string>
#include <utility>
#include <vector>

namespace score
{
namespace td
namespace score::td
{

JobRunner::JobRunner(std::vector<Job> jobs, const std::string name)
: jobs_(std::move(jobs)), name_(name), status_{Result::kIdle}
{
}
JobRunner::JobRunner(std::vector<Job> jobs, std::string name) : jobs_(std::move(jobs)), name_(std::move(name)) {}

void JobRunner::Start(const score::cpp::stop_token& token)
{
{
std::lock_guard<std::mutex> lock(status_mutex_);
const std::lock_guard<std::mutex> lock(status_mutex_);
if (status_ != Result::kIdle)
{
return; // Already running
Expand All @@ -41,9 +42,9 @@ void JobRunner::Start(const score::cpp::stop_token& token)

const auto thread_name = "td_" + name_ + "_worker";
worker_thread_ = score::cpp::jthread(score::cpp::jthread::name_hint{thread_name}, [this, &token]() {
bool success = RunJobs(token);
const bool success = RunJobs(token);
{
std::lock_guard<std::mutex> lock(status_mutex_);
const std::lock_guard<std::mutex> lock(status_mutex_);
status_ = success ? Result::kSucceed : Result::kFailed;
}
});
Expand Down Expand Up @@ -83,7 +84,10 @@ bool JobRunner::RunJobs(const score::cpp::stop_token& token)
}

if (!jobs_.empty())
score::concurrency::wait_for(token, std::chrono::milliseconds(10));
{
constexpr auto kJobPollInterval = std::chrono::milliseconds(10);
score::concurrency::wait_for(token, kJobPollInterval);
}
}
// If the loop exited due to stop token, mark as failure
if (token.stop_requested())
Expand All @@ -96,9 +100,8 @@ bool JobRunner::RunJobs(const score::cpp::stop_token& token)

JobRunner::Result JobRunner::GetResult() const
{
std::lock_guard<std::mutex> lock(status_mutex_);
const std::lock_guard<std::mutex> lock(status_mutex_);
return status_;
}

} // namespace td
} // namespace score
} // namespace score::td
17 changes: 8 additions & 9 deletions score/time_daemon/src/application/job_runner/job_runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
#include <score/jthread.hpp>
#include <score/stop_token.hpp>
#include <chrono>
#include <cstdint>
#include <functional>
#include <mutex>
#include <string>
#include <vector>

namespace score
{
namespace td
namespace score::td
{

/**
Expand All @@ -33,7 +33,7 @@ struct Job
std::function<bool()> fn;
std::string name;
std::chrono::seconds timeout;
std::chrono::steady_clock::time_point start{};
std::chrono::steady_clock::time_point start;
};

/**
Expand All @@ -51,12 +51,12 @@ class JobRunner
* @param jobs Vector of jobs to run.
* @param name name of the job.
*/
JobRunner(std::vector<Job> jobs, const std::string name);
JobRunner(std::vector<Job> jobs, std::string name);

/**
* @brief Represents the jobs status
*/
enum class Result
enum class Result : std::uint8_t
{
kIdle,
kInProgress,
Expand Down Expand Up @@ -89,12 +89,11 @@ class JobRunner

std::vector<Job> jobs_;
const std::string name_;
Result status_;
Result status_{Result::kIdle};
mutable std::mutex status_mutex_;
score::cpp::jthread worker_thread_;
};

} // namespace td
} // namespace score
} // namespace score::td

#endif // SCORE_TIME_DAEMON_SRC_APPLICATION_JOB_RUNNER_JOB_RUNNER_H
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@
#include <chrono>
#include <thread>

namespace score
{
namespace td
namespace score::td
{

/**
Expand Down Expand Up @@ -179,5 +177,4 @@ TEST_F(JobRunnerTest, StopMultipleJobsEarly)
EXPECT_LE(counter.load(), 2);
}

} // namespace td
} // namespace score
} // namespace score::td
9 changes: 4 additions & 5 deletions score/time_daemon/src/application/svt/factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,15 @@
#include "score/time_daemon/src/application/svt/factory.h"

#include "score/time_daemon/src/application/svt/svt_handler.h"
#include "score/time_daemon/src/application/timebase_handler.h"
#include <memory>

namespace score
{
namespace td
namespace score::td
{

std::unique_ptr<TimebaseHandler> CreateSvtTimebase()
{
return std::make_unique<SvtHandler>();
}

} // namespace td
} // namespace score
} // namespace score::td
7 changes: 2 additions & 5 deletions score/time_daemon/src/application/svt/factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,14 @@

#include <memory>

namespace score
{
namespace td
namespace score::td
{

/// \brief Creates a new SVT timebase handler
///
/// \return std::unique_ptr<TimebaseHandler> New SVT timebase handler
std::unique_ptr<TimebaseHandler> CreateSvtTimebase();

} // namespace td
} // namespace score
} // namespace score::td

#endif // SCORE_TIME_DAEMON_SRC_APPLICATION_FACTORY_H
36 changes: 21 additions & 15 deletions score/time_daemon/src/application/svt/svt_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,60 +11,67 @@
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
#include "score/time_daemon/src/application/svt/svt_handler.h"
#include "score/concurrency/interruptible_wait.h"
#include "score/mw/log/logging.h"
#include "score/stop_token.hpp"
#include "score/time_daemon/src/application/job_runner/job_runner.h"
#include "score/time_daemon/src/application/timebase_handler.h"
#include "score/time_daemon/src/common/data_types/ptp_time_info.h"
#include "score/time_daemon/src/common/logging_contexts.h"
#include "score/time_daemon/src/control_flow_divider/ptp/factory.h"
#include "score/time_daemon/src/ipc/svt/publisher/factory.h"
#include "score/time_daemon/src/msg_broker/subscription.h"
#include "score/time_daemon/src/msg_broker/msg_broker.h"
#include "score/time_daemon/src/msg_broker/topic.h"
#include "score/time_daemon/src/ptp_machine/shm/factory.h"
#include "score/time_daemon/src/verification_machine/svt/factory.h"

#include <chrono>
#include <future>
#include <memory>
#include <utility>
#include <vector>

namespace score
namespace score::td
{
namespace td

namespace
{
constexpr auto kCtrlFlowDividerTimeout = std::chrono::milliseconds{250};
constexpr auto kJobInitTimeout = std::chrono::seconds(20);
} // namespace

SvtHandler::SvtHandler() noexcept
: job_runner_{nullptr},
msg_broker_{nullptr},
gptp_machine_{nullptr},
verification_machine_{nullptr},
ipc_publisher_{nullptr},
ctrl_flow_divider_{nullptr},
handler_status_{TimebaseHandler::Status::kIdle}
ctrl_flow_divider_{nullptr}
{
msg_broker_ = std::make_shared<MessageBroker<PtpTimeInfo>>();
gptp_machine_ = CreateGPTPShmMachine("ptp_worker");
verification_machine_ = CreateSvtVerificationMachine("time_verification_worker");
ipc_publisher_ = CreateSvtPublisher("svt_ipc_publisher");
ctrl_flow_divider_ = CreatePtpControlFlowDivider("ptp_control_flow_divider", std::chrono::milliseconds{250});
ctrl_flow_divider_ = CreatePtpControlFlowDivider("ptp_control_flow_divider", kCtrlFlowDividerTimeout);

std::vector<Job> jobs = {
{[this] {
return gptp_machine_->Init();
},
gptp_machine_->GetName(),
std::chrono::seconds(20)},
kJobInitTimeout},
{[this] {
return verification_machine_->Init();
},
verification_machine_->GetName(),
std::chrono::seconds(20)},
kJobInitTimeout},
{[this] {
return ipc_publisher_->Init();
},
ipc_publisher_->GetName(),
std::chrono::seconds(20)},
kJobInitTimeout},
{[this] {
return ctrl_flow_divider_->Init();
},
ctrl_flow_divider_->GetName(),
std::chrono::seconds(20)},
kJobInitTimeout},
};
job_runner_ = std::make_unique<JobRunner>(std::move(jobs), "svt_init");

Expand Down Expand Up @@ -145,5 +152,4 @@ void SvtHandler::Stop() noexcept
}
}

} // namespace td
} // namespace score
} // namespace score::td
Loading
Loading