diff options
author | William A. Kennington III <wak@google.com> | 2018-10-17 23:17:57 -0700 |
---|---|---|
committer | Andrew Geissler <geissonator@yahoo.com> | 2018-10-22 12:29:06 +0000 |
commit | d998f82bda2f1f28f1a7a5db58025f1c575c5261 (patch) | |
tree | 68d78fc98c4b24c8ed63ca2595032606ec807fa2 | |
parent | f287059d29d5307309ff2a84f487b9f9b56b5160 (diff) | |
download | phosphor-state-manager-d998f82bda2f1f28f1a7a5db58025f1c575c5261.tar.gz phosphor-state-manager-d998f82bda2f1f28f1a7a5db58025f1c575c5261.zip |
timer: Replace with sdeventplus/timer
This is aimed at replacing the ad-hoc timer implementation contained in
each of our openbmc daemons, with a single well-tested timer
implementation.
Tested:
Compiled
Change-Id: I3e562ab72820442aa137a2d517e476192ea6c1bd
Signed-off-by: William A. Kennington III <wak@google.com>
-rw-r--r-- | Makefile.am | 12 | ||||
-rw-r--r-- | chassis_state_manager.cpp | 60 | ||||
-rw-r--r-- | chassis_state_manager.hpp | 24 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | timer.cpp | 89 | ||||
-rw-r--r-- | timer.hpp | 112 |
6 files changed, 41 insertions, 258 deletions
diff --git a/Makefile.am b/Makefile.am index 5aff810..dfbd2cf 100644 --- a/Makefile.am +++ b/Makefile.am @@ -14,8 +14,7 @@ phosphor_host_state_manager_SOURCES = \ phosphor_chassis_state_manager_SOURCES = \ chassis_state_manager.cpp \ - chassis_state_manager_main.cpp \ - timer.cpp + chassis_state_manager_main.cpp phosphor_bmc_state_manager_SOURCES = \ bmc_state_manager.cpp \ @@ -43,8 +42,13 @@ generic_ldflags = \ phosphor_host_state_manager_CXXFLAGS = $(generic_cxxflags) phosphor_host_state_manager_LDFLAGS = $(generic_ldflags) -lstdc++fs -phosphor_chassis_state_manager_CXXFLAGS = $(generic_cxxflags) -phosphor_chassis_state_manager_LDFLAGS = $(generic_ldflags) -lstdc++fs +phosphor_chassis_state_manager_CXXFLAGS = \ + $(generic_cxxflags) \ + $(SDEVENTPLUS_CFLAGS) +phosphor_chassis_state_manager_LDFLAGS = \ + $(generic_ldflags) \ + $(SDEVENTPLUS_LIBS) \ + -lstdc++fs phosphor_bmc_state_manager_CXXFLAGS = $(generic_cxxflags) phosphor_bmc_state_manager_LDFLAGS = $(generic_ldflags) diff --git a/chassis_state_manager.cpp b/chassis_state_manager.cpp index 4e8e1e7..d721460 100644 --- a/chassis_state_manager.cpp +++ b/chassis_state_manager.cpp @@ -1,5 +1,7 @@ #include <sdbusplus/bus.hpp> #include <sdbusplus/exception.hpp> +#include <sdeventplus/event.hpp> +#include <sdeventplus/exception.hpp> #include <phosphor-logging/log.hpp> #include <phosphor-logging/elog-errors.hpp> #include "xyz/openbmc_project/Common/error.hpp" @@ -21,6 +23,7 @@ namespace server = sdbusplus::xyz::openbmc_project::State::server; using namespace phosphor::logging; using sdbusplus::exception::SdBusError; +using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; constexpr auto CHASSIS_STATE_POWEROFF_TGT = "obmc-chassis-poweroff@0.target"; constexpr auto CHASSIS_STATE_HARD_POWEROFF_TGT = @@ -268,14 +271,7 @@ Chassis::PowerState Chassis::currentPowerState(PowerState value) convertForMessage(value).c_str())); chassisPowerState = server::Chassis::currentPowerState(value); - if (chassisPowerState == PowerState::On) - { - timer->state(timer::ON); - } - else - { - timer->state(timer::OFF); - } + pOHTimer.setEnabled(chassisPowerState == PowerState::On); return chassisPowerState; } @@ -289,6 +285,14 @@ uint32_t Chassis::pOHCounter(uint32_t value) return pOHCounter(); } +void Chassis::pOHCallback() +{ + if (ChassisInherit::currentPowerState() == PowerState::On) + { + pOHCounter(pOHCounter() + 1); + } +} + void Chassis::restorePOHCounter() { uint32_t counter; @@ -340,47 +344,19 @@ bool Chassis::deserializePOH(const fs::path& path, uint32_t& pOHCounter) void Chassis::startPOHCounter() { - using namespace std::chrono_literals; - using namespace phosphor::logging; - using namespace sdbusplus::xyz::openbmc_project::Common::Error; - auto dir = fs::path(POH_COUNTER_PERSIST_PATH).parent_path(); fs::create_directories(dir); - sd_event* event = nullptr; - auto r = sd_event_default(&event); - if (r < 0) - { - log<level::ERR>("Error creating a default sd_event handler"); - throw; - } - - phosphor::state::manager::EventPtr eventP{event}; - event = nullptr; - - auto callback = [&]() { - if (ChassisInherit::currentPowerState() == PowerState::On) - { - pOHCounter(pOHCounter() + 1); - } - }; - try { - timer = std::make_unique<phosphor::state::manager::Timer>( - eventP, callback, std::chrono::seconds(POH::hour), - phosphor::state::manager::timer::ON); - bus.attach_event(eventP.get(), SD_EVENT_PRIORITY_NORMAL); - r = sd_event_loop(eventP.get()); - if (r < 0) - { - log<level::ERR>("Error occurred during the sd_event_loop", - entry("RC=%d", r)); - elog<InternalFailure>(); - } + auto event = sdeventplus::Event::get_default(); + bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL); + event.loop(); } - catch (InternalFailure& e) + catch (const sdeventplus::SdEventError& e) { + log<level::ERR>("Error occurred during the sdeventplus loop", + entry("ERROR=%s", e.what())); phosphor::logging::commit<InternalFailure>(); } } diff --git a/chassis_state_manager.hpp b/chassis_state_manager.hpp index 9a6b647..4780e0f 100644 --- a/chassis_state_manager.hpp +++ b/chassis_state_manager.hpp @@ -1,13 +1,16 @@ #pragma once +#include <chrono> #include <functional> #include <experimental/filesystem> #include <cereal/cereal.hpp> #include <sdbusplus/bus.hpp> +#include <sdeventplus/clock.hpp> +#include <sdeventplus/event.hpp> +#include <sdeventplus/utility/timer.hpp> #include "xyz/openbmc_project/State/Chassis/server.hpp" #include "xyz/openbmc_project/State/PowerOnHours/server.hpp" #include "config.h" -#include "timer.hpp" namespace phosphor { @@ -15,13 +18,6 @@ namespace state { namespace manager { -namespace POH -{ - -using namespace std::chrono_literals; -constexpr auto hour = 3600s; // seconds Per Hour - -} // namespace POH using ChassisInherit = sdbusplus::server::object::object< sdbusplus::xyz::openbmc_project::State::server::Chassis, @@ -57,7 +53,10 @@ class Chassis : public ChassisInherit sdbusRule::path("/org/freedesktop/systemd1") + sdbusRule::interface("org.freedesktop.systemd1.Manager"), std::bind(std::mem_fn(&Chassis::sysStateChange), this, - std::placeholders::_1)) + std::placeholders::_1)), + pOHTimer(sdeventplus::Event::get_default(), + std::bind(&Chassis::pOHCallback, this), std::chrono::hours{1}, + std::chrono::minutes{1}) { subscribeToSystemdSignals(); @@ -136,6 +135,9 @@ class Chassis : public ChassisInherit /** @brief Used to Set value of POHCounter */ uint32_t pOHCounter(uint32_t value) override; + /** @brief Used by the timer to update the POHCounter */ + void pOHCallback(); + /** @brief Used to restore POHCounter value from persisted file */ void restorePOHCounter(); @@ -188,8 +190,8 @@ class Chassis : public ChassisInherit */ void restoreChassisStateChangeTime(); - /** @brief Timer */ - std::unique_ptr<phosphor::state::manager::Timer> timer; + /** @brief Timer used for tracking power on hours */ + sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> pOHTimer; }; } // namespace manager diff --git a/configure.ac b/configure.ac index bd3ecac..e985a95 100644 --- a/configure.ac +++ b/configure.ac @@ -16,6 +16,8 @@ PKG_CHECK_MODULES([PHOSPHOR_DBUS_INTERFACES], [phosphor-dbus-interfaces],,\ AC_MSG_ERROR(["Requires phosphor-dbus-interfaces package."])) PKG_CHECK_MODULES([SDBUSPLUS], [sdbusplus],, AC_MSG_ERROR(["Requires sdbusplus package."])) +PKG_CHECK_MODULES([SDEVENTPLUS], [sdeventplus],, + AC_MSG_ERROR(["Requires sdeventplus package."])) PKG_CHECK_MODULES([PHOSPHOR_LOGGING], [phosphor-logging],,\ AC_MSG_ERROR(["Requires phosphor-logging package."])) diff --git a/timer.cpp b/timer.cpp deleted file mode 100644 index ceb4c29..0000000 --- a/timer.cpp +++ /dev/null @@ -1,89 +0,0 @@ -#include <chrono> -#include <system_error> -#include <string.h> -#include "timer.hpp" - -namespace phosphor -{ -namespace state -{ -namespace manager -{ -static std::chrono::microseconds getTime() -{ - using namespace std::chrono; - auto usec = steady_clock::now().time_since_epoch(); - return duration_cast<microseconds>(usec); -} - -int Timer::state(timer::Action value) -{ - action_ = value; - return sd_event_source_set_enabled(eventSource_.get(), action_); -} - -timer::Action Timer::getAction() const -{ - return action_; -} - -std::chrono::microseconds Timer::getDuration() const -{ - return duration_; -} - -Timer::Timer(EventPtr& event, std::function<void()> callback, - std::chrono::microseconds usec, timer::Action action) : - event_(event), - callback_(callback), duration_(usec), action_(action) -{ - // Add infinite expiration time - sd_event_source* sourcePtr = nullptr; - - auto r = sd_event_add_time(event_.get(), &sourcePtr, - CLOCK_MONOTONIC, // Time base - (getTime() + usec).count(), // When to fire - 0, // Use default event accuracy - timeoutHandler, // Callback handler on timeout - this); // User data - - if (r < 0) - { - throw std::system_error(r, std::generic_category(), strerror(-r)); - } - - eventSource_.reset(sourcePtr); -} - -int Timer::timeoutHandler(sd_event_source* eventSrc, uint64_t usec, - void* userData) -{ - auto timer = static_cast<Timer*>(userData); - - if (timer->getAction() == timer::ON) - { - auto r = sd_event_source_set_time( - eventSrc, (getTime() + timer->getDuration()).count()); - if (r < 0) - { - throw std::system_error(r, std::generic_category(), strerror(-r)); - } - - r = sd_event_source_set_enabled(eventSrc, timer::ON); - if (r < 0) - { - throw std::system_error(r, std::generic_category(), strerror(-r)); - } - } - - if (timer->callback_) - { - timer->callback_(); - } - - return 0; -} - -} // namespace manager -} // namespace state -} // namespace phosphor diff --git a/timer.hpp b/timer.hpp deleted file mode 100644 index f5f9ada..0000000 --- a/timer.hpp +++ /dev/null @@ -1,112 +0,0 @@ -#pragma once - -#include <memory> -#include <chrono> -#include <functional> -#include <systemd/sd-event.h> - -namespace phosphor -{ -namespace state -{ -namespace manager -{ -namespace timer -{ - -enum Action -{ - OFF = SD_EVENT_OFF, - ON = SD_EVENT_ON, - ONESHOT = SD_EVENT_ONESHOT -}; -} // namespace timer - -/* Need a custom deleter for freeing up sd_event */ -struct EventDeleter -{ - void operator()(sd_event* event) const - { - event = sd_event_unref(event); - } -}; -using EventPtr = std::unique_ptr<sd_event, EventDeleter>; - -/* Need a custom deleter for freeing up sd_event_source */ -struct EventSourceDeleter -{ - void operator()(sd_event_source* eventSource) const - { - eventSource = sd_event_source_unref(eventSource); - } -}; -using EventSourcePtr = std::unique_ptr<sd_event_source, EventSourceDeleter>; - -/** @class Timer - * @brief Provides a timer source and a mechanism to callback when the timer - * expires. - * - * The timer is armed upon construction. The constructor requires a timeout - * handler function, the timer expiry duration, and the timer state (one-shot, - * reptitive, disabled). - * It's possible to change the state of the timer after it's been armed via the - * state() API. - */ -class Timer -{ - public: - Timer() = delete; - Timer(const Timer&) = delete; - Timer& operator=(const Timer&) = delete; - Timer(Timer&&) = delete; - Timer& operator=(Timer&&) = delete; - - /** @brief Constructs timer object - * - * @param[in] events - sd_event pointer - * @param[in] callback - function callback for timer expiry - * @param[in] usec - timer duration, in micro seconds - * @param[in] action - controls the timer's lifetime - */ - Timer(EventPtr& event, std::function<void()> userCallback, - std::chrono::microseconds usec, timer::Action action); - - /** @brief Enables / disables the timer - * @param[in] action - controls the timer's lifetime - */ - int state(timer::Action value); - - timer::Action getAction() const; - - std::chrono::microseconds getDuration() const; - - private: - /** @brief Reference to sd_event unique pointer */ - EventPtr& event_; - - /** @brief Source of events */ - EventSourcePtr eventSource_; - - /** @brief Optional function to call on timer expiration */ - std::function<void()> callback_{}; - - /** @brief Duration of the timer */ - std::chrono::microseconds duration_{}; - - /** @brief whether the timer is enabled/disabled/one-shot */ - timer::Action action_ = timer::OFF; - - /** @brief Timer expiry handler - invokes callback - * - * @param[in] eventSource - Source of the event - * @param[in] usec - time in micro seconds - * @param[in] userData - User data pointer - * - * @return zero on success, non-zero otherwise - */ - static int timeoutHandler(sd_event_source* eventSource, uint64_t usec, - void* userData); -}; -} // namespace manager -} // namespace state -} // namespace phosphor |