summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam A. Kennington III <wak@google.com>2018-10-17 23:17:57 -0700
committerAndrew Geissler <geissonator@yahoo.com>2018-10-22 12:29:06 +0000
commitd998f82bda2f1f28f1a7a5db58025f1c575c5261 (patch)
tree68d78fc98c4b24c8ed63ca2595032606ec807fa2
parentf287059d29d5307309ff2a84f487b9f9b56b5160 (diff)
downloadphosphor-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.am12
-rw-r--r--chassis_state_manager.cpp60
-rw-r--r--chassis_state_manager.hpp24
-rw-r--r--configure.ac2
-rw-r--r--timer.cpp89
-rw-r--r--timer.hpp112
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
OpenPOWER on IntegriCloud