Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#ifndef TIMESORTINGBUFFER_HPP_INCLUDED
#define TIMESORTINGBUFFER_HPP_INCLUDED

#include <chrono>
#include <cstdint>
#include <type_traits>

Expand Down Expand Up @@ -67,9 +68,7 @@ class TimeSortingBuffer
/// @return Success of push (true) sufficient space in buffer was available
/* RULECHECKER_comment(0, 3, check_cheap_to_copy_in_parameter, "For template argument f_element_r, it is not \
possible to classify cheap_to_copy or expensive_to_copy without referring original object.", true_no_defect) */
bool push(
const TimeSortedElementType& f_element_r,
const score::mw::lifecycle::internal::saf::timers::NanoSecondType f_timestamp)
bool push(const TimeSortedElementType& f_element_r, const std::chrono::nanoseconds f_timestamp)
{
bool isSuccess{false};
SortChainElement newElement{nullptr, nullptr, f_element_r, f_timestamp};
Expand Down Expand Up @@ -134,8 +133,7 @@ class TimeSortingBuffer
nullptr}; // Pointer to previous element, null pointer means first element (oldest)
SortChainElement* next_p{nullptr}; // Pointer to next element, null pointer means last element (latest)
TimeSortedElementType element{}; // Element to be sorted
score::mw::lifecycle::internal::saf::timers::NanoSecondType timestamp{
0U}; // Timestamp used for sorting the elements
std::chrono::nanoseconds timestamp{0U}; // Timestamp used for sorting the elements
};

/// Sort elements
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ PhmDaemon::PhmDaemon(OsClock& f_osClock, std::size_t supervised_components)

