Make Watchdog use single thread dispatch (#1347)

Notifier has one thread per instance because the callbacks must be
asynchronous. Watchdog callbacks can be synchronous, so this overhead
can be done away with via a scheduler thread akin to what the HAL
Notifier does.
This commit is contained in:
Tyler Veness
2018-12-01 00:05:33 -08:00
committed by Peter Johnson
parent 99033481e0
commit 3b33abfc7b
7 changed files with 730 additions and 67 deletions

View File

@@ -7,13 +7,14 @@
#pragma once
#include <chrono>
#include <functional>
#include <hal/cpp/fpga_clock.h>
#include <wpi/SafeThread.h>
#include <wpi/StringMap.h>
#include <wpi/StringRef.h>
#include "frc/Notifier.h"
namespace frc {
/**
@@ -30,19 +31,35 @@ class Watchdog {
/**
* Watchdog constructor.
*
* @param timeout The watchdog's timeout in seconds.
* @param timeout The watchdog's timeout in seconds with microsecond
* resolution.
* @param callback This function is called when the timeout expires.
*/
explicit Watchdog(double timeout, std::function<void()> callback = [] {});
Watchdog(double timeout, std::function<void()> callback);
~Watchdog();
Watchdog(Watchdog&&) = default;
Watchdog& operator=(Watchdog&&) = default;
/**
* Get the time in seconds since the watchdog was last fed.
* Returns the time in seconds since the watchdog was last fed.
*/
double GetTime() const;
/**
* Sets the watchdog's timeout.
*
* @param timeout The watchdog's timeout in seconds with microsecond
* resolution.
*/
void SetTimeout(double timeout);
/**
* Returns the watchdog's timeout in seconds.
*/
double GetTimeout() const;
/**
* Returns true if the watchdog timer has expired.
*/
@@ -76,20 +93,25 @@ class Watchdog {
void Enable();
/**
* Disable the watchdog.
* Disables the watchdog timer.
*/
void Disable();
private:
double m_timeout;
hal::fpga_clock::time_point m_startTime;
std::chrono::microseconds m_timeout;
hal::fpga_clock::time_point m_expirationTime;
std::function<void()> m_callback;
Notifier m_notifier;
double m_startTime = 0.0;
wpi::StringMap<double> m_epochs;
wpi::StringMap<std::chrono::microseconds> m_epochs;
bool m_isExpired = false;
void TimeoutFunc();
class Thread;
wpi::SafeThreadOwner<Thread>* m_owner;
bool operator>(const Watchdog& rhs);
static wpi::SafeThreadOwner<Thread>& GetThreadOwner();
};
} // namespace frc