Add PerformanceLoss threshold checking

This xyz.openbmc_project.Sensor.Threshold.PerformanceLoss interface will
be checked along with the other threshold interfaces.  It can be used to
indicate the system will suffer a performance loss when the sensor goes
above/below the high/low threshold values.

Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I855aaf6ea550e672bf52af5631533049269934d1
diff --git a/thresholds.hpp b/thresholds.hpp
index e53e496..b01d86d 100644
--- a/thresholds.hpp
+++ b/thresholds.hpp
@@ -2,6 +2,7 @@
 
 #include <xyz/openbmc_project/Sensor/Threshold/Critical/server.hpp>
 #include <xyz/openbmc_project/Sensor/Threshold/HardShutdown/server.hpp>
+#include <xyz/openbmc_project/Sensor/Threshold/PerformanceLoss/server.hpp>
 #include <xyz/openbmc_project/Sensor/Threshold/SoftShutdown/server.hpp>
 #include <xyz/openbmc_project/Sensor/Threshold/Warning/server.hpp>
 
@@ -17,6 +18,7 @@
 using WarningObject = ServerObject<threshold_ns::Warning>;
 using SoftShutdownObject = ServerObject<threshold_ns::SoftShutdown>;
 using HardShutdownObject = ServerObject<threshold_ns::HardShutdown>;
+using PerformanceLossObject = ServerObject<threshold_ns::PerformanceLoss>;
 
 template <typename T>
 struct Threshold;
@@ -133,4 +135,32 @@
     }
 };
 
+template <>
+struct Threshold<PerformanceLossObject> : public PerformanceLossObject
+{
+    static constexpr auto name = "PerformanceLoss";
+    using PerformanceLossObject::PerformanceLossObject;
+
+    auto high()
+    {
+        return performanceLossHigh();
+    }
+    auto low()
+    {
+        return performanceLossLow();
+    }
+
+    template <typename... Args>
+    auto alarmHigh(Args... args)
+    {
+        return performanceLossAlarmHigh(std::forward<Args>(args)...);
+    }
+
+    template <typename... Args>
+    auto alarmLow(Args... args)
+    {
+        return performanceLossAlarmLow(std::forward<Args>(args)...);
+    }
+};
+
 } // namespace phosphor::virtualSensor
diff --git a/virtualSensor.cpp b/virtualSensor.cpp
index a67077b..b74f0d3 100644
--- a/virtualSensor.cpp
+++ b/virtualSensor.cpp
@@ -132,6 +132,20 @@
             softShutdownIface->softShutdownLow(threshold.value(
                 "SoftShutdownLow", std::numeric_limits<double>::quiet_NaN()));
         }
+
+        if (threshold.contains("PerformanceLossHigh") ||
+            threshold.contains("PerformanceLossLow"))
+        {
+            perfLossIface = std::make_unique<Threshold<PerformanceLossObject>>(
+                bus, objPath.c_str());
+
+            perfLossIface->performanceLossHigh(
+                threshold.value("PerformanceLossHigh",
+                                std::numeric_limits<double>::quiet_NaN()));
+            perfLossIface->performanceLossLow(
+                threshold.value("PerformanceLossLow",
+                                std::numeric_limits<double>::quiet_NaN()));
+        }
     }
 
     /* Get expression string */
@@ -248,6 +262,7 @@
         std::cout << "Sensor value is " << val << "\n";
 
     /* Check sensor thresholds and log required message */
+    checkThresholds(val, perfLossIface);
     checkThresholds(val, warningIface);
     checkThresholds(val, criticalIface);
     checkThresholds(val, softShutdownIface);
diff --git a/virtualSensor.hpp b/virtualSensor.hpp
index 4553024..ba802db 100644
--- a/virtualSensor.hpp
+++ b/virtualSensor.hpp
@@ -115,6 +115,8 @@
     std::unique_ptr<Threshold<SoftShutdownObject>> softShutdownIface;
     /** @brief The hard shutdown threshold interface object */
     std::unique_ptr<Threshold<HardShutdownObject>> hardShutdownIface;
+    /** @brief The performance loss threshold interface object */
+    std::unique_ptr<Threshold<PerformanceLossObject>> perfLossIface;
 
     /** @brief Read config from json object and initialize sensor data
      * for each virtual sensor