void PhmDaemon::performCyclicTriggers(void)
{
NanoSecondType syncTimestamp{timers::OsClock::getMonotonicSystemClock()};
if (syncTimestamp == 0U)
std::chrono::nanoseconds syncTimestamp{timers::OsClock::getMonotonicSystemClock()};
if (syncTimestamp.count() == 0U)
{
// No valid time value, use max value for synchronization
// All received data will be considered.
syncTimestamp = UINT64_MAX;
syncTimestamp = std::chrono::nanoseconds::max();
}

if (supervisionStateReader_.distributeChanges(syncTimestamp))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ class PhmDaemon final : public ISupervisionFactory
using RecoveryClient = score::mw::lifecycle::IRecoveryClient;
using CycleTimer = score::mw::lifecycle::internal::saf::timers::CycleTimer;
using CycleTimeValidator = score::mw::lifecycle::internal::saf::timers::CycleTimeValidator;
using NanoSecondType = score::mw::lifecycle::internal::saf::timers::NanoSecondType;
using ObservableEventReader = score::mw::lifecycle::internal::saf::ifexm::ObservableEventReader;
using Config = score::mw::lifecycle::internal::configuration::Config;

Expand Down Expand Up @@ -77,18 +76,17 @@ class PhmDaemon final : public ISupervisionFactory
{
recoveryClient = recovery_client;

int64_t cycleTimeModified{
static_cast<std::int64_t>(timers::TimeConversion::convertMilliSecToNanoSec(config.evaluation_cycle_ms))};
std::chrono::nanoseconds cycleTimeModified{
timers::TimeConversion::convertMilliSecToNanoSec(std::chrono::milliseconds{config.evaluation_cycle_ms})};

cycleTimeModified = CycleTimeValidator::adjustCycleTimeOnClockAccuracy(cycleTimeModified, osClock);

const int64_t timerInit{cycleTimer.init(cycleTimeModified)};
if (timerInit > 0)
const std::chrono::nanoseconds timerInit{cycleTimer.init(cycleTimeModified)};
if (timerInit.count() > 0)
{
LM_LOG_INFO() << "Phm Daemon: The (configured) periodicity in [ns] is set to:"
<< static_cast<uint64_t>(cycleTimeModified);
LM_LOG_INFO() << "Phm Daemon: The (configured) periodicity in [ns] is set to:" << cycleTimeModified;
LM_LOG_DEBUG() << "Phm Daemon: The accuracy of the monotonic system clock in [ns] is:"
<< static_cast<uint64_t>(CycleTimeValidator::getMonotonicClockAccuracy(osClock));
<< CycleTimeValidator::getMonotonicClockAccuracy(osClock);
}
else
{
Expand Down Expand Up @@ -122,8 +120,8 @@ class PhmDaemon final : public ISupervisionFactory
template <typename TerminationSignalPredType>
bool startCyclicExec(const TerminationSignalPredType& f_terminateCond) noexcept
{
NanoSecondType startTimestamp{cycleTimer.start()};
if (startTimestamp == 0U)
std::chrono::nanoseconds startTimestamp{cycleTimer.start()};
if (startTimestamp.count() == 0U)
{
LM_LOG_ERROR() << "Phm Daemon: Failed to get initial timestamp";
return false;
Expand All @@ -143,7 +141,7 @@ class PhmDaemon final : public ISupervisionFactory
(void)cycleTimer.calcNextShot();

// Sleep for the remaining cycle time or break out of cyclic loop if termination is requested
std::uint64_t nsOverDeadline{0U};
std::chrono::nanoseconds nsOverDeadline{0U};
const int sleepResult{cycleTimer.sleep(f_terminateCond, nsOverDeadline)};
if (sleepResult == EINTR)
{
Expand All @@ -153,8 +151,8 @@ class PhmDaemon final : public ISupervisionFactory
else if (sleepResult == CycleTimer::kDeadlineAlreadyOver)
{
LM_LOG_DEBUG() << "Phm Daemon: Phm cycle took"
<< (static_cast<double>(nsOverDeadline) / 1000000.0 /*ns per ms*/)
<< "ms longer than the configured cycle time";
<< std::chrono::ceil<std::chrono::milliseconds>(nsOverDeadline)
<< "longer than the configured cycle time";
Comment thread
NicolasFussberger marked this conversation as resolved.
}
else if (sleepResult != 0)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,15 @@ bool SupervisionManager::constructWorker(
return true;
}

void SupervisionManager::checkInterfaceForNewData(const timers::NanoSecondType f_syncTimestamp)
void SupervisionManager::checkInterfaceForNewData(const std::chrono::nanoseconds f_syncTimestamp)
{
for (auto& aliveInterface : aliveInterfaces)
{
aliveInterface.checkForNewData(f_syncTimestamp);
}
}

void SupervisionManager::evaluateSupervisions(const timers::NanoSecondType f_syncTimestamp)
void SupervisionManager::evaluateSupervisions(const std::chrono::nanoseconds f_syncTimestamp)
{
for (auto& alive : aliveSupervisions)
{
Expand All @@ -107,7 +107,7 @@ bool SupervisionManager::hasAnyRecoveryEnqueueFailed() const noexcept
return false;
}

void SupervisionManager::performCyclicTriggers(const timers::NanoSecondType f_syncTimestamp)
void SupervisionManager::performCyclicTriggers(const std::chrono::nanoseconds f_syncTimestamp)
{
checkInterfaceForNewData(f_syncTimestamp);
evaluateSupervisions(f_syncTimestamp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class SupervisionManager
/// @brief Perform cyclic execution
/// @details Perform cyclic execution required for alive supervision
/// @param [in] f_syncTimestamp Timestamp for cyclic synchronization
void performCyclicTriggers(const timers::NanoSecondType f_syncTimestamp);
void performCyclicTriggers(const std::chrono::nanoseconds f_syncTimestamp);

/// @brief Check whether any alive supervision failed to enqueue a recovery request
/// @return True if any alive supervision recovery request has failed
Expand All @@ -117,12 +117,12 @@ class SupervisionManager
/// @brief Check interfaces for new data
/// @details All interfaces created during construction will be checked for new data.
/// @param [in] f_syncTimestamp Timestamp for cyclic synchronization
void checkInterfaceForNewData(const timers::NanoSecondType f_syncTimestamp);
void checkInterfaceForNewData(const std::chrono::nanoseconds f_syncTimestamp);

/// @brief Evaluate supervisions
/// @details Evaluate all supervisions created during construction.
/// @param [in] f_syncTimestamp Timestamp for cyclic synchronization
void evaluateSupervisions(const timers::NanoSecondType f_syncTimestamp);
void evaluateSupervisions(const std::chrono::nanoseconds f_syncTimestamp);

/// Vector of Process states
std::vector<ifexm::ObservableEvent> processStates;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ namespace score::mw::lifecycle::internal::saf::factory
{

using RecoveryClient = score::mw::lifecycle::IRecoveryClient;
using NanoSecondType = saf::timers::NanoSecondType;
using IdentifierHash = score::mw::lifecycle::IdentifierHash;

FlatCfgFactory::FlatCfgFactory() : IPhmFactory()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@ Checkpoint::Checkpoint(const ifexm::ObservableEvent* f_processState_p) noexcept(
static_cast<void>(0U);
}

timers::NanoSecondType Checkpoint::getTimestamp(void) const noexcept(true)
std::chrono::nanoseconds Checkpoint::getTimestamp(void) const noexcept(true)
{
return timestamp;
}

void Checkpoint::pushData(const timers::NanoSecondType f_timestamp) noexcept(true)
void Checkpoint::pushData(const std::chrono::nanoseconds f_timestamp) noexcept(true)
{
timestamp = f_timestamp;

// If monotonic system clock fails, set data loss event.
if (timestamp == 0U)
if (timestamp.count() == 0U)
{
setDataLossEvent(true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,13 @@ class Checkpoint : public saf::common::Observable<Checkpoint>
~Checkpoint() override = default;

/// @brief Get timestamp
/// @return NanoSecondType Timestamp value of the reported checkpoint in [nano seconds]
score::mw::lifecycle::internal::saf::timers::NanoSecondType getTimestamp(void) const noexcept(true);
/// @return std::chrono::nanoseconds Timestamp value of the reported checkpoint in [nano seconds]
std::chrono::nanoseconds getTimestamp(void) const noexcept(true);

/// @brief Push data to checkpoint observer
/// @details Push the checkpoint timestamp to the checkpoint observer to notify it was reported
/// @param [in] f_timestamp Timestamp value captured when the checkpoint was reported in [nano seconds]
void pushData(const score::mw::lifecycle::internal::saf::timers::NanoSecondType f_timestamp) noexcept(true);
void pushData(const std::chrono::nanoseconds f_timestamp) noexcept(true);

/// @brief Set data loss event
/// @details Set data loss event in the checkpoint observer
Expand All @@ -91,7 +91,7 @@ class Checkpoint : public saf::common::Observable<Checkpoint>
bool isDataLossEvent;

/// @brief Timestamp value in [nano seconds]
score::mw::lifecycle::internal::saf::timers::NanoSecondType timestamp;
std::chrono::nanoseconds timestamp;
};

} // namespace score::mw::lifecycle::internal::saf::ifappl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ required for Vector and IPC APIs", true_no_defect) */
struct CheckpointBufferElement final
{
/// @brief Timestamp of the checkpoint
internal::saf::timers::NanoSecondType timestamp{0U};
std::chrono::nanoseconds timestamp{0U};

/// @brief Default constructor needed for storage in vector
CheckpointBufferElement() = default;

/// @brief Constructor for usage with emplace
/// @param [in] f_timestamp The checkpoint timestamp
CheckpointBufferElement(internal::saf::timers::NanoSecondType f_timestamp) noexcept(true) : timestamp(f_timestamp)
CheckpointBufferElement(std::chrono::nanoseconds f_timestamp) noexcept(true) : timestamp(f_timestamp)
{
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ void MonitorIfDaemon::updateData(const ifexm::ObservableEvent& f_observable_r) n
}
}

void MonitorIfDaemon::checkForNewData(const timers::NanoSecondType f_syncTimestamp) noexcept(true)
void MonitorIfDaemon::checkForNewData(const std::chrono::nanoseconds f_syncTimestamp) noexcept(true)
{
if ((isActivateRequest == true) && (status == EInternalState::kInactive))
{
Expand Down Expand Up @@ -126,7 +126,7 @@ void MonitorIfDaemon::pushCheckpointToObservers(const CheckpointBufferElement& f
}
}

bool MonitorIfDaemon::pushNewDataToCheckpointObservers(const timers::NanoSecondType f_syncTimestamp)
bool MonitorIfDaemon::pushNewDataToCheckpointObservers(const std::chrono::nanoseconds f_syncTimestamp)
{
using IpcResult = CheckpointIpcServer::EIpcPeekResult;
std::uint32_t amountOfReceivedCheckpoints{0U};
Expand Down Expand Up @@ -188,7 +188,7 @@ void MonitorIfDaemon::pushOverflowInfoToCheckpointObservers(void) const
for (auto& observer : checkpointObservers)
{
observer->setDataLossEvent(true);
observer->pushData(static_cast<timers::NanoSecondType>(0));
observer->pushData(static_cast<std::chrono::nanoseconds>(0));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@ class MonitorIfDaemon : public common::Observer<ifexm::ObservableEvent>
/// @brief Check for new data
/// @details Check Alive interface for new data from application side
/// @param [in] f_syncTimestamp Timestamp till data shall be read, newer data will not be considered
void checkForNewData(const score::mw::lifecycle::internal::saf::timers::NanoSecondType f_syncTimestamp) noexcept(
true);
void checkForNewData(const std::chrono::nanoseconds f_syncTimestamp) noexcept(true);

private:
/// @brief Check if checkpoint ring buffer overflow has occurred
Expand All @@ -115,8 +114,7 @@ class MonitorIfDaemon : public common::Observer<ifexm::ObservableEvent>
/// @details The checkpoint ring buffer data is pushed to checkpoint specific objects.
/// @param [in] f_syncTimestamp Timestamp till data shall be read, newer data will not be considered
/// @returns True if reading data from IPC channel and pushing data to observers was successful, else false
bool pushNewDataToCheckpointObservers(
const score::mw::lifecycle::internal::saf::timers::NanoSecondType f_syncTimestamp);
bool pushNewDataToCheckpointObservers(const std::chrono::nanoseconds f_syncTimestamp);

/// @brief Push a single checkpoint to observers
/// @param[in] f_elem_r The checkpoint to push to observers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,23 +72,23 @@ struct MonitorIfDaemonFixture
}

/// Send an activation event and notify observers.
void activateProcess(long ts)
void activateProcess(std::chrono::nanoseconds ts)
{
processState.event.systemClockTimestamp.tv_nsec = ts;
processState.event.systemClockTimestamp.tv_nsec = ts.count();
processState.event.eventType = score::mw::lifecycle::SupervisionEventType::kActivation;
processState.pushData();
}

/// Send a deactivation event and notify observers.
void deactivateProcess(long ts)
void deactivateProcess(std::chrono::nanoseconds ts)
{
processState.event.systemClockTimestamp.tv_nsec = ts;
processState.event.systemClockTimestamp.tv_nsec = ts.count();
processState.event.eventType = score::mw::lifecycle::SupervisionEventType::kDeactivation;
processState.pushData();
}

/// Write a single checkpoint element into the IPC ring buffer.
void sendCheckpoint(timers::NanoSecondType ts)
void sendCheckpoint(std::chrono::nanoseconds ts)
{
ipcServer.sendEmplace(ts);
}
Expand All @@ -99,7 +99,7 @@ struct MonitorIfDaemonFixture
// Sending one element beyond capacity sets the ring-buffer overflow flag.
for (uint32_t i = 0U; i <= ifappl::k_maxCheckpointBufferElements; ++i)
{
ipcServer.sendEmplace(static_cast<timers::NanoSecondType>(i));
ipcServer.sendEmplace(static_cast<std::chrono::nanoseconds>(i));
}
}
};
Expand All @@ -109,43 +109,43 @@ struct MonitorIfDaemonFixture
class MonitorIfDaemonTest : public ::testing::Test
{
private:
timespec time_{};
static constexpr long kTimeStep = 100U;
std::chrono::nanoseconds time_{};
static constexpr std::chrono::nanoseconds kTimeStep{100U};

protected:
void SetUp() override
{
RecordProperty("TestType", "interface-test");
RecordProperty("DerivationTechnique", "explorative-testing");
time_.tv_nsec = 0;
time_ = std::chrono::nanoseconds{0};
}

public:
/// @brief Clock that increases at fixed intervals with each call
[[nodiscard]]
timers::NanoSecondType mockClock()
std::chrono::nanoseconds mockClock()
{
return time_.tv_nsec += kTimeStep;
return time_ += kTimeStep;
}

/// @brief Increase the time by @c count mockClock() calls
timers::NanoSecondType mockClockSkip(int count)
std::chrono::nanoseconds mockClockSkip(int count)
{
return time_.tv_nsec += (kTimeStep * count);
return time_ += (kTimeStep * count);
}

/// @brief Get the current time plus an offset smaller than the tick size
[[nodiscard]]
timers::NanoSecondType mockClockOffset() const
std::chrono::nanoseconds mockClockOffset() const
{
return time_.tv_nsec + 50U;
return time_ + std::chrono::nanoseconds{50U};
}

/// @brief Get the time @c count mockClock() calls from now
[[nodiscard]]
timers::NanoSecondType mockClockFuture(int count) const
std::chrono::nanoseconds mockClockFuture(int count) const
{
return time_.tv_nsec + (kTimeStep * count);
return time_ + (kTimeStep * count);
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void ObservableEventReader::deregisterObservableEvent(const IdentifierHash f_pro
}
}

bool ObservableEventReader::distributeChanges(const timers::NanoSecondType f_syncTimestamp) noexcept
bool ObservableEventReader::distributeChanges(const std::chrono::nanoseconds f_syncTimestamp) noexcept
{
// If push update is pending from previous cycle, push data for last change observable event.
if (isPushPending)
Expand Down Expand Up @@ -123,7 +123,7 @@ score::Result<std::optional<SupervisionEvent>> ObservableEventReader::getNextSup

bool ObservableEventReader::pushUpdateTill(
const SupervisionEvent& f_event,
const timers::NanoSecondType f_syncTimestamp) noexcept
const std::chrono::nanoseconds f_syncTimestamp) noexcept
{
bool isSyncTimestampReached{false};

Expand All @@ -133,7 +133,7 @@ bool ObservableEventReader::pushUpdateTill(
processMapIterator->second->event.eventType = f_event.eventType;
processMapIterator->second->event.systemClockTimestamp = f_event.systemClockTimestamp;

timers::NanoSecondType changedProcessTimestamp{
std::chrono::nanoseconds changedProcessTimestamp{
timers::TimeConversion::convertToNanoSec(f_event.systemClockTimestamp)};

// If event occurred before synchronization timestamp, push data for current cycle.
Expand Down
Loading
Loading