px4_work_queue: minor status changes

- only record start time on first run rather than init
 - increase name length
 - round average interval to nearest microsecond
 - basic formatting consistency (google style guide)
This commit is contained in:
Daniel Agar
2020-05-23 11:51:23 -04:00
parent dd9c82eb20
commit 8ee0a5d328
6 changed files with 49 additions and 67 deletions
@@ -39,7 +39,7 @@
#include <containers/IntrusiveQueue.hpp> #include <containers/IntrusiveQueue.hpp>
#include <px4_platform_common/defines.h> #include <px4_platform_common/defines.h>
#include <drivers/drv_hrt.h> #include <drivers/drv_hrt.h>
#include <lib/mathlib/mathlib.h>
#include <lib/perf/perf_counter.h> #include <lib/perf/perf_counter.h>
namespace px4 namespace px4
@@ -91,7 +91,14 @@ protected:
void ScheduleClear(); void ScheduleClear();
protected: protected:
void RunPreamble() { _run_count++; } void RunPreamble()
{
_run_count++;
if (_time_first_run == 0) {
_time_first_run = hrt_absolute_time();
}
}
friend void WorkQueue::Run(); friend void WorkQueue::Run();
virtual void Run() = 0; virtual void Run() = 0;
@@ -111,10 +118,9 @@ protected:
float average_rate() const; float average_rate() const;
float average_interval() const; float average_interval() const;
hrt_abstime _time_first_run{0};
hrt_abstime _start_time{0};
unsigned _run_count{0};
const char *_item_name; const char *_item_name;
uint32_t _run_count{0};
private: private:
@@ -76,7 +76,7 @@ private:
bool should_exit() const { return _should_exit.load(); } bool should_exit() const { return _should_exit.load(); }
inline void signal_worker_thread(); inline void SignalWorkerThread();
#ifdef __PX4_NUTTX #ifdef __PX4_NUTTX
// In NuttX work can be enqueued from an ISR // In NuttX work can be enqueued from an ISR
@@ -41,41 +41,33 @@ ScheduledWorkItem::~ScheduledWorkItem()
ScheduleClear(); ScheduleClear();
} }
void void ScheduledWorkItem::schedule_trampoline(void *arg)
ScheduledWorkItem::schedule_trampoline(void *arg)
{ {
ScheduledWorkItem *dev = static_cast<ScheduledWorkItem *>(arg); ScheduledWorkItem *dev = static_cast<ScheduledWorkItem *>(arg);
dev->ScheduleNow(); dev->ScheduleNow();
} }
void void ScheduledWorkItem::ScheduleDelayed(uint32_t delay_us)
ScheduledWorkItem::ScheduleDelayed(uint32_t delay_us)
{ {
hrt_call_after(&_call, delay_us, (hrt_callout)&ScheduledWorkItem::schedule_trampoline, this); hrt_call_after(&_call, delay_us, (hrt_callout)&ScheduledWorkItem::schedule_trampoline, this);
} }
void void ScheduledWorkItem::ScheduleOnInterval(uint32_t interval_us, uint32_t delay_us)
ScheduledWorkItem::ScheduleOnInterval(uint32_t interval_us, uint32_t delay_us)
{ {
// reset start time to first deadline (approximately)
_start_time = hrt_absolute_time() + interval_us + delay_us;
hrt_call_every(&_call, delay_us, interval_us, (hrt_callout)&ScheduledWorkItem::schedule_trampoline, this); hrt_call_every(&_call, delay_us, interval_us, (hrt_callout)&ScheduledWorkItem::schedule_trampoline, this);
} }
void void ScheduledWorkItem::ScheduleClear()
ScheduledWorkItem::ScheduleClear()
{ {
// first clear any scheduled hrt call, then remove the item from the runnable queue // first clear any scheduled hrt call, then remove the item from the runnable queue
hrt_cancel(&_call); hrt_cancel(&_call);
WorkItem::ScheduleClear(); WorkItem::ScheduleClear();
} }
void void ScheduledWorkItem::print_run_status() const
ScheduledWorkItem::print_run_status() const
{ {
if (_call.period > 0) { if (_call.period > 0) {
PX4_INFO_RAW("%-24s %8.1f Hz %12.1f us (%" PRId64 " us)\n", _item_name, (double)average_rate(), PX4_INFO_RAW("%-26s %8.1f Hz %12.0f us (%" PRId64 " us)\n", _item_name, (double)average_rate(),
(double)average_interval(), _call.period); (double)average_interval(), _call.period);
} else { } else {
+16 -24
View File
@@ -57,7 +57,6 @@ WorkItem::WorkItem(const char *name, const WorkItem &work_item) :
if ((wq != nullptr) && wq->Attach(this)) { if ((wq != nullptr) && wq->Attach(this)) {
_wq = wq; _wq = wq;
_start_time = hrt_absolute_time();
} }
} }
@@ -66,8 +65,7 @@ WorkItem::~WorkItem()
Deinit(); Deinit();
} }
bool bool WorkItem::Init(const wq_config_t &config)
WorkItem::Init(const wq_config_t &config)
{ {
// clear any existing first // clear any existing first
Deinit(); Deinit();
@@ -76,7 +74,7 @@ WorkItem::Init(const wq_config_t &config)
if ((wq != nullptr) && wq->Attach(this)) { if ((wq != nullptr) && wq->Attach(this)) {
_wq = wq; _wq = wq;
_start_time = hrt_absolute_time(); _time_first_run = 0;
return true; return true;
} }
@@ -84,8 +82,7 @@ WorkItem::Init(const wq_config_t &config)
return false; return false;
} }
void void WorkItem::Deinit()
WorkItem::Deinit()
{ {
// remove any currently queued work // remove any currently queued work
if (_wq != nullptr) { if (_wq != nullptr) {
@@ -100,49 +97,44 @@ WorkItem::Deinit()
} }
} }
void void WorkItem::ScheduleClear()
WorkItem::ScheduleClear()
{ {
if (_wq != nullptr) { if (_wq != nullptr) {
_wq->Remove(this); _wq->Remove(this);
} }
} }
float float WorkItem::elapsed_time() const
WorkItem::elapsed_time() const
{ {
return hrt_elapsed_time(&_start_time) / 1e6f; return hrt_elapsed_time(&_time_first_run) / 1e6f;
} }
float float WorkItem::average_rate() const
WorkItem::average_rate() const
{ {
const float rate = _run_count / elapsed_time(); const float rate = _run_count / elapsed_time();
if ((_run_count > 0) && PX4_ISFINITE(rate)) { if ((_run_count > 1) && PX4_ISFINITE(rate)) {
return rate; return rate;
} }
return 0.0f; return 0.f;
} }
float float WorkItem::average_interval() const
WorkItem::average_interval() const
{ {
const float rate = average_rate(); const float rate = average_rate();
const float interval = 1000000.0f / rate; const float interval = 1e6f / rate;
if ((rate > 0.0f) && PX4_ISFINITE(interval)) { if ((rate > FLT_EPSILON) && PX4_ISFINITE(interval)) {
return interval; return roundf(interval);
} }
return 0.0f; return 0.f;
} }
void void WorkItem::print_run_status() const
WorkItem::print_run_status() const
{ {
PX4_INFO_RAW("%-24s %8.1f Hz %12.1f us\n", _item_name, (double)average_rate(), (double)average_interval()); PX4_INFO_RAW("%-26s %8.1f Hz %12.0f us\n", _item_name, (double)average_rate(), (double)average_interval());
} }
} // namespace px4 } // namespace px4
+13 -21
View File
@@ -72,8 +72,7 @@ WorkQueue::~WorkQueue()
#endif /* __PX4_NUTTX */ #endif /* __PX4_NUTTX */
} }
bool bool WorkQueue::Attach(WorkItem *item)
WorkQueue::Attach(WorkItem *item)
{ {
work_lock(); work_lock();
@@ -87,8 +86,7 @@ WorkQueue::Attach(WorkItem *item)
return false; return false;
} }
void void WorkQueue::Detach(WorkItem *item)
WorkQueue::Detach(WorkItem *item)
{ {
work_lock(); work_lock();
@@ -99,24 +97,22 @@ WorkQueue::Detach(WorkItem *item)
PX4_DEBUG("stopping: %s, last active WorkItem closing", _config.name); PX4_DEBUG("stopping: %s, last active WorkItem closing", _config.name);
request_stop(); request_stop();
signal_worker_thread(); SignalWorkerThread();
} }
work_unlock(); work_unlock();
} }
void void WorkQueue::Add(WorkItem *item)
WorkQueue::Add(WorkItem *item)
{ {
work_lock(); work_lock();
_q.push(item); _q.push(item);
work_unlock(); work_unlock();
signal_worker_thread(); SignalWorkerThread();
} }
void void WorkQueue::SignalWorkerThread()
WorkQueue::signal_worker_thread()
{ {
int sem_val; int sem_val;
@@ -125,16 +121,14 @@ WorkQueue::signal_worker_thread()
} }
} }
void void WorkQueue::Remove(WorkItem *item)
WorkQueue::Remove(WorkItem *item)
{ {
work_lock(); work_lock();
_q.remove(item); _q.remove(item);
work_unlock(); work_unlock();
} }
void void WorkQueue::Clear()
WorkQueue::Clear()
{ {
work_lock(); work_lock();
@@ -145,8 +139,7 @@ WorkQueue::Clear()
work_unlock(); work_unlock();
} }
void void WorkQueue::Run()
WorkQueue::Run()
{ {
while (!should_exit()) { while (!should_exit()) {
// loop as the wait may be interrupted by a signal // loop as the wait may be interrupted by a signal
@@ -171,12 +164,11 @@ WorkQueue::Run()
PX4_DEBUG("%s: exiting", _config.name); PX4_DEBUG("%s: exiting", _config.name);
} }
void void WorkQueue::print_status(bool last)
WorkQueue::print_status(bool last)
{ {
const size_t num_items = _work_items.size(); const size_t num_items = _work_items.size();
PX4_INFO_RAW("%-16s\n", get_name()); PX4_INFO_RAW("%-16s\n", get_name());
size_t i = 0; unsigned i = 0;
for (WorkItem *item : _work_items) { for (WorkItem *item : _work_items) {
i++; i++;
@@ -189,10 +181,10 @@ WorkQueue::print_status(bool last)
} }
if (i < num_items) { if (i < num_items) {
PX4_INFO_RAW("|__ %zu) ", i); PX4_INFO_RAW("|__%2d) ", i);
} else { } else {
PX4_INFO_RAW("\\__ %zu) ", i); PX4_INFO_RAW("\\__%2d) ", i);
} }
item->print_run_status(); item->print_run_status();
@@ -390,7 +390,7 @@ WorkQueueManagerStatus()
if (!_wq_manager_should_exit.load() && (_wq_manager_wqs_list != nullptr)) { if (!_wq_manager_should_exit.load() && (_wq_manager_wqs_list != nullptr)) {
const size_t num_wqs = _wq_manager_wqs_list->size(); const size_t num_wqs = _wq_manager_wqs_list->size();
PX4_INFO_RAW("\nWork Queue: %-1zu threads RATE INTERVAL\n", num_wqs); PX4_INFO_RAW("\nWork Queue: %-1zu threads RATE INTERVAL\n", num_wqs);
LockGuard lg{_wq_manager_wqs_list->mutex()}; LockGuard lg{_wq_manager_wqs_list->mutex()};
size_t i = 0; size_t i = 0;
@@ -398,7 +398,7 @@ WorkQueueManagerStatus()
for (WorkQueue *wq : *_wq_manager_wqs_list) { for (WorkQueue *wq : *_wq_manager_wqs_list) {
i++; i++;
const bool last_wq = !(i < num_wqs); const bool last_wq = (i >= num_wqs);
if (!last_wq) { if (!last_wq) {
PX4_INFO_RAW("|__ %zu) ", i); PX4_INFO_RAW("|__ %zu) ", i);