From 2ded13f1959376644a3fb9dfa3438c2ca104bd33 Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Wed, 31 May 2023 15:55:59 +0200 Subject: [PATCH] fix: Reduce heap allocations by getting rid of temporary std::list and std::string --- .../cxx_include/esp_modem_command_library.hpp | 6 ++-- .../esp_modem_command_library_utils.hpp | 13 +++++--- .../include/cxx_include/esp_modem_dce.hpp | 2 +- .../include/cxx_include/esp_modem_dte.hpp | 4 +-- .../include/cxx_include/esp_modem_types.hpp | 4 +-- .../src/esp_modem_command_library.cpp | 33 ++++++++++--------- components/esp_modem/src/esp_modem_dte.cpp | 6 ++-- 7 files changed, 36 insertions(+), 32 deletions(-) diff --git a/components/esp_modem/include/cxx_include/esp_modem_command_library.hpp b/components/esp_modem/include/cxx_include/esp_modem_command_library.hpp index 6e3729e13..80b015652 100644 --- a/components/esp_modem/include/cxx_include/esp_modem_command_library.hpp +++ b/components/esp_modem/include/cxx_include/esp_modem_command_library.hpp @@ -31,9 +31,9 @@ namespace dce_commands { * @param fail_phrase String to be present in the reply to fail this command * @param timeout_ms Timeout in ms */ -command_result generic_command(CommandableIf *t, const std::string &command, - const std::string &pass_phrase, - const std::string &fail_phrase, uint32_t timeout_ms); +command_result generic_command(CommandableIf *t, std::string_view command, + std::string_view pass_phrase, + std::string_view fail_phrase, uint32_t timeout_ms); /** * @brief Declaration of all commands is generated from esp_modem_command_declare.inc diff --git a/components/esp_modem/include/cxx_include/esp_modem_command_library_utils.hpp b/components/esp_modem/include/cxx_include/esp_modem_command_library_utils.hpp index b47c150d8..b2f430cbf 100644 --- a/components/esp_modem/include/cxx_include/esp_modem_command_library_utils.hpp +++ b/components/esp_modem/include/cxx_include/esp_modem_command_library_utils.hpp @@ -6,6 +6,9 @@ #pragma once +#include +#include + namespace esp_modem::dce_commands { /** @@ -17,9 +20,9 @@ namespace esp_modem::dce_commands { * @param timeout_ms Command timeout in ms * @return Generic command return type (OK, FAIL, TIMEOUT) */ -command_result generic_command(CommandableIf *t, const std::string &command, - const std::string &pass_phrase, - const std::string &fail_phrase, uint32_t timeout_ms); +command_result generic_command(CommandableIf *t, std::string_view command, + std::string_view pass_phrase, + std::string_view fail_phrase, uint32_t timeout_ms); /** * @brief Utility command to send command and return reply (after DCE says OK) @@ -30,7 +33,7 @@ command_result generic_command(CommandableIf *t, const std::string &command, * @param timeout_ms Command timeout in ms * @return Generic command return type (OK, FAIL, TIMEOUT) */ -command_result generic_get_string(CommandableIf *t, const std::string &command, std::string &output, uint32_t timeout_ms = 500); +command_result generic_get_string(CommandableIf *t, std::string_view command, std::string &output, uint32_t timeout_ms = 500); /** * @brief Generic command that passes on "OK" and fails on "ERROR" @@ -40,6 +43,6 @@ command_result generic_get_string(CommandableIf *t, const std::string &command, * @param timeout_ms Command timeout in ms * @return Generic command return type (OK, FAIL, TIMEOUT) */ -command_result generic_command_common(CommandableIf *t, const std::string &command, uint32_t timeout_ms = 500); +command_result generic_command_common(CommandableIf *t, std::string_view command, uint32_t timeout_ms = 500); } // esp_modem::dce_commands diff --git a/components/esp_modem/include/cxx_include/esp_modem_dce.hpp b/components/esp_modem/include/cxx_include/esp_modem_dce.hpp index 28395e158..165d4f1fc 100644 --- a/components/esp_modem/include/cxx_include/esp_modem_dce.hpp +++ b/components/esp_modem/include/cxx_include/esp_modem_dce.hpp @@ -74,7 +74,7 @@ public: return device.get(); } - command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms) + command_result command(std::string_view command, got_line_cb got_line, uint32_t time_ms) { return dte->command(command, std::move(got_line), time_ms); } diff --git a/components/esp_modem/include/cxx_include/esp_modem_dte.hpp b/components/esp_modem/include/cxx_include/esp_modem_dte.hpp index 2ee56099a..91f0e2a1b 100644 --- a/components/esp_modem/include/cxx_include/esp_modem_dte.hpp +++ b/components/esp_modem/include/cxx_include/esp_modem_dte.hpp @@ -101,12 +101,12 @@ public: * @param time_ms Time in ms to wait for the answer * @return OK, FAIL, TIMEOUT */ - command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms) override; + command_result command(std::string_view command, got_line_cb got_line, uint32_t time_ms) override; /** * @brief Sends the command (same as above) but with a specific separator */ - command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms, char separator) override; + command_result command(std::string_view command, got_line_cb got_line, uint32_t time_ms, char separator) override; protected: /** diff --git a/components/esp_modem/include/cxx_include/esp_modem_types.hpp b/components/esp_modem/include/cxx_include/esp_modem_types.hpp index 513b1f847..287671507 100644 --- a/components/esp_modem/include/cxx_include/esp_modem_types.hpp +++ b/components/esp_modem/include/cxx_include/esp_modem_types.hpp @@ -78,8 +78,8 @@ public: * @param time_ms timeout in milliseconds * @return OK, FAIL or TIMEOUT */ - virtual command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms, const char separator) = 0; - virtual command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms) = 0; + virtual command_result command(std::string_view command, got_line_cb got_line, uint32_t time_ms, const char separator) = 0; + virtual command_result command(std::string_view command, got_line_cb got_line, uint32_t time_ms) = 0; virtual int write(uint8_t *data, size_t len) = 0; virtual void on_read(got_line_cb on_data) = 0; diff --git a/components/esp_modem/src/esp_modem_command_library.cpp b/components/esp_modem/src/esp_modem_command_library.cpp index 3947d70ed..dc8f238d8 100644 --- a/components/esp_modem/src/esp_modem_command_library.cpp +++ b/components/esp_modem/src/esp_modem_command_library.cpp @@ -5,7 +5,8 @@ */ #include -#include +#include + #include "esp_log.h" #include "cxx_include/esp_modem_dte.hpp" #include "cxx_include/esp_modem_dce_module.hpp" @@ -16,12 +17,12 @@ namespace esp_modem::dce_commands { static const char *TAG = "command_lib"; -static command_result generic_command(CommandableIf *t, const std::string &command, - const std::list &pass_phrase, - const std::list &fail_phrase, - uint32_t timeout_ms) +command_result generic_command(CommandableIf *t, std::string_view command, + std::span pass_phrase, + std::span fail_phrase, + uint32_t timeout_ms) { - ESP_LOGD(TAG, "%s command %s\n", __func__, command.c_str()); + ESP_LOGD(TAG, "%s command %.*s\n", __func__, command.size(), command.data()); return t->command(command, [&](uint8_t *data, size_t len) { std::string_view response((char *)data, len); if (data == nullptr || len == 0 || response.empty()) { @@ -41,17 +42,17 @@ static command_result generic_command(CommandableIf *t, const std::string &comma } -command_result generic_command(CommandableIf *t, const std::string &command, - const std::string &pass_phrase, - const std::string &fail_phrase, uint32_t timeout_ms) +command_result generic_command(CommandableIf *t, std::string_view command, + std::string_view pass_phrase, + std::string_view fail_phrase, uint32_t timeout_ms) { ESP_LOGV(TAG, "%s", __func__ ); - const auto pass = std::list({pass_phrase}); - const auto fail = std::list({fail_phrase}); + const std::string_view pass[] { pass_phrase }; + const std::string_view fail[] { fail_phrase }; return generic_command(t, command, pass, fail, timeout_ms); } -static command_result generic_get_string(CommandableIf *t, const std::string &command, std::string_view &output, uint32_t timeout_ms = 500) +static command_result generic_get_string(CommandableIf *t, std::string_view command, std::string_view &output, uint32_t timeout_ms = 500) { ESP_LOGV(TAG, "%s", __func__ ); return t->command(command, [&](uint8_t *data, size_t len) { @@ -78,7 +79,7 @@ static command_result generic_get_string(CommandableIf *t, const std::string &co }, timeout_ms); } -command_result generic_get_string(CommandableIf *t, const std::string &command, std::string &output, uint32_t timeout_ms) +command_result generic_get_string(CommandableIf *t, std::string_view command, std::string &output, uint32_t timeout_ms) { ESP_LOGV(TAG, "%s", __func__ ); std::string_view out; @@ -90,7 +91,7 @@ command_result generic_get_string(CommandableIf *t, const std::string &command, } -command_result generic_command_common(CommandableIf *t, const std::string &command, uint32_t timeout_ms) +command_result generic_command_common(CommandableIf *t, std::string_view command, uint32_t timeout_ms) { ESP_LOGV(TAG, "%s", __func__ ); return generic_command(t, command, "OK", "ERROR", timeout_ms); @@ -290,8 +291,8 @@ command_result resume_data_mode(CommandableIf *t) command_result set_command_mode(CommandableIf *t) { ESP_LOGV(TAG, "%s", __func__ ); - const auto pass = std::list({"NO CARRIER", "OK"}); - const auto fail = std::list({"ERROR"}); + const std::string_view pass[] {"NO CARRIER", "OK"}; + const std::string_view fail[] {"ERROR"}; return generic_command(t, "+++", pass, fail, 5000); } diff --git a/components/esp_modem/src/esp_modem_dte.cpp b/components/esp_modem/src/esp_modem_dte.cpp index 98e3ff687..c493b6653 100644 --- a/components/esp_modem/src/esp_modem_dte.cpp +++ b/components/esp_modem/src/esp_modem_dte.cpp @@ -34,7 +34,7 @@ DTE::DTE(std::unique_ptr t, std::unique_ptr s): cmux_term(nullptr), primary_term(std::move(t)), secondary_term(std::move(s)), mode(modem_mode::DUAL_MODE) {} -command_result DTE::command(const std::string &command, got_line_cb got_line, uint32_t time_ms, const char separator) +command_result DTE::command(std::string_view command, got_line_cb got_line, uint32_t time_ms, const char separator) { Scoped l(internal_lock); result = command_result::TIMEOUT; @@ -56,7 +56,7 @@ command_result DTE::command(const std::string &command, got_line_cb got_line, ui buffer.consumed += len; return false; }); - primary_term->write((uint8_t *)command.c_str(), command.length()); + primary_term->write((uint8_t *)command.data(), command.length()); auto got_lf = signal.wait(GOT_LINE, time_ms); if (got_lf && result == command_result::TIMEOUT) { ESP_MODEM_THROW_IF_ERROR(ESP_ERR_INVALID_STATE); @@ -66,7 +66,7 @@ command_result DTE::command(const std::string &command, got_line_cb got_line, ui return result; } -command_result DTE::command(const std::string &cmd, got_line_cb got_line, uint32_t time_ms) +command_result DTE::command(std::string_view cmd, got_line_cb got_line, uint32_t time_ms) { return command(cmd, got_line, time_ms, '\n'); }