Enable an io-uring build
There exists a bug where calls that we previously thought were
non-blocking, actually do block when used with hwmon or filesystem fds.
This causes high latencies on the dbus interfaces when lots of sensors
are used in a single daemon, as is the case in PSUSensor.
This patchset moves the PSUSensor code over to using io-uring, through
boost asio, using the random_access_file class. This helps with
performance in a number of ways, the largest of which being that sensor
reads are no longer blocking.
Tested:
Booted the sensor system on Tyan S7106; dbus-monitor shows sensors
scanning normally.
Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: I654eafcfab5a24b65b89c204ab43d81c7ae064cf
diff --git a/src/PSUEvent.cpp b/src/PSUEvent.cpp
index d1cb40e..883c871 100644
--- a/src/PSUEvent.cpp
+++ b/src/PSUEvent.cpp
@@ -149,23 +149,17 @@
eventInterface(std::move(eventInterface)),
asserts(std::move(asserts)), combineEvent(std::move(combineEvent)),
assertState(std::move(state)), path(path), eventName(eventName),
- readState(powerState), waitTimer(io), inputDev(io), psuName(psuName),
- groupEventName(groupEventName), systemBus(conn)
+ readState(powerState), waitTimer(io),
+
+ inputDev(io, path, boost::asio::random_access_file::read_only),
+ psuName(psuName), groupEventName(groupEventName), systemBus(conn)
{
+ buffer = std::make_shared<std::array<char, 128>>();
if (pollRate > 0.0)
{
eventPollMs = static_cast<unsigned int>(pollRate * 1000);
}
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
- fd = open(path.c_str(), O_RDONLY);
- if (fd < 0)
- {
- std::cerr << "PSU sub event failed to open file\n";
- return;
- }
- inputDev.assign(fd);
-
auto found = logID.find(eventName);
if (found == logID.end())
{
@@ -205,19 +199,21 @@
restartRead();
return;
}
+ if (!buffer)
+ {
+ std::cerr << "Buffer was invalid?";
+ return;
+ }
- std::shared_ptr<boost::asio::streambuf> buffer =
- std::make_shared<boost::asio::streambuf>();
std::weak_ptr<PSUSubEvent> weakRef = weak_from_this();
- boost::asio::async_read_until(
- inputDev, *buffer, '\n',
- [weakRef, buffer](const boost::system::error_code& ec,
- std::size_t /*bytes_transfered*/) {
+ inputDev.async_read_some_at(
+ 0, boost::asio::buffer(buffer->data(), buffer->size() - 1),
+ [weakRef, buffer{buffer}](const boost::system::error_code& ec,
+ std::size_t bytesTransferred) {
std::shared_ptr<PSUSubEvent> self = weakRef.lock();
if (self)
{
- self->readBuf = buffer;
- self->handleResponse(ec);
+ self->handleResponse(ec, bytesTransferred);
}
});
}
@@ -239,23 +235,34 @@
});
}
-void PSUSubEvent::handleResponse(const boost::system::error_code& err)
+void PSUSubEvent::handleResponse(const boost::system::error_code& err,
+ size_t bytesTransferred)
{
+ if (err == boost::asio::error::operation_aborted)
+ {
+ return;
+ }
+
if ((err == boost::system::errc::bad_file_descriptor) ||
(err == boost::asio::error::misc_errors::not_found))
{
return;
}
- std::istream responseStream(readBuf.get());
+ if (!buffer)
+ {
+ std::cerr << "Buffer was invalid?";
+ return;
+ }
+ // null terminate the string so we don't walk off the end
+ std::array<char, 128>& bufferRef = *buffer;
+ bufferRef[bytesTransferred] = '\0';
+
if (!err)
{
std::string response;
try
{
- std::getline(responseStream, response);
- int nvalue = std::stoi(response);
- responseStream.clear();
-
+ int nvalue = std::stoi(bufferRef.data());
updateValue(nvalue);
errCount = 0;
}