Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Latency test with maximum stats and custom process evaluation #779

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
6036b30
Upintegrate changes from OpenMRNIDF.
balazsracz Jan 31, 2024
2591593
Fix compile error.
balazsracz Jan 31, 2024
04e9951
Remove deprecated hardware can driver.
balazsracz Jan 31, 2024
cc0f25e
Adds I2C driver written by Mike Dunston for the ESP32.
balazsracz Jan 31, 2024
57d5873
Adds refactored Adc Input class.
balazsracz Jan 31, 2024
91c419e
Fix compiler warnings in openmrn when using new GCC's.
balazsracz Jan 31, 2024
850c9ba
Merge branch 'master' into bracz-esp-compiler-warnings
balazsracz Feb 2, 2024
c506a65
Adds a debug print function to the stats object.
balazsracz Feb 2, 2024
af000a9
Adds maximum to the statistics object.
balazsracz Feb 2, 2024
2cbafa8
Adds a consumer object for event based testing.
balazsracz Feb 2, 2024
20435f9
Adds hook to the latency test consumer. This allows testing latency
balazsracz Feb 3, 2024
c5adf0c
Fix comments.
balazsracz Feb 4, 2024
c23a214
Merge branch 'master' into bracz-idf-downintegrate
balazsracz Feb 4, 2024
358f146
Merge branch 'bracz-idf-downintegrate' into bracz-esp-compiler-warnings
balazsracz Feb 4, 2024
6cbc79d
Fix comment.
balazsracz Feb 5, 2024
7898dd3
Merge branch 'master' of github.com:bakerstu/openmrn into bracz-esp-c…
balazsracz Feb 5, 2024
7cc73c8
Merge branch 'bracz-esp-compiler-warnings' into bracz-tmp-compile-fix…
balazsracz Feb 5, 2024
0be1c81
Merge branch 'bracz-tmp-compile-fix-merge' into bracz-stat-max
balazsracz Feb 5, 2024
23899a0
Adds documentation comment to latency test consumer.
balazsracz Feb 5, 2024
8d89bbe
Fix comment.
balazsracz Feb 5, 2024
98b935d
Fixes data type of max.
balazsracz Feb 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions applications/hub_test/targets/linux.x86/main.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,7 @@ class Receiver : public CanHubPortInterface
numFrames_ = numUnknownFrames_ = numInOrder_ = numOutOfOrder_ =
numMissed_ = 0;

ret += StringPrintf("|RTT %.1f msec +- %.1f\n",
rttUsec_.favg()/1000, rttUsec_.stddev() / 1000);
ret += StringPrintf("|RTT %s\n", rttUsec_.debug_string().c_str());

rttUsec_.clear();
return ret;
Expand Down
133 changes: 133 additions & 0 deletions src/openlcb/LatencyTestConsumer.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/** \copyright
* Copyright (c) 2024, Balazs Racz
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \file LatencyTestConsumer.hxx
*
* Utility class for determining the response latency of a node.
*
* @author Balazs Racz
* @date 2 Feb 2024
*/

#ifndef _OPENLCB_LATENCYTESTCONSUMER_HXX_
#define _OPENLCB_LATENCYTESTCONSUMER_HXX_

#include "openlcb/EventHandlerTemplates.hxx"

