Zero-copy encode: pack response body in place, single shared tx_buf, drain rx loop

This commit is contained in:
Ian Gulliver
2026-04-10 22:48:28 +09:00
parent 58db392bf3
commit 8408603390
8 changed files with 98 additions and 57 deletions

View File

@@ -29,7 +29,7 @@ void dispatch_schedule_ms(uint32_t ms, std::function<void()> fn) {
static usb_cdc usb;
static static_vector<uint8_t, 256> usb_rx_buf;
static uint8_t tx_buf[1514];
static std::array<uint8_t, 1514> tx_buf;
net_set_handler([&](std::span<const uint8_t> payload, span_writer &out) -> size_t {
auto msg = try_decode(payload.data(), payload.size());
@@ -45,7 +45,7 @@ void dispatch_schedule_ms(uint32_t ms, std::function<void()> fn) {
dlog_if_slow("tud_task", 1000, [&]{ tud_task(); });
dlog_if_slow("drain", 1000, [&]{ usb.drain(); });
dlog_if_slow("timers", 1000, [&]{ timers.run(); });
dlog_if_slow("net_poll", 1000, [&]{ net_poll(); });
dlog_if_slow("net_poll", 1000, [&]{ net_poll(std::span{tx_buf}); });
while (tud_cdc_available()) {
uint8_t byte;
@@ -63,16 +63,16 @@ void dispatch_schedule_ms(uint32_t ms, std::function<void()> fn) {
auto it = handler_map.find(msg->type_id);
if (it != handler_map.end()) {
span_writer out(tx_buf, sizeof(tx_buf));
span_writer out(tx_buf);
size_t resp_len = it->second(msg->message_id, msg->payload, out);
if (resp_len > 0) {
if (resp_len > usb.tx.free()) {
span_writer err_out(tx_buf, sizeof(tx_buf));
span_writer err_out(tx_buf);
size_t err_len = encode_response_into(err_out, msg->message_id,
DeviceError{2, "response too large: " + std::to_string(resp_len)});
usb.send(std::span<const uint8_t>{tx_buf, err_len});
usb.send(std::span<const uint8_t>{tx_buf.data(), err_len});
} else {
usb.send(std::span<const uint8_t>{tx_buf, resp_len});
usb.send(std::span<const uint8_t>{tx_buf.data(), resp_len});
}
}
}