namespace openlcb
{

/// This event consumer works together with the hub_test application in order
/// to detect the response latency of a node. The theory of operation is that
/// hub_test sends out an identify consumer message with a given event ID, and
/// this consumer is going to respond. The hub_test then measures the response
/// latency. There is a big event range being advertised (32 bits), and
/// hub_test will send events with different IDs to be able to match request to
/// response.
///
/// Here in the consumer the only thing we need to do is respond to identify
/// consumer messages with consumer identified.
///
/// An additional feature is to be able to measure an arbitrary processing step
/// inside the node. For this purpose we have a hook function. When the
/// identify producer message comes in, we call the hook. When the measured
/// process completes, it should notify the given notifiable. Only thereafter
/// the consumer will reply on the bus. Requests' handling is not
/// parallelized. If the hook process cannot complete the requests fast enough,
/// the node will run out of memory and crash.
class LatencyTestConsumer : public SimpleEventHandler
{
public:
/// To complete the hook, call the notifiable.
using HookFn = std::function<void(Notifiable *)>;

LatencyTestConsumer(Node *node, HookFn hook = nullptr)
: node_(node)
, hook_(hook)
{
EventRegistry::instance()->register_handler(
EventRegistryEntry(this, EVENT_BASE), 32);
}

void handle_identify_global(const EventRegistryEntry &registry_entry,
EventReport *event, BarrierNotifiable *done) override
{
AutoNotify an(done);
if (event->dst_node && event->dst_node != node_)
{
return;
}
event->event_write_helper<1>()->WriteAsync(node_,
Defs::MTI_CONSUMER_IDENTIFIED_RANGE, WriteHelper::global(),
eventid_to_buffer(EncodeRange(EVENT_BASE, 0xffffffff)),
done->new_child());
}

void handle_identify_consumer(const EventRegistryEntry &entry,
EventReport *event, BarrierNotifiable *done) override
{
event_ = event;
done_ = done;
if (hook_)
{
hook_(new TempNotifiable([this]() { reply(); }));
}
else
{
reply();
}
}

private:
void reply()
{
AutoNotify an(done_);
event_->event_write_helper<1>()->WriteAsync(node_,
Defs::MTI_CONSUMER_IDENTIFIED_UNKNOWN, WriteHelper::global(),
eventid_to_buffer(event_->event), done_->new_child());
}

/// This is within NMRA ID 1, which is not assigned. Lower four bytes are
/// the id.
static constexpr EventId EVENT_BASE = 0x0900013900000000;

/// Which node should be sending responses.
Node *node_;

/// The owner's hook will be invoked and run (asynchronous) before
/// replying..
HookFn hook_;

/// Incoming event report we are working on.
EventReport *event_;

/// Will notify this after sending the reply.
BarrierNotifiable *done_ {nullptr};
};

} // namespace openlcb

#endif // _OPENLCB_LATENCYTESTCONSUMER_HXX_
43 changes: 43 additions & 0 deletions src/utils/Stats.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/** \copyright
* Copyright (c) 2023, Balazs Racz
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \file Stats.hxx
*
* Utility class for collecting statistics.
*
* @author Balazs Racz
* @date 28 Dec 2023
*/

#include "utils/Stats.hxx"

#include "utils/StringPrintf.hxx"

std::string Stats::debug_string()
{
return StringPrintf("%.1f msec +- %.1f, max %.1f\n", favg() / 1000,
stddev() / 1000, ((FloatType)max_) / 1000);
}
15 changes: 14 additions & 1 deletion src/utils/Stats.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,14 @@

#include <math.h>
#include <stdint.h>
#include <string>
#include <limits>

class Stats
{
public:
using FloatType = double;
using ValueType = int32_t;

Stats()
{
Expand All @@ -54,16 +57,21 @@ public:
sum_ = 0;
count_ = 0;
qsum_ = 0;
max_ = std::numeric_limits<ValueType>::min();
}

/// Appends a data point to the statistics.
/// @param value the data point.
void add(int32_t value)
void add(ValueType value)
{
++count_;
sum_ += value;
FloatType fval = value;
qsum_ += fval * fval;
if (value > max_)
{
max_ = value;
}
}

/// @return the average
Expand All @@ -86,9 +94,14 @@ public:
return sqrt(qsum_ * count_ - sum * sum) / count_;
}

/// Creates a half-a-line printout of this stats object for debug purposes.
std::string debug_string();

private:
/// Number of samples added.
uint32_t count_;
/// Maximum value found since the last clear.
ValueType max_;
/// Sum of sample values added.
int64_t sum_;
/// Sum of squares of sample values added.
Expand Down
1 change: 1 addition & 0 deletions src/utils/sources
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ CXXSRCS += \
Queue.cxx \
ReflashBootloader.cxx \
ServiceLocator.cxx \
Stats.cxx \
SocketCan.cxx \
SocketClient.cxx \
constants.cxx \
Expand